aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--AUTHORS8
-rw-r--r--Makefile.common3
-rw-r--r--audio/mixer.cpp8
-rw-r--r--audio/softsynth/fluidsynth.cpp2
-rw-r--r--audio/softsynth/mt32/AReverbModel.cpp277
-rw-r--r--audio/softsynth/mt32/AReverbModel.h87
-rw-r--r--audio/softsynth/mt32/BReverbModel.cpp129
-rw-r--r--audio/softsynth/mt32/BReverbModel.h24
-rw-r--r--audio/softsynth/mt32/DelayReverb.cpp142
-rw-r--r--audio/softsynth/mt32/DelayReverb.h50
-rw-r--r--audio/softsynth/mt32/FreeverbModel.cpp78
-rw-r--r--audio/softsynth/mt32/FreeverbModel.h44
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.cpp (renamed from audio/softsynth/mt32/LegacyWaveGenerator.cpp)10
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.h (renamed from audio/softsynth/mt32/LegacyWaveGenerator.h)6
-rw-r--r--audio/softsynth/mt32/LA32WaveGenerator.cpp9
-rw-r--r--audio/softsynth/mt32/LA32WaveGenerator.h6
-rw-r--r--audio/softsynth/mt32/Part.cpp43
-rw-r--r--audio/softsynth/mt32/Part.h4
-rw-r--r--audio/softsynth/mt32/Partial.cpp39
-rw-r--r--audio/softsynth/mt32/Partial.h25
-rw-r--r--audio/softsynth/mt32/PartialManager.cpp62
-rw-r--r--audio/softsynth/mt32/PartialManager.h12
-rw-r--r--audio/softsynth/mt32/Poly.cpp49
-rw-r--r--audio/softsynth/mt32/Poly.h6
-rw-r--r--audio/softsynth/mt32/Structures.h6
-rw-r--r--audio/softsynth/mt32/Synth.cpp608
-rw-r--r--audio/softsynth/mt32/Synth.h192
-rw-r--r--audio/softsynth/mt32/TVP.cpp2
-rw-r--r--audio/softsynth/mt32/Tables.h5
-rw-r--r--audio/softsynth/mt32/freeverb.cpp324
-rw-r--r--audio/softsynth/mt32/freeverb.h189
-rw-r--r--audio/softsynth/mt32/module.mk9
-rw-r--r--audio/softsynth/mt32/mt32emu.h35
-rw-r--r--backends/base-backend.cpp4
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp40
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp31
-rw-r--r--backends/midi/timidity.cpp2
-rw-r--r--backends/modular-backend.cpp6
-rw-r--r--backends/platform/android/gfx.cpp4
-rw-r--r--backends/platform/android/texture.cpp10
-rw-r--r--backends/platform/dc/display.cpp6
-rw-r--r--backends/platform/dc/selector.cpp2
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.cpp23
-rw-r--r--backends/platform/iphone/iphone_video.mm6
-rw-r--r--backends/platform/iphone/osys_main.cpp4
-rw-r--r--backends/platform/iphone/osys_video.mm22
-rw-r--r--backends/platform/n64/osys_n64_base.cpp6
-rw-r--r--backends/platform/ps2/Gs2dScreen.cpp8
-rw-r--r--backends/platform/psp/default_display_client.cpp7
-rw-r--r--backends/platform/sdl/sdl.cpp27
-rw-r--r--backends/platform/tizen/application.cpp22
-rw-r--r--backends/platform/tizen/audio.cpp36
-rw-r--r--backends/platform/tizen/audio.h4
-rw-r--r--backends/platform/tizen/form.cpp19
-rw-r--r--backends/platform/tizen/form.h9
-rw-r--r--backends/platform/tizen/fs.cpp1
-rw-r--r--backends/platform/tizen/graphics.cpp7
-rw-r--r--backends/platform/tizen/sscanf.cpp2
-rw-r--r--backends/platform/tizen/system.cpp6
-rw-r--r--backends/platform/wii/osystem_gfx.cpp11
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.cpp42
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.h6
-rw-r--r--backends/vkeybd/virtual-keyboard.h4
-rw-r--r--base/commandLine.cpp5
-rw-r--r--base/main.cpp6
-rw-r--r--common/config-manager.h27
-rw-r--r--common/ini-file.cpp (renamed from common/config-file.cpp)60
-rw-r--r--common/ini-file.h (renamed from common/config-file.h)29
-rw-r--r--common/macresman.cpp98
-rw-r--r--common/macresman.h25
-rw-r--r--common/math.h8
-rw-r--r--common/module.mk2
-rw-r--r--common/random.cpp8
-rw-r--r--common/recorderfile.cpp6
-rw-r--r--common/scummsys.h57
-rw-r--r--common/util.h8
-rw-r--r--common/winexe_ne.cpp2
-rwxr-xr-xconfigure20
-rw-r--r--devtools/README7
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp7
-rw-r--r--devtools/create_kyradat/pak.cpp2
-rw-r--r--devtools/create_lure/process_actions.cpp1
-rw-r--r--devtools/create_mortdat/create_mortdat.cpp279
-rw-r--r--devtools/create_mortdat/create_mortdat.h63
-rw-r--r--devtools/create_mortdat/enginetext.h189
-rw-r--r--devtools/create_mortdat/gametext.h1794
-rw-r--r--devtools/create_mortdat/menudata.h143
-rw-r--r--devtools/create_mortdat/module.mk11
-rw-r--r--devtools/create_neverhood/create_neverhood.cpp74
-rw-r--r--devtools/create_neverhood/tables.h2
-rw-r--r--devtools/create_project/create_project.cpp195
-rw-r--r--devtools/create_project/create_project.h10
-rw-r--r--devtools/create_project/msbuild.cpp113
-rw-r--r--devtools/create_project/msbuild.h4
-rw-r--r--devtools/create_project/msvc.cpp30
-rw-r--r--devtools/create_project/msvc.h9
-rw-r--r--devtools/create_project/visualstudio.cpp67
-rw-r--r--devtools/create_project/visualstudio.h2
-rw-r--r--devtools/create_teenagent/static_tables.h2
-rwxr-xr-xdevtools/credits.pl10
-rw-r--r--devtools/extract_mort/extract_mort.cpp428
-rw-r--r--devtools/extract_mort/module.mk11
-rw-r--r--devtools/scumm-md5.txt5
-rw-r--r--devtools/skycpt/cptcompiler.cpp3
-rw-r--r--dists/engine-data/README5
-rw-r--r--dists/engine-data/mort.datbin0 -> 76151 bytes
-rw-r--r--dists/msvc10/create_msvc10.bat10
-rw-r--r--dists/msvc11/create_msvc11.bat10
-rw-r--r--dists/msvc12/create_msvc12.bat10
-rw-r--r--dists/msvc8/create_msvc8.bat10
-rw-r--r--dists/msvc9/create_msvc9.bat10
-rw-r--r--dists/scummvm.rc3
-rw-r--r--dists/scummvm.rc.in3
-rw-r--r--engines/advancedDetector.cpp2
-rw-r--r--engines/agi/agi.cpp4
-rw-r--r--engines/agi/detection_tables.h1
-rw-r--r--engines/agi/preagi_troll.cpp2
-rw-r--r--engines/agi/preagi_winnie.cpp1
-rw-r--r--engines/agos/agos.h24
-rw-r--r--engines/agos/animation.cpp8
-rw-r--r--engines/agos/charset-fontdata.cpp8
-rw-r--r--engines/agos/charset.cpp2
-rw-r--r--engines/agos/draw.cpp30
-rw-r--r--engines/agos/event.cpp2
-rw-r--r--engines/agos/gfx.cpp64
-rw-r--r--engines/agos/icons.cpp16
-rw-r--r--engines/agos/menus.cpp4
-rw-r--r--engines/agos/saveload.cpp99
-rw-r--r--engines/agos/script_pn.cpp14
-rw-r--r--engines/agos/verb.cpp2
-rw-r--r--engines/agos/vga.cpp11
-rw-r--r--engines/agos/vga_e2.cpp10
-rw-r--r--engines/agos/vga_pn.cpp4
-rw-r--r--engines/agos/vga_s2.cpp5
-rw-r--r--engines/agos/vga_ww.cpp2
-rw-r--r--engines/agos/window.cpp4
-rw-r--r--engines/cge/cge_main.cpp2
-rw-r--r--engines/cge/detection.cpp2
-rw-r--r--engines/cge/snail.cpp2
-rw-r--r--engines/cge/vga13h.cpp6
-rw-r--r--engines/composer/composer.h4
-rw-r--r--engines/composer/graphics.cpp10
-rw-r--r--engines/configure.engines1
-rw-r--r--engines/draci/screen.cpp4
-rw-r--r--engines/draci/surface.cpp2
-rw-r--r--engines/drascula/actors.cpp16
-rw-r--r--engines/drascula/animation.cpp18
-rw-r--r--engines/drascula/console.cpp2
-rw-r--r--engines/drascula/converse.cpp16
-rw-r--r--engines/drascula/drascula.cpp93
-rw-r--r--engines/drascula/drascula.h16
-rw-r--r--engines/drascula/graphics.cpp22
-rw-r--r--engines/drascula/interface.cpp8
-rw-r--r--engines/drascula/objects.cpp74
-rw-r--r--engines/drascula/rooms.cpp60
-rw-r--r--engines/drascula/saveload.cpp24
-rw-r--r--engines/drascula/sound.cpp16
-rw-r--r--engines/drascula/talk.cpp54
-rw-r--r--engines/dreamweb/monitor.cpp10
-rw-r--r--engines/dreamweb/print.cpp2
-rw-r--r--engines/engines.mk5
-rw-r--r--engines/gob/iniconfig.cpp4
-rw-r--r--engines/gob/iniconfig.h4
-rw-r--r--engines/gob/surface.cpp2
-rw-r--r--engines/gob/videoplayer.cpp6
-rw-r--r--engines/groovie/graphics.cpp6
-rw-r--r--engines/groovie/roq.cpp14
-rw-r--r--engines/groovie/script.cpp4
-rw-r--r--engines/groovie/stuffit.cpp2
-rw-r--r--engines/groovie/vdx.cpp14
-rw-r--r--engines/hopkins/computer.cpp53
-rw-r--r--engines/hopkins/computer.h2
-rw-r--r--engines/hopkins/detection.cpp4
-rw-r--r--engines/hopkins/dialogs.cpp4
-rw-r--r--engines/hopkins/globals.cpp2
-rw-r--r--engines/hopkins/graphics.cpp12
-rw-r--r--engines/hopkins/graphics.h2
-rw-r--r--engines/hopkins/hopkins.cpp4
-rw-r--r--engines/hopkins/hopkins.h1
-rw-r--r--engines/hopkins/saveload.cpp29
-rw-r--r--engines/hopkins/saveload.h4
-rw-r--r--engines/hugo/dialogs.cpp4
-rw-r--r--engines/hugo/hugo.cpp2
-rw-r--r--engines/hugo/intro.cpp18
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/scene_mr.cpp1
-rw-r--r--engines/kyra/screen.cpp7
-rw-r--r--engines/kyra/text_rpg.cpp2
-rw-r--r--engines/lastexpress/data/animation.cpp2
-rw-r--r--engines/lastexpress/data/scene.h14
-rw-r--r--engines/lastexpress/data/sequence.cpp12
-rw-r--r--engines/lastexpress/debug.cpp8
-rw-r--r--engines/lastexpress/game/scenes.cpp4
-rw-r--r--engines/lastexpress/game/state.h1
-rw-r--r--engines/lastexpress/graphics.cpp12
-rw-r--r--engines/lastexpress/lastexpress.cpp4
-rw-r--r--engines/lure/hotspots.cpp198
-rw-r--r--engines/made/graphics.cpp4
-rw-r--r--engines/made/pmvplayer.cpp2
-rw-r--r--engines/made/screen.cpp8
-rw-r--r--engines/made/screenfx.cpp4
-rw-r--r--engines/made/scriptfuncs.cpp2
-rw-r--r--engines/mohawk/bitmap.cpp10
-rw-r--r--engines/mohawk/cursors.cpp4
-rw-r--r--engines/mohawk/livingbooks.cpp4
-rw-r--r--engines/mohawk/livingbooks.h4
-rw-r--r--engines/mohawk/livingbooks_lbx.cpp10
-rw-r--r--engines/mohawk/myst.cpp1
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp1
-rw-r--r--engines/mohawk/riven_graphics.cpp8
-rw-r--r--engines/mohawk/video.cpp2
-rw-r--r--engines/mortevielle/actions.cpp1674
-rw-r--r--engines/mortevielle/debugger.cpp59
-rw-r--r--engines/mortevielle/debugger.h49
-rw-r--r--engines/mortevielle/detection.cpp115
-rw-r--r--engines/mortevielle/detection_tables.h116
-rw-r--r--engines/mortevielle/dialogs.cpp472
-rw-r--r--engines/mortevielle/dialogs.h65
-rw-r--r--engines/mortevielle/graphics.cpp1167
-rw-r--r--engines/mortevielle/graphics.h117
-rw-r--r--engines/mortevielle/menu.cpp792
-rw-r--r--engines/mortevielle/menu.h125
-rw-r--r--engines/mortevielle/module.mk23
-rw-r--r--engines/mortevielle/mortevielle.cpp458
-rw-r--r--engines/mortevielle/mortevielle.h494
-rw-r--r--engines/mortevielle/mouse.cpp273
-rw-r--r--engines/mortevielle/mouse.h56
-rw-r--r--engines/mortevielle/outtext.cpp308
-rw-r--r--engines/mortevielle/outtext.h49
-rw-r--r--engines/mortevielle/saveload.cpp332
-rw-r--r--engines/mortevielle/saveload.h73
-rw-r--r--engines/mortevielle/sound.cpp800
-rw-r--r--engines/mortevielle/sound.h106
-rw-r--r--engines/mortevielle/utils.cpp3404
-rw-r--r--engines/neverhood/background.cpp4
-rw-r--r--engines/neverhood/blbarchive.cpp16
-rw-r--r--engines/neverhood/console.cpp2
-rw-r--r--engines/neverhood/diskplayerscene.cpp32
-rw-r--r--engines/neverhood/diskplayerscene.h6
-rw-r--r--engines/neverhood/entity.cpp20
-rw-r--r--engines/neverhood/entity.h2
-rw-r--r--engines/neverhood/gamemodule.cpp20
-rw-r--r--engines/neverhood/gamemodule.h2
-rw-r--r--engines/neverhood/gamevars.cpp2
-rw-r--r--engines/neverhood/gamevars.h2
-rw-r--r--engines/neverhood/graphics.cpp20
-rw-r--r--engines/neverhood/graphics.h12
-rw-r--r--engines/neverhood/klaymen.cpp400
-rw-r--r--engines/neverhood/klaymen.h30
-rw-r--r--engines/neverhood/menumodule.cpp126
-rw-r--r--engines/neverhood/menumodule.h8
-rw-r--r--engines/neverhood/module.cpp4
-rw-r--r--engines/neverhood/modules/module1000.cpp104
-rw-r--r--engines/neverhood/modules/module1000.h2
-rw-r--r--engines/neverhood/modules/module1100.cpp48
-rw-r--r--engines/neverhood/modules/module1200.cpp62
-rw-r--r--engines/neverhood/modules/module1300.cpp86
-rw-r--r--engines/neverhood/modules/module1400.cpp54
-rw-r--r--engines/neverhood/modules/module1500.cpp6
-rw-r--r--engines/neverhood/modules/module1600.cpp48
-rw-r--r--engines/neverhood/modules/module1700.cpp12
-rw-r--r--engines/neverhood/modules/module1700.h2
-rw-r--r--engines/neverhood/modules/module1800.cpp4
-rw-r--r--engines/neverhood/modules/module1900.cpp40
-rw-r--r--engines/neverhood/modules/module2000.cpp8
-rw-r--r--engines/neverhood/modules/module2100.cpp20
-rw-r--r--engines/neverhood/modules/module2100.h2
-rw-r--r--engines/neverhood/modules/module2200.cpp114
-rw-r--r--engines/neverhood/modules/module2200.h4
-rw-r--r--engines/neverhood/modules/module2300.cpp10
-rw-r--r--engines/neverhood/modules/module2400.cpp46
-rw-r--r--engines/neverhood/modules/module2500.cpp30
-rw-r--r--engines/neverhood/modules/module2600.cpp10
-rw-r--r--engines/neverhood/modules/module2700.cpp104
-rw-r--r--engines/neverhood/modules/module2800.cpp166
-rw-r--r--engines/neverhood/modules/module2800.h6
-rw-r--r--engines/neverhood/modules/module2900.cpp20
-rw-r--r--engines/neverhood/modules/module2900.h4
-rw-r--r--engines/neverhood/modules/module3000.cpp42
-rw-r--r--engines/neverhood/modules/module3000.h2
-rw-r--r--engines/neverhood/mouse.cpp52
-rw-r--r--engines/neverhood/mouse.h2
-rw-r--r--engines/neverhood/navigationscene.cpp20
-rw-r--r--engines/neverhood/neverhood.cpp12
-rw-r--r--engines/neverhood/neverhood.h4
-rw-r--r--engines/neverhood/palette.cpp14
-rw-r--r--engines/neverhood/resource.cpp64
-rw-r--r--engines/neverhood/resource.h4
-rw-r--r--engines/neverhood/resourceman.cpp2
-rw-r--r--engines/neverhood/saveload.cpp10
-rw-r--r--engines/neverhood/scene.cpp50
-rw-r--r--engines/neverhood/scene.h42
-rw-r--r--engines/neverhood/screen.cpp58
-rw-r--r--engines/neverhood/smackerplayer.cpp18
-rw-r--r--engines/neverhood/smackerplayer.h2
-rw-r--r--engines/neverhood/smackerscene.cpp8
-rw-r--r--engines/neverhood/sound.cpp26
-rw-r--r--engines/neverhood/sound.h30
-rw-r--r--engines/neverhood/sprite.cpp24
-rw-r--r--engines/neverhood/staticdata.cpp10
-rw-r--r--engines/parallaction/disk_br.cpp8
-rw-r--r--engines/parallaction/disk_ns.cpp6
-rw-r--r--engines/parallaction/exec_ns.cpp4
-rw-r--r--engines/parallaction/graphics.cpp22
-rw-r--r--engines/parallaction/input.cpp2
-rw-r--r--engines/parallaction/inventory.h2
-rw-r--r--engines/pegasus/cursor.cpp6
-rw-r--r--engines/pegasus/graphics.cpp2
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoria.cpp4
-rw-r--r--engines/pegasus/neighborhood/neighborhood.cpp2
-rw-r--r--engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp2
-rw-r--r--engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp2
-rw-r--r--engines/pegasus/neighborhood/norad/norad.cpp4
-rw-r--r--engines/pegasus/pegasus.cpp10
-rw-r--r--engines/pegasus/timers.cpp4
-rw-r--r--engines/pegasus/transition.cpp2
-rw-r--r--engines/plugins_table.h3
-rw-r--r--engines/saga/animation.cpp4
-rw-r--r--engines/saga/gfx.h2
-rw-r--r--engines/saga/introproc_ihnm.cpp8
-rw-r--r--engines/saga/introproc_saga2.cpp2
-rw-r--r--engines/saga/music.cpp2
-rw-r--r--engines/saga/scene.cpp6
-rw-r--r--engines/sci/detection.cpp5
-rw-r--r--engines/sci/detection_tables.h25
-rw-r--r--engines/sci/engine/features.cpp6
-rw-r--r--engines/sci/engine/kpathing.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp2
-rw-r--r--engines/sci/engine/kvideo.cpp4
-rw-r--r--engines/sci/engine/script_patches.cpp24
-rw-r--r--engines/sci/engine/vm_types.cpp32
-rw-r--r--engines/sci/engine/vm_types.h2
-rw-r--r--engines/sci/engine/workarounds.cpp10
-rw-r--r--engines/sci/graphics/frameout.cpp12
-rw-r--r--engines/sci/graphics/maciconbar.cpp6
-rw-r--r--engines/sci/graphics/picture.cpp16
-rw-r--r--engines/sci/graphics/screen.cpp4
-rw-r--r--engines/sci/sci.h1
-rw-r--r--engines/sci/sound/midiparser_sci.cpp29
-rw-r--r--engines/sci/sound/midiparser_sci.h1
-rw-r--r--engines/sci/video/robot_decoder.cpp2
-rw-r--r--engines/sci/video/seq_decoder.cpp4
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/akos.cpp6
-rw-r--r--engines/scumm/base-costume.cpp8
-rw-r--r--engines/scumm/bomp.cpp5
-rw-r--r--engines/scumm/charset.cpp10
-rw-r--r--engines/scumm/costume.cpp6
-rw-r--r--engines/scumm/cursor.cpp10
-rw-r--r--engines/scumm/debugger.cpp2
-rw-r--r--engines/scumm/detection_tables.h11
-rw-r--r--engines/scumm/gfx.cpp29
-rw-r--r--engines/scumm/gfx_towns.cpp2
-rw-r--r--engines/scumm/he/animation_he.cpp4
-rw-r--r--engines/scumm/he/logic/moonbase.cpp2
-rw-r--r--engines/scumm/he/script_v100he.cpp2
-rw-r--r--engines/scumm/he/script_v70he.cpp2
-rw-r--r--engines/scumm/he/script_v72he.cpp7
-rw-r--r--engines/scumm/he/script_v80he.cpp6
-rw-r--r--engines/scumm/imuse/imuse.cpp2
-rw-r--r--engines/scumm/input.cpp2
-rw-r--r--engines/scumm/insane/insane_enemy.cpp4
-rw-r--r--engines/scumm/nut_renderer.cpp10
-rw-r--r--engines/scumm/object.cpp2
-rw-r--r--engines/scumm/player_mac.cpp10
-rw-r--r--engines/scumm/player_v3m.cpp2
-rw-r--r--engines/scumm/script_v6.cpp2
-rw-r--r--engines/scumm/scumm-md5.h7
-rw-r--r--engines/scumm/scumm.h1
-rw-r--r--engines/scumm/vars.cpp6
-rw-r--r--engines/sword1/animation.cpp6
-rw-r--r--engines/sword2/animation.cpp4
-rw-r--r--engines/sword25/fmv/movieplayer.cpp4
-rw-r--r--engines/sword25/gfx/dynamicbitmap.cpp4
-rw-r--r--engines/sword25/gfx/image/image.h2
-rw-r--r--engines/sword25/gfx/image/imgloader.cpp2
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp36
-rw-r--r--engines/sword25/gfx/panel.cpp2
-rw-r--r--engines/sword25/gfx/renderobject.cpp2
-rw-r--r--engines/sword25/gfx/renderobject.h16
-rw-r--r--engines/sword25/gfx/renderobjectmanager.cpp6
-rw-r--r--engines/sword25/gfx/screenshot.cpp4
-rw-r--r--engines/sword25/gfx/staticbitmap.cpp2
-rw-r--r--engines/sword25/util/pluto/pluto.cpp540
-rw-r--r--engines/teenagent/callbacks.cpp6
-rw-r--r--engines/teenagent/dialog.cpp2
-rw-r--r--engines/teenagent/font.cpp2
-rw-r--r--engines/teenagent/resources.cpp5
-rw-r--r--engines/teenagent/scene.cpp12
-rw-r--r--engines/teenagent/teenagent.cpp2
-rw-r--r--engines/testbed/config.cpp8
-rw-r--r--engines/testbed/config.h4
-rw-r--r--engines/testbed/graphics.cpp22
-rw-r--r--engines/tinsel/bmv.cpp2
-rw-r--r--engines/tinsel/detection_tables.h20
-rw-r--r--engines/tinsel/graphics.cpp2
-rw-r--r--engines/tinsel/handle.cpp2
-rw-r--r--engines/tinsel/rince.cpp3
-rw-r--r--engines/tinsel/scene.cpp2
-rw-r--r--engines/tinsel/tinsel.cpp6
-rw-r--r--engines/toltecs/detection.cpp14
-rw-r--r--engines/toltecs/menu.cpp4
-rw-r--r--engines/toltecs/screen.cpp2
-rw-r--r--engines/toltecs/segmap.cpp2
-rw-r--r--engines/tony/detection.cpp29
-rw-r--r--engines/tony/game.cpp3
-rw-r--r--engines/tony/gfxcore.cpp2
-rw-r--r--engines/tony/gfxcore.h6
-rw-r--r--engines/tony/mpal/mpal.cpp16
-rw-r--r--engines/tony/sound.cpp6
-rw-r--r--engines/tony/window.cpp8
-rw-r--r--engines/toon/anim.cpp6
-rw-r--r--engines/toon/movie.cpp2
-rw-r--r--engines/toon/picture.cpp6
-rw-r--r--engines/toon/toon.cpp12
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp1
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp2
-rw-r--r--engines/tsage/converse.cpp174
-rw-r--r--engines/tsage/converse.h11
-rw-r--r--engines/tsage/core.cpp34
-rw-r--r--engines/tsage/core.h3
-rw-r--r--engines/tsage/dialogs.cpp78
-rw-r--r--engines/tsage/events.cpp10
-rw-r--r--engines/tsage/globals.cpp80
-rw-r--r--engines/tsage/globals.h33
-rw-r--r--engines/tsage/graphics.cpp103
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.cpp1
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp16
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp661
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h98
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp1305
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h138
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp2448
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h225
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp89
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp48
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp392
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h26
-rw-r--r--engines/tsage/saveload.cpp2
-rw-r--r--engines/tsage/saveload.h10
-rw-r--r--engines/tsage/staticres.cpp6
-rw-r--r--engines/tsage/staticres.h6
-rw-r--r--engines/tsage/user_interface.cpp22
-rw-r--r--engines/tsage/user_interface.h2
-rw-r--r--engines/tucker/sequences.cpp4
-rw-r--r--engines/tucker/tucker.cpp13
-rw-r--r--engines/wintermute/ad/ad_actor.cpp2
-rw-r--r--engines/wintermute/ad/ad_actor.h2
-rw-r--r--engines/wintermute/ad/ad_entity.cpp2
-rw-r--r--engines/wintermute/ad/ad_entity.h2
-rw-r--r--engines/wintermute/ad/ad_game.cpp2
-rw-r--r--engines/wintermute/ad/ad_game.h2
-rw-r--r--engines/wintermute/ad/ad_inventory.cpp2
-rw-r--r--engines/wintermute/ad/ad_inventory.h2
-rw-r--r--engines/wintermute/ad/ad_inventory_box.cpp2
-rw-r--r--engines/wintermute/ad/ad_inventory_box.h2
-rw-r--r--engines/wintermute/ad/ad_item.cpp2
-rw-r--r--engines/wintermute/ad/ad_item.h2
-rw-r--r--engines/wintermute/ad/ad_layer.cpp2
-rw-r--r--engines/wintermute/ad/ad_layer.h2
-rw-r--r--engines/wintermute/ad/ad_node_state.cpp2
-rw-r--r--engines/wintermute/ad/ad_node_state.h2
-rw-r--r--engines/wintermute/ad/ad_object.cpp2
-rw-r--r--engines/wintermute/ad/ad_object.h2
-rw-r--r--engines/wintermute/ad/ad_path.cpp2
-rw-r--r--engines/wintermute/ad/ad_path.h2
-rw-r--r--engines/wintermute/ad/ad_path_point.cpp2
-rw-r--r--engines/wintermute/ad/ad_path_point.h2
-rw-r--r--engines/wintermute/ad/ad_region.cpp4
-rw-r--r--engines/wintermute/ad/ad_region.h2
-rw-r--r--engines/wintermute/ad/ad_response.cpp4
-rw-r--r--engines/wintermute/ad/ad_response.h2
-rw-r--r--engines/wintermute/ad/ad_response_box.cpp2
-rw-r--r--engines/wintermute/ad/ad_response_box.h2
-rw-r--r--engines/wintermute/ad/ad_response_context.cpp2
-rw-r--r--engines/wintermute/ad/ad_response_context.h2
-rw-r--r--engines/wintermute/ad/ad_rot_level.cpp4
-rw-r--r--engines/wintermute/ad/ad_rot_level.h2
-rw-r--r--engines/wintermute/ad/ad_scale_level.cpp4
-rw-r--r--engines/wintermute/ad/ad_scale_level.h2
-rw-r--r--engines/wintermute/ad/ad_scene.cpp2
-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_scene_state.h2
-rw-r--r--engines/wintermute/ad/ad_sentence.cpp2
-rw-r--r--engines/wintermute/ad/ad_sentence.h2
-rw-r--r--engines/wintermute/ad/ad_sprite_set.cpp2
-rw-r--r--engines/wintermute/ad/ad_sprite_set.h2
-rw-r--r--engines/wintermute/ad/ad_talk_def.cpp2
-rw-r--r--engines/wintermute/ad/ad_talk_def.h2
-rw-r--r--engines/wintermute/ad/ad_talk_holder.cpp2
-rw-r--r--engines/wintermute/ad/ad_talk_holder.h2
-rw-r--r--engines/wintermute/ad/ad_talk_node.cpp2
-rw-r--r--engines/wintermute/ad/ad_talk_node.h2
-rw-r--r--engines/wintermute/ad/ad_types.h2
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.cpp4
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.h2
-rw-r--r--engines/wintermute/base/base.cpp2
-rw-r--r--engines/wintermute/base/base.h2
-rw-r--r--engines/wintermute/base/base_active_rect.cpp2
-rw-r--r--engines/wintermute/base/base_active_rect.h2
-rw-r--r--engines/wintermute/base/base_dynamic_buffer.cpp2
-rw-r--r--engines/wintermute/base/base_dynamic_buffer.h2
-rw-r--r--engines/wintermute/base/base_engine.cpp15
-rw-r--r--engines/wintermute/base/base_engine.h12
-rw-r--r--engines/wintermute/base/base_fader.cpp2
-rw-r--r--engines/wintermute/base/base_fader.h2
-rw-r--r--engines/wintermute/base/base_file_manager.cpp4
-rw-r--r--engines/wintermute/base/base_file_manager.h2
-rw-r--r--engines/wintermute/base/base_frame.cpp2
-rw-r--r--engines/wintermute/base/base_frame.h2
-rw-r--r--engines/wintermute/base/base_game.cpp40
-rw-r--r--engines/wintermute/base/base_game.h16
-rw-r--r--engines/wintermute/base/base_game_music.cpp110
-rw-r--r--engines/wintermute/base/base_game_music.h8
-rw-r--r--engines/wintermute/base/base_game_settings.cpp52
-rw-r--r--engines/wintermute/base/base_game_settings.h6
-rw-r--r--engines/wintermute/base/base_keyboard_state.cpp2
-rw-r--r--engines/wintermute/base/base_keyboard_state.h4
-rw-r--r--engines/wintermute/base/base_named_object.cpp2
-rw-r--r--engines/wintermute/base/base_named_object.h2
-rw-r--r--engines/wintermute/base/base_object.cpp22
-rw-r--r--engines/wintermute/base/base_object.h2
-rw-r--r--engines/wintermute/base/base_parser.cpp2
-rw-r--r--engines/wintermute/base/base_parser.h2
-rw-r--r--engines/wintermute/base/base_persistence_manager.cpp75
-rw-r--r--engines/wintermute/base/base_persistence_manager.h6
-rw-r--r--engines/wintermute/base/base_point.cpp2
-rw-r--r--engines/wintermute/base/base_point.h2
-rw-r--r--engines/wintermute/base/base_quick_msg.cpp2
-rw-r--r--engines/wintermute/base/base_quick_msg.h2
-rw-r--r--engines/wintermute/base/base_region.cpp4
-rw-r--r--engines/wintermute/base/base_region.h2
-rw-r--r--engines/wintermute/base/base_script_holder.cpp2
-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_scriptable.h2
-rw-r--r--engines/wintermute/base/base_sprite.cpp2
-rw-r--r--engines/wintermute/base/base_sprite.h11
-rw-r--r--engines/wintermute/base/base_string_table.cpp2
-rw-r--r--engines/wintermute/base/base_string_table.h2
-rw-r--r--engines/wintermute/base/base_sub_frame.cpp34
-rw-r--r--engines/wintermute/base/base_sub_frame.h2
-rw-r--r--engines/wintermute/base/base_surface_storage.cpp2
-rw-r--r--engines/wintermute/base/base_surface_storage.h2
-rw-r--r--engines/wintermute/base/base_transition_manager.cpp2
-rw-r--r--engines/wintermute/base/base_transition_manager.h2
-rw-r--r--engines/wintermute/base/base_viewport.cpp2
-rw-r--r--engines/wintermute/base/base_viewport.h2
-rw-r--r--engines/wintermute/base/file/base_disk_file.cpp8
-rw-r--r--engines/wintermute/base/file/base_disk_file.h2
-rw-r--r--engines/wintermute/base/file/base_file.cpp2
-rw-r--r--engines/wintermute/base/file/base_file.h2
-rw-r--r--engines/wintermute/base/file/base_file_entry.cpp2
-rw-r--r--engines/wintermute/base/file/base_file_entry.h2
-rw-r--r--engines/wintermute/base/file/base_package.cpp2
-rw-r--r--engines/wintermute/base/file/base_package.h2
-rw-r--r--engines/wintermute/base/file/base_save_thumb_file.cpp2
-rw-r--r--engines/wintermute/base/file/base_save_thumb_file.h2
-rw-r--r--engines/wintermute/base/file/dcpackage.h2
-rw-r--r--engines/wintermute/base/font/base_font.cpp2
-rw-r--r--engines/wintermute/base/font/base_font.h2
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.cpp2
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.h2
-rw-r--r--engines/wintermute/base/font/base_font_storage.cpp2
-rw-r--r--engines/wintermute/base/font/base_font_storage.h2
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp6
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h2
-rw-r--r--engines/wintermute/base/gfx/base_image.cpp2
-rw-r--r--engines/wintermute/base/gfx/base_image.h2
-rw-r--r--engines/wintermute/base/gfx/base_renderer.cpp16
-rw-r--r--engines/wintermute/base/gfx/base_renderer.h2
-rw-r--r--engines/wintermute/base/gfx/base_surface.cpp6
-rw-r--r--engines/wintermute/base/gfx/base_surface.h9
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp75
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h42
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp163
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h19
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp78
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.h39
-rw-r--r--engines/wintermute/base/particles/part_emitter.cpp22
-rw-r--r--engines/wintermute/base/particles/part_emitter.h2
-rw-r--r--engines/wintermute/base/particles/part_force.cpp2
-rw-r--r--engines/wintermute/base/particles/part_force.h2
-rw-r--r--engines/wintermute/base/particles/part_particle.cpp12
-rw-r--r--engines/wintermute/base/particles/part_particle.h2
-rw-r--r--engines/wintermute/base/save_thumb_helper.cpp14
-rw-r--r--engines/wintermute/base/save_thumb_helper.h2
-rw-r--r--engines/wintermute/base/saveload.cpp2
-rw-r--r--engines/wintermute/base/saveload.h2
-rw-r--r--engines/wintermute/base/scriptables/dcscript.h2
-rw-r--r--engines/wintermute/base/scriptables/script.cpp3
-rw-r--r--engines/wintermute/base/scriptables/script.h2
-rw-r--r--engines/wintermute/base/scriptables/script_engine.cpp11
-rw-r--r--engines/wintermute/base/scriptables/script_engine.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_object.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_object.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.h2
-rw-r--r--engines/wintermute/base/scriptables/script_stack.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_stack.h2
-rw-r--r--engines/wintermute/base/scriptables/script_value.cpp13
-rw-r--r--engines/wintermute/base/scriptables/script_value.h2
-rw-r--r--engines/wintermute/base/sound/base_sound.cpp2
-rw-r--r--engines/wintermute/base/sound/base_sound.h2
-rw-r--r--engines/wintermute/base/sound/base_sound_buffer.cpp2
-rw-r--r--engines/wintermute/base/sound/base_sound_buffer.h2
-rw-r--r--engines/wintermute/base/sound/base_sound_manager.cpp2
-rw-r--r--engines/wintermute/base/sound/base_sound_manager.h2
-rw-r--r--engines/wintermute/base/timer.cpp4
-rw-r--r--engines/wintermute/base/timer.h6
-rw-r--r--engines/wintermute/coll_templ.h2
-rw-r--r--engines/wintermute/dcgf.h2
-rw-r--r--engines/wintermute/dctypes.h2
-rw-r--r--engines/wintermute/debugger.cpp6
-rw-r--r--engines/wintermute/debugger.h6
-rw-r--r--engines/wintermute/detection.cpp2
-rw-r--r--engines/wintermute/detection_tables.h158
-rw-r--r--engines/wintermute/graphics/transform_struct.cpp93
-rw-r--r--engines/wintermute/graphics/transform_struct.h83
-rw-r--r--engines/wintermute/graphics/transform_tools.cpp73
-rw-r--r--engines/wintermute/graphics/transform_tools.h53
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp366
-rw-r--r--engines/wintermute/graphics/transparent_surface.h48
-rw-r--r--engines/wintermute/math/floatpoint.h52
-rw-r--r--engines/wintermute/math/math_util.cpp2
-rw-r--r--engines/wintermute/math/math_util.h2
-rw-r--r--engines/wintermute/math/matrix4.cpp2
-rw-r--r--engines/wintermute/math/matrix4.h2
-rw-r--r--engines/wintermute/math/rect32.h29
-rw-r--r--engines/wintermute/math/vector2.cpp2
-rw-r--r--engines/wintermute/math/vector2.h2
-rw-r--r--engines/wintermute/module.mk2
-rw-r--r--engines/wintermute/persistent.h4
-rw-r--r--engines/wintermute/platform_osystem.cpp11
-rw-r--r--engines/wintermute/platform_osystem.h2
-rw-r--r--engines/wintermute/system/sys_class.cpp2
-rw-r--r--engines/wintermute/system/sys_class.h2
-rw-r--r--engines/wintermute/system/sys_class_registry.cpp2
-rw-r--r--engines/wintermute/system/sys_class_registry.h2
-rw-r--r--engines/wintermute/system/sys_instance.cpp2
-rw-r--r--engines/wintermute/system/sys_instance.h2
-rw-r--r--engines/wintermute/ui/ui_button.cpp2
-rw-r--r--engines/wintermute/ui/ui_button.h2
-rw-r--r--engines/wintermute/ui/ui_edit.cpp2
-rw-r--r--engines/wintermute/ui/ui_edit.h2
-rw-r--r--engines/wintermute/ui/ui_entity.cpp2
-rw-r--r--engines/wintermute/ui/ui_entity.h2
-rw-r--r--engines/wintermute/ui/ui_object.cpp2
-rw-r--r--engines/wintermute/ui/ui_object.h2
-rw-r--r--engines/wintermute/ui/ui_text.cpp2
-rw-r--r--engines/wintermute/ui/ui_text.h2
-rw-r--r--engines/wintermute/ui/ui_tiled_image.cpp2
-rw-r--r--engines/wintermute/ui/ui_tiled_image.h2
-rw-r--r--engines/wintermute/ui/ui_window.cpp2
-rw-r--r--engines/wintermute/ui/ui_window.h2
-rw-r--r--engines/wintermute/utils/crc.cpp2
-rw-r--r--engines/wintermute/utils/path_util.cpp2
-rw-r--r--engines/wintermute/utils/path_util.h2
-rw-r--r--engines/wintermute/utils/string_util.cpp25
-rw-r--r--engines/wintermute/utils/string_util.h2
-rw-r--r--engines/wintermute/utils/utils.cpp2
-rw-r--r--engines/wintermute/utils/utils.h2
-rw-r--r--engines/wintermute/video/video_player.cpp2
-rw-r--r--engines/wintermute/video/video_player.h2
-rw-r--r--engines/wintermute/video/video_theora_player.cpp14
-rw-r--r--engines/wintermute/video/video_theora_player.h4
-rw-r--r--engines/wintermute/wintermute.cpp9
-rw-r--r--engines/wintermute/wintypes.h2
-rw-r--r--graphics/VectorRenderer.h18
-rw-r--r--graphics/VectorRendererSpec.cpp874
-rw-r--r--graphics/VectorRendererSpec.h26
-rw-r--r--graphics/decoders/bmp.cpp6
-rw-r--r--graphics/decoders/iff.cpp4
-rw-r--r--graphics/decoders/jpeg.cpp2
-rw-r--r--graphics/decoders/pcx.cpp6
-rw-r--r--graphics/decoders/pict.cpp2
-rw-r--r--graphics/decoders/png.cpp2
-rw-r--r--graphics/decoders/tga.cpp4
-rw-r--r--graphics/font.cpp2
-rw-r--r--graphics/fonts/bdf.cpp4
-rw-r--r--graphics/fonts/ttf.cpp4
-rw-r--r--graphics/scaler.h6
-rw-r--r--graphics/scaler/thumbnail_intern.cpp191
-rw-r--r--graphics/surface.cpp48
-rw-r--r--graphics/surface.h77
-rw-r--r--graphics/thumbnail.cpp65
-rw-r--r--graphics/yuv_to_rgb.cpp18
-rw-r--r--gui/EventRecorder.cpp57
-rw-r--r--gui/EventRecorder.h59
-rw-r--r--gui/ThemeEngine.cpp71
-rw-r--r--gui/ThemeEngine.h13
-rw-r--r--gui/about.cpp11
-rw-r--r--gui/chooser.cpp1
-rw-r--r--gui/credits.h9
-rw-r--r--gui/editrecorddialog.cpp2
-rw-r--r--gui/gui-manager.cpp4
-rw-r--r--gui/object.cpp2
-rw-r--r--gui/object.h7
-rw-r--r--gui/onscreendialog.cpp36
-rw-r--r--gui/onscreendialog.h10
-rw-r--r--gui/recorderdialog.cpp13
-rw-r--r--gui/saveload-dialog.cpp2
-rw-r--r--gui/themes/default.inc2892
-rw-r--r--gui/themes/scummclassic.zipbin110000 -> 113348 bytes
-rw-r--r--gui/themes/scummmodern.zipbin1485763 -> 1489429 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx42
-rwxr-xr-xgui/themes/scummtheme.py17
-rw-r--r--gui/widget.cpp10
-rw-r--r--gui/widgets/editable.cpp2
-rw-r--r--gui/widgets/edittext.cpp8
-rw-r--r--po/POTFILES2
-rw-r--r--test/audio/raw.h1
-rw-r--r--test/common/hash-str.h164
-rw-r--r--test/common/huffman.h44
-rw-r--r--test/common/rendermode.h84
-rw-r--r--test/common/util.h95
-rw-r--r--video/avi_decoder.cpp487
-rw-r--r--video/avi_decoder.h50
-rw-r--r--video/codecs/cdtoons.cpp2
-rw-r--r--video/codecs/cinepak.cpp6
-rw-r--r--video/codecs/codec.h2
-rw-r--r--video/codecs/mpeg.cpp2
-rw-r--r--video/codecs/msrle.cpp2
-rw-r--r--video/codecs/msvideo1.cpp2
-rw-r--r--video/codecs/qtrle.cpp12
-rw-r--r--video/codecs/rpza.cpp2
-rw-r--r--video/codecs/smc.cpp2
-rw-r--r--video/codecs/truemotion1.cpp5
-rw-r--r--video/coktel_decoder.cpp51
-rw-r--r--video/dxa_decoder.cpp6
-rw-r--r--video/flic_decoder.cpp14
-rw-r--r--video/smk_decoder.cpp6
-rw-r--r--video/theora_decoder.cpp11
-rw-r--r--video/video_decoder.cpp53
-rw-r--r--video/video_decoder.h41
752 files changed, 27446 insertions, 9479 deletions
diff --git a/.gitignore b/.gitignore
index a046909bbf..0fe212098c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,6 +93,7 @@ project.xcworkspace
/dists/msvc*/*.SAV
/dists/msvc*/*.dat
/dists/msvc*/*.dll
+/dists/msvc*/test_runner.cpp
/doc/*.aux
/doc/*.dvi
@@ -116,12 +117,14 @@ project.xcworkspace
/devtools/create_kyradat/create_kyradat
/devtools/create_lure/create_lure
/devtools/create_mads/create_mads
+/devtools/create_mortdat/create_mortdat
/devtools/create_neverhood/create_neverhood
/devtools/create_project/create_project
/devtools/create_teenagent/create_teenagent
/devtools/create_tony/create_tony
/devtools/create_toon/create_toon
/devtools/create_translations/create_translations
+/devtools/extract_mort/extract_mort
/devtools/qtable/qtable
/devtools/skycpt/skycpt
@@ -165,6 +168,8 @@ ipch/
[Rr]elease32/
[Dd]ebug64/
[Rr]elease64/
+LLVM32/
+LLVM64/
#Ignore Qt Creator project files
ScummVM.config
@@ -174,3 +179,6 @@ ScummVM.includes
#Ignore Komodo IDE/Edit project files
*.komodoproject
+
+#Ignore Mac DS_Store files
+.DS_Store
diff --git a/AUTHORS b/AUTHORS
index 0a2d2c5fe1..fd5407b460 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -142,6 +142,14 @@ ScummVM Team
Eugene Sandulenko
David Turner
+ Mortevielle:
+ Arnaud Boutonne
+ Paul Gilbert
+
+ Neverhood:
+ Benjamin Haisch
+ Filippos Karapetis
+
Parallaction:
peres
diff --git a/Makefile.common b/Makefile.common
index aec033f0c7..02c3408684 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -253,6 +253,9 @@ endif
ifdef ENABLE_LURE
DIST_FILES_ENGINEDATA+=lure.dat
endif
+ifdef ENABLE_MORTEVIELLE
+DIST_FILES_ENGINEDATA+=mort.dat
+endif
ifdef ENABLE_NEVERHOOD
DIST_FILES_ENGINEDATA+=neverhood.dat
endif
diff --git a/audio/mixer.cpp b/audio/mixer.cpp
index ab3ed9eb2d..9e6e4596e2 100644
--- a/audio/mixer.cpp
+++ b/audio/mixer.cpp
@@ -429,7 +429,11 @@ void MixerImpl::pauseHandle(SoundHandle handle, bool paused) {
bool MixerImpl::isSoundIDActive(int id) {
Common::StackLock lock(_mutex);
+
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.updateSubsystems();
+#endif
+
for (int i = 0; i != NUM_CHANNELS; i++)
if (_channels[i] && _channels[i]->getId() == id)
return true;
@@ -446,7 +450,11 @@ int MixerImpl::getSoundID(SoundHandle handle) {
bool MixerImpl::isSoundHandleActive(SoundHandle handle) {
Common::StackLock lock(_mutex);
+
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.updateSubsystems();
+#endif
+
const int index = handle._val % NUM_CHANNELS;
return _channels[index] && _channels[index]->getHandle()._val == handle._val;
}
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index 518e260175..efcf1be615 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -163,7 +163,7 @@ int MidiDriver_FluidSynth::open() {
Common::String interpolation = ConfMan.get("fluidsynth_misc_interpolation");
int interpMethod = FLUID_INTERP_4THORDER;
-
+
if (interpolation == "none") {
interpMethod = FLUID_INTERP_NONE;
} else if (interpolation == "linear") {
diff --git a/audio/softsynth/mt32/AReverbModel.cpp b/audio/softsynth/mt32/AReverbModel.cpp
deleted file mode 100644
index 1d63832157..0000000000
--- a/audio/softsynth/mt32/AReverbModel.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mt32emu.h"
-
-#if MT32EMU_USE_REVERBMODEL == 1
-
-#include "AReverbModel.h"
-
-// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that
-// the reverb model implemented in the real devices consists of three series allpass filters preceded by a non-feedback comb (or a delay with a LPF)
-// and followed by three parallel comb filters
-
-namespace MT32Emu {
-
-// Because LA-32 chip makes it's output available to process by the Boss chip with a significant delay,
-// the Boss chip puts to the buffer the LA32 dry output when it is ready and performs processing of the _previously_ latched data.
-// Of course, the right way would be to use a dedicated variable for this, but our reverb model is way higher level,
-// so we can simply increase the input buffer size.
-static const Bit32u PROCESS_DELAY = 1;
-
-// Default reverb settings for modes 0-2. These correspond to CM-32L / LAPC-I "new" reverb settings. MT-32 reverb is a bit different.
-// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog).
-
-static const Bit32u NUM_ALLPASSES = 3;
-static const Bit32u NUM_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be perfectly processed via a comb here.
-
-static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78};
-static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632};
-static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960};
-static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145};
-static const Bit32u MODE_0_COMB_FACTOR[] = {0x3C, 0x60, 0x60, 0x60};
-static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
-static const Bit32u MODE_0_LEVELS[] = {10*1, 10*3, 10*5, 10*7, 11*9, 11*12, 11*15, 13*15};
-static const Bit32u MODE_0_LPF_AMP = 6;
-
-static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176};
-static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519};
-static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
-static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
-static const Bit32u MODE_1_COMB_FACTOR[] = {0x30, 0x60, 0x60, 0x60};
-static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
-static const Bit32u MODE_1_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 11*15, 14*15};
-static const Bit32u MODE_1_LPF_AMP = 6;
-
-static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157};
-static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539};
-static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769};
-static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1};
-static const Bit32u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20};
-static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0};
-static const Bit32u MODE_2_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 12*15, 14*15};
-static const Bit32u MODE_2_LPF_AMP = 8;
-
-static const AReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_ALLPASSES, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_LEVELS, MODE_0_LPF_AMP};
-static const AReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_ALLPASSES, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_LEVELS, MODE_1_LPF_AMP};
-static const AReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_ALLPASSES, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_LEVELS, MODE_2_LPF_AMP};
-
-static const AReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_0_SETTINGS};
-
-RingBuffer::RingBuffer(const Bit32u newsize) : size(newsize), index(0) {
- buffer = new float[size];
-}
-
-RingBuffer::~RingBuffer() {
- delete[] buffer;
- buffer = NULL;
-}
-
-float RingBuffer::next() {
- if (++index >= size) {
- index = 0;
- }
- return buffer[index];
-}
-
-bool RingBuffer::isEmpty() const {
- if (buffer == NULL) return true;
-
- float *buf = buffer;
- float max = 0.001f;
- for (Bit32u i = 0; i < size; i++) {
- if ((*buf < -max) || (*buf > max)) return false;
- buf++;
- }
- return true;
-}
-
-void RingBuffer::mute() {
- float *buf = buffer;
- for (Bit32u i = 0; i < size; i++) {
- *buf++ = 0;
- }
-}
-
-AllpassFilter::AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-
-float AllpassFilter::process(const float in) {
- // This model corresponds to the allpass filter implementation of the real CM-32L device
- // found from sample analysis
-
- const float bufferOut = next();
-
- // store input - feedback / 2
- buffer[index] = in - 0.5f * bufferOut;
-
- // return buffer output + feedforward / 2
- return bufferOut + 0.5f * buffer[index];
-}
-
-CombFilter::CombFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-
-void CombFilter::process(const float in) {
- // This model corresponds to the comb filter implementation of the real CM-32L device
- // found from sample analysis
-
- // the previously stored value
- float last = buffer[index];
-
- // prepare input + feedback
- float filterIn = in + next() * feedbackFactor;
-
- // store input + feedback processed by a low-pass filter
- buffer[index] = filterFactor * last - filterIn;
-}
-
-float CombFilter::getOutputAt(const Bit32u outIndex) const {
- return buffer[(size + index - outIndex) % size];
-}
-
-void CombFilter::setFeedbackFactor(const float useFeedbackFactor) {
- feedbackFactor = useFeedbackFactor;
-}
-
-void CombFilter::setFilterFactor(const float useFilterFactor) {
- filterFactor = useFilterFactor;
-}
-
-AReverbModel::AReverbModel(const ReverbMode mode) : allpasses(NULL), combs(NULL), currentSettings(*REVERB_SETTINGS[mode]) {}
-
-AReverbModel::~AReverbModel() {
- close();
-}
-
-void AReverbModel::open() {
- allpasses = new AllpassFilter*[NUM_ALLPASSES];
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- allpasses[i] = new AllpassFilter(currentSettings.allpassSizes[i]);
- }
- combs = new CombFilter*[NUM_COMBS];
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i] = new CombFilter(currentSettings.combSizes[i]);
- combs[i]->setFilterFactor(currentSettings.filterFactor[i] / 256.0f);
- }
- lpfAmp = currentSettings.lpfAmp / 16.0f;
- mute();
-}
-
-void AReverbModel::close() {
- if (allpasses != NULL) {
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- if (allpasses[i] != NULL) {
- delete allpasses[i];
- allpasses[i] = NULL;
- }
- }
- delete[] allpasses;
- allpasses = NULL;
- }
- if (combs != NULL) {
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- if (combs[i] != NULL) {
- delete combs[i];
- combs[i] = NULL;
- }
- }
- delete[] combs;
- combs = NULL;
- }
-}
-
-void AReverbModel::mute() {
- if (allpasses == NULL || combs == NULL) return;
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- allpasses[i]->mute();
- }
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i]->mute();
- }
-}
-
-void AReverbModel::setParameters(Bit8u time, Bit8u level) {
-// FIXME: wetLevel definitely needs ramping when changed
-// Although, most games don't set reverb level during MIDI playback
- if (combs == NULL) return;
- level &= 7;
- time &= 7;
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i]->setFeedbackFactor(currentSettings.decayTimes[(i << 3) + time] / 256.0f);
- }
- wetLevel = (level == 0 && time == 0) ? 0.0f : 0.5f * lpfAmp * currentSettings.wetLevels[level] / 256.0f;
-}
-
-bool AReverbModel::isActive() const {
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- if (!allpasses[i]->isEmpty()) return true;
- }
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- if (!combs[i]->isEmpty()) return true;
- }
- return false;
-}
-
-void AReverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- float dry, link, outL1;
-
- for (unsigned long i = 0; i < numSamples; i++) {
- dry = wetLevel * (*inLeft + *inRight);
-
- // Get the last stored sample before processing in order not to loose it
- link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
-
- combs[0]->process(-dry);
-
- link = allpasses[0]->process(link);
- link = allpasses[1]->process(link);
- link = allpasses[2]->process(link);
-
- // If the output position is equal to the comb size, get it now in order not to loose it
- outL1 = 1.5f * combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
-
- combs[1]->process(link);
- combs[2]->process(link);
- combs[3]->process(link);
-
- link = outL1 + 1.5f * combs[2]->getOutputAt(currentSettings.outLPositions[1]);
- link += combs[3]->getOutputAt(currentSettings.outLPositions[2]);
- *outLeft = link;
-
- link = 1.5f * combs[1]->getOutputAt(currentSettings.outRPositions[0]);
- link += 1.5f * combs[2]->getOutputAt(currentSettings.outRPositions[1]);
- link += combs[3]->getOutputAt(currentSettings.outRPositions[2]);
- *outRight = link;
-
- inLeft++;
- inRight++;
- outLeft++;
- outRight++;
- }
-}
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/AReverbModel.h b/audio/softsynth/mt32/AReverbModel.h
deleted file mode 100644
index c992478907..0000000000
--- a/audio/softsynth/mt32/AReverbModel.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_A_REVERB_MODEL_H
-#define MT32EMU_A_REVERB_MODEL_H
-
-namespace MT32Emu {
-
-struct AReverbSettings {
- const Bit32u * const allpassSizes;
- const Bit32u * const combSizes;
- const Bit32u * const outLPositions;
- const Bit32u * const outRPositions;
- const Bit32u * const filterFactor;
- const Bit32u * const decayTimes;
- const Bit32u * const wetLevels;
- const Bit32u lpfAmp;
-};
-
-class RingBuffer {
-protected:
- float *buffer;
- const Bit32u size;
- Bit32u index;
-
-public:
- RingBuffer(const Bit32u size);
- virtual ~RingBuffer();
- float next();
- bool isEmpty() const;
- void mute();
-};
-
-class AllpassFilter : public RingBuffer {
-public:
- AllpassFilter(const Bit32u size);
- float process(const float in);
-};
-
-class CombFilter : public RingBuffer {
- float feedbackFactor;
- float filterFactor;
-
-public:
- CombFilter(const Bit32u size);
- void process(const float in);
- float getOutputAt(const Bit32u outIndex) const;
- void setFeedbackFactor(const float useFeedbackFactor);
- void setFilterFactor(const float useFilterFactor);
-};
-
-class AReverbModel : public ReverbModel {
- AllpassFilter **allpasses;
- CombFilter **combs;
-
- const AReverbSettings &currentSettings;
- float lpfAmp;
- float wetLevel;
- void mute();
-
-public:
- AReverbModel(const ReverbMode mode);
- ~AReverbModel();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index cc0219b741..c16f7f17da 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -15,10 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+//#include <memory.h>
#include "mt32emu.h"
-
-#if MT32EMU_USE_REVERBMODEL == 2
-
#include "BReverbModel.h"
// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that
@@ -62,9 +60,9 @@ static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
static const Bit32u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60};
static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
+ 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
+ 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
+ 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
static const Bit32u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0};
static const Bit32u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
static const Bit32u MODE_1_LPF_AMP = 0x60;
@@ -103,7 +101,11 @@ static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTING
// This algorithm tries to emulate exactly Boss multiplication operation (at least this is what we see on reverb RAM data lines).
// Also LA32 is suspected to use the similar one to perform PCM interpolation and ring modulation.
-static Bit32s weirdMul(Bit32s a, Bit8u addMask, Bit8u carryMask) {
+static Sample weirdMul(Sample a, Bit8u addMask, Bit8u carryMask) {
+ (void)carryMask;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ return a * addMask / 256.0f;
+#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
Bit8u mask = 0x80;
Bit32s res = 0;
for (int i = 0; i < 8; i++) {
@@ -113,10 +115,13 @@ static Bit32s weirdMul(Bit32s a, Bit8u addMask, Bit8u carryMask) {
mask >>= 1;
}
return res;
+#else
+ return Sample(((Bit32s)a * addMask) >> 8);
+#endif
}
RingBuffer::RingBuffer(Bit32u newsize) : size(newsize), index(0) {
- buffer = new Bit16s[size];
+ buffer = new Sample[size];
}
RingBuffer::~RingBuffer() {
@@ -124,7 +129,7 @@ RingBuffer::~RingBuffer() {
buffer = NULL;
}
-Bit32s RingBuffer::next() {
+Sample RingBuffer::next() {
if (++index >= size) {
index = 0;
}
@@ -134,52 +139,69 @@ Bit32s RingBuffer::next() {
bool RingBuffer::isEmpty() const {
if (buffer == NULL) return true;
- Bit16s *buf = buffer;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ Sample max = 0.001f;
+#else
+ Sample max = 8;
+#endif
+ Sample *buf = buffer;
for (Bit32u i = 0; i < size; i++) {
- if (*buf < -8 || *buf > 8) return false;
+ if (*buf < -max || *buf > max) return false;
buf++;
}
return true;
}
void RingBuffer::mute() {
- Bit16s *buf = buffer;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ Sample *buf = buffer;
for (Bit32u i = 0; i < size; i++) {
*buf++ = 0;
}
+#else
+ memset(buffer, 0, size * sizeof(Sample));
+#endif
}
AllpassFilter::AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-Bit32s AllpassFilter::process(const Bit32s in) {
+Sample AllpassFilter::process(const Sample in) {
// This model corresponds to the allpass filter implementation of the real CM-32L device
// found from sample analysis
- Bit16s bufferOut = next();
+ const Sample bufferOut = next();
+#if MT32EMU_USE_FLOAT_SAMPLES
+ // store input - feedback / 2
+ buffer[index] = in - 0.5f * bufferOut;
+
+ // return buffer output + feedforward / 2
+ return bufferOut + 0.5f * buffer[index];
+#else
// store input - feedback / 2
buffer[index] = in - (bufferOut >> 1);
// return buffer output + feedforward / 2
return bufferOut + (buffer[index] >> 1);
+#endif
}
CombFilter::CombFilter(const Bit32u useSize, const Bit32u useFilterFactor) : RingBuffer(useSize), filterFactor(useFilterFactor) {}
-void CombFilter::process(const Bit32s in) {
+void CombFilter::process(const Sample in) {
// This model corresponds to the comb filter implementation of the real CM-32L device
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// prepare input + feedback
- Bit32s filterIn = in + weirdMul(next(), feedbackFactor, 0xF0 /* Maybe 0x80 ? */);
+ const Sample filterIn = in + weirdMul(next(), feedbackFactor, 0xF0 /* Maybe 0x80 ? */);
// store input + feedback processed by a low-pass filter
buffer[index] = weirdMul(last, filterFactor, 0x40) - filterIn;
}
-Bit32s CombFilter::getOutputAt(const Bit32u outIndex) const {
+Sample CombFilter::getOutputAt(const Bit32u outIndex) const {
return buffer[(size + index - outIndex) % size];
}
@@ -190,15 +212,15 @@ void CombFilter::setFeedbackFactor(const Bit32u useFeedbackFactor) {
DelayWithLowPassFilter::DelayWithLowPassFilter(const Bit32u useSize, const Bit32u useFilterFactor, const Bit32u useAmp)
: CombFilter(useSize, useFilterFactor), amp(useAmp) {}
-void DelayWithLowPassFilter::process(const Bit32s in) {
+void DelayWithLowPassFilter::process(const Sample in) {
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// move to the next index
next();
// low-pass filter process
- Bit32s lpfOut = weirdMul(last, filterFactor, 0xFF) + in;
+ Sample lpfOut = weirdMul(last, filterFactor, 0xFF) + in;
// store lpfOut multiplied by LPF amp factor
buffer[index] = weirdMul(lpfOut, amp, 0xFF);
@@ -206,26 +228,26 @@ void DelayWithLowPassFilter::process(const Bit32s in) {
TapDelayCombFilter::TapDelayCombFilter(const Bit32u useSize, const Bit32u useFilterFactor) : CombFilter(useSize, useFilterFactor) {}
-void TapDelayCombFilter::process(const Bit32s in) {
+void TapDelayCombFilter::process(const Sample in) {
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// move to the next index
next();
// prepare input + feedback
// Actually, the size of the filter varies with the TIME parameter, the feedback sample is taken from the position just below the right output
- Bit32s filterIn = in + weirdMul(getOutputAt(outR + MODE_3_FEEDBACK_DELAY), feedbackFactor, 0xF0);
+ const Sample filterIn = in + weirdMul(getOutputAt(outR + MODE_3_FEEDBACK_DELAY), feedbackFactor, 0xF0);
// store input + feedback processed by a low-pass filter
buffer[index] = weirdMul(last, filterFactor, 0xF0) - filterIn;
}
-Bit32s TapDelayCombFilter::getLeftOutput() const {
+Sample TapDelayCombFilter::getLeftOutput() const {
return getOutputAt(outL + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY);
}
-Bit32s TapDelayCombFilter::getRightOutput() const {
+Sample TapDelayCombFilter::getRightOutput() const {
return getOutputAt(outR + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY);
}
@@ -327,14 +349,14 @@ bool BReverbModel::isActive() const {
return false;
}
-void BReverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- Bit32s dry, link, outL1, outR1;
+void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples) {
+ Sample dry;
- for (unsigned long i = 0; i < numSamples; i++) {
+ while (numSamples > 0) {
if (tapDelayMode) {
- dry = Bit32s(*inLeft * 8192.0f) + Bit32s(*inRight * 8192.0f);
+ dry = *inLeft + *inRight;
} else {
- dry = Bit32s(*inLeft * 8192.0f) / 2 + Bit32s(*inRight * 8192.0f) / 2;
+ dry = *inLeft / 2 + *inRight / 2;
}
// Looks like dryAmp doesn't change in MT-32 but it does in CM-32L / LAPC-I
@@ -343,44 +365,53 @@ void BReverbModel::process(const float *inLeft, const float *inRight, float *out
if (tapDelayMode) {
TapDelayCombFilter *comb = static_cast<TapDelayCombFilter *> (*combs);
comb->process(dry);
- *outLeft = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF) / 8192.0f;
- *outRight = weirdMul(comb->getRightOutput(), wetLevel, 0xFF) / 8192.0f;
+ *outLeft = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF);
+ *outRight = weirdMul(comb->getRightOutput(), wetLevel, 0xFF);
} else {
- // Get the last stored sample before processing in order not to loose it
- link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
+ // If the output position is equal to the comb size, get it now in order not to loose it
+ Sample link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
// Entrance LPF. Note, comb.process() differs a bit here.
combs[0]->process(dry);
+#if !MT32EMU_USE_FLOAT_SAMPLES
// This introduces reverb noise which actually makes output from the real Boss chip nondeterministic
link = link - 1;
+#endif
link = allpasses[0]->process(link);
link = allpasses[1]->process(link);
link = allpasses[2]->process(link);
// If the output position is equal to the comb size, get it now in order not to loose it
- outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
- outL1 += outL1 >> 1;
+ Sample outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
combs[1]->process(link);
combs[2]->process(link);
combs[3]->process(link);
- link = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
- link += link >> 1;
- link += outL1;
- link += combs[3]->getOutputAt(currentSettings.outLPositions[2]);
- *outLeft = weirdMul(link, wetLevel, 0xFF) / 8192.0f;
+ Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
+ Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]);
+ Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
+ Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
+ Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]);
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *outLeft = 1.5f * (outL1 + outL2) + outL3;
+ *outRight = 1.5f * (outR1 + outR2) + outR3;
+#else
+ outL1 += outL1 >> 1;
+ outL2 += outL2 >> 1;
+ *outLeft = outL1 + outL2 + outL3;
- outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
outR1 += outR1 >> 1;
- link = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
- link += link >> 1;
- link += outR1;
- link += combs[3]->getOutputAt(currentSettings.outRPositions[2]);
- *outRight = weirdMul(link, wetLevel, 0xFF) / 8192.0f;
+ outR2 += outR2 >> 1;
+ *outRight = outR1 + outR2 + outR3;
+#endif
+ *outLeft = weirdMul(*outLeft, wetLevel, 0xFF);
+ *outRight = weirdMul(*outRight, wetLevel, 0xFF);
}
+ numSamples--;
inLeft++;
inRight++;
outLeft++;
@@ -389,5 +420,3 @@ void BReverbModel::process(const float *inLeft, const float *inRight, float *out
}
}
-
-#endif
diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h
index d6fcb73c13..7cf431db0d 100644
--- a/audio/softsynth/mt32/BReverbModel.h
+++ b/audio/softsynth/mt32/BReverbModel.h
@@ -36,14 +36,14 @@ struct BReverbSettings {
class RingBuffer {
protected:
- Bit16s *buffer;
+ Sample *buffer;
const Bit32u size;
Bit32u index;
public:
RingBuffer(const Bit32u size);
virtual ~RingBuffer();
- Bit32s next();
+ Sample next();
bool isEmpty() const;
void mute();
};
@@ -51,7 +51,7 @@ public:
class AllpassFilter : public RingBuffer {
public:
AllpassFilter(const Bit32u size);
- Bit32s process(const Bit32s in);
+ Sample process(const Sample in);
};
class CombFilter : public RingBuffer {
@@ -61,8 +61,8 @@ protected:
public:
CombFilter(const Bit32u size, const Bit32u useFilterFactor);
- virtual void process(const Bit32s in); // Actually, no need to make it virtual, but for sure
- Bit32s getOutputAt(const Bit32u outIndex) const;
+ virtual void process(const Sample in);
+ Sample getOutputAt(const Bit32u outIndex) const;
void setFeedbackFactor(const Bit32u useFeedbackFactor);
};
@@ -71,7 +71,7 @@ class DelayWithLowPassFilter : public CombFilter {
public:
DelayWithLowPassFilter(const Bit32u useSize, const Bit32u useFilterFactor, const Bit32u useAmp);
- void process(const Bit32s in);
+ void process(const Sample in);
void setFeedbackFactor(const Bit32u) {}
};
@@ -81,13 +81,13 @@ class TapDelayCombFilter : public CombFilter {
public:
TapDelayCombFilter(const Bit32u useSize, const Bit32u useFilterFactor);
- void process(const Bit32s in);
- Bit32s getLeftOutput() const;
- Bit32s getRightOutput() const;
+ void process(const Sample in);
+ Sample getLeftOutput() const;
+ Sample getRightOutput() const;
void setOutputPositions(const Bit32u useOutL, const Bit32u useOutR);
};
-class BReverbModel : public ReverbModel {
+class BReverbModel {
AllpassFilter **allpasses;
CombFilter **combs;
@@ -100,10 +100,12 @@ class BReverbModel : public ReverbModel {
public:
BReverbModel(const ReverbMode mode);
~BReverbModel();
+ // After construction or a close(), open() must be called at least once before any other call (with the exception of close()).
void open();
+ // May be called multiple times without an open() in between.
void close();
void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
+ void process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples);
bool isActive() const;
};
diff --git a/audio/softsynth/mt32/DelayReverb.cpp b/audio/softsynth/mt32/DelayReverb.cpp
deleted file mode 100644
index d80c98acbc..0000000000
--- a/audio/softsynth/mt32/DelayReverb.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-//#include <cmath>
-//#include <cstring>
-#include "mt32emu.h"
-#include "DelayReverb.h"
-
-namespace MT32Emu {
-
-// CONFIRMED: The values below are found via analysis of digital samples and tracing reverb RAM address / data lines. Checked with all time and level combinations.
-// Obviously:
-// rightDelay = (leftDelay - 2) * 2 + 2
-// echoDelay = rightDelay - 1
-// Leaving these separate in case it's useful for work on other reverb modes...
-static const Bit32u REVERB_TIMINGS[8][3]= {
- // {leftDelay, rightDelay, feedbackDelay}
- {402, 802, 801},
- {626, 1250, 1249},
- {962, 1922, 1921},
- {1490, 2978, 2977},
- {2258, 4514, 4513},
- {3474, 6946, 6945},
- {5282, 10562, 10561},
- {8002, 16002, 16001}
-};
-
-// Reverb amp is found as dryAmp * wetAmp
-static const Bit32u REVERB_AMP[8] = {0x20*0x18, 0x50*0x18, 0x50*0x28, 0x50*0x40, 0x50*0x60, 0x50*0x80, 0x50*0xA8, 0x50*0xF8};
-static const Bit32u REVERB_FEEDBACK67 = 0x60;
-static const Bit32u REVERB_FEEDBACK = 0x68;
-static const float LPF_VALUE = 0x68 / 256.0f;
-
-static const Bit32u BUFFER_SIZE = 16384;
-
-DelayReverb::DelayReverb() {
- buf = NULL;
- setParameters(0, 0);
-}
-
-DelayReverb::~DelayReverb() {
- delete[] buf;
-}
-
-void DelayReverb::open() {
- if (buf == NULL) {
- delete[] buf;
-
- buf = new float[BUFFER_SIZE];
-
- recalcParameters();
-
- // mute buffer
- bufIx = 0;
- if (buf != NULL) {
- for (unsigned int i = 0; i < BUFFER_SIZE; i++) {
- buf[i] = 0.0f;
- }
- }
- }
-}
-
-void DelayReverb::close() {
- delete[] buf;
- buf = NULL;
-}
-
-// This method will always trigger a flush of the buffer
-void DelayReverb::setParameters(Bit8u newTime, Bit8u newLevel) {
- time = newTime;
- level = newLevel;
- recalcParameters();
-}
-
-void DelayReverb::recalcParameters() {
- // Number of samples between impulse and eventual appearance on the left channel
- delayLeft = REVERB_TIMINGS[time][0];
- // Number of samples between impulse and eventual appearance on the right channel
- delayRight = REVERB_TIMINGS[time][1];
- // Number of samples between a response and that response feeding back/echoing
- delayFeedback = REVERB_TIMINGS[time][2];
-
- if (level < 3 || time < 6) {
- feedback = REVERB_FEEDBACK / 256.0f;
- } else {
- feedback = REVERB_FEEDBACK67 / 256.0f;
- }
-
- // Overall output amp
- amp = (level == 0 && time == 0) ? 0.0f : REVERB_AMP[level] / 65536.0f;
-}
-
-void DelayReverb::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- if (buf == NULL) return;
-
- for (unsigned int sampleIx = 0; sampleIx < numSamples; sampleIx++) {
- // The ring buffer write index moves backwards; reads are all done with positive offsets.
- Bit32u bufIxPrev = (bufIx + 1) % BUFFER_SIZE;
- Bit32u bufIxLeft = (bufIx + delayLeft) % BUFFER_SIZE;
- Bit32u bufIxRight = (bufIx + delayRight) % BUFFER_SIZE;
- Bit32u bufIxFeedback = (bufIx + delayFeedback) % BUFFER_SIZE;
-
- // Attenuated input samples and feedback response are directly added to the current ring buffer location
- float lpfIn = amp * (inLeft[sampleIx] + inRight[sampleIx]) + feedback * buf[bufIxFeedback];
-
- // Single-pole IIR filter found on real devices
- buf[bufIx] = buf[bufIxPrev] * LPF_VALUE - lpfIn;
-
- outLeft[sampleIx] = buf[bufIxLeft];
- outRight[sampleIx] = buf[bufIxRight];
-
- bufIx = (BUFFER_SIZE + bufIx - 1) % BUFFER_SIZE;
- }
-}
-
-bool DelayReverb::isActive() const {
- if (buf == NULL) return false;
-
- float *b = buf;
- float max = 0.001f;
- for (Bit32u i = 0; i < BUFFER_SIZE; i++) {
- if ((*b < -max) || (*b > max)) return true;
- b++;
- }
- return false;
-}
-
-}
diff --git a/audio/softsynth/mt32/DelayReverb.h b/audio/softsynth/mt32/DelayReverb.h
deleted file mode 100644
index c8003832b5..0000000000
--- a/audio/softsynth/mt32/DelayReverb.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_DELAYREVERB_H
-#define MT32EMU_DELAYREVERB_H
-
-namespace MT32Emu {
-
-class DelayReverb : public ReverbModel {
-private:
- Bit8u time;
- Bit8u level;
-
- Bit32u bufIx;
- float *buf;
-
- Bit32u delayLeft;
- Bit32u delayRight;
- Bit32u delayFeedback;
-
- float amp;
- float feedback;
-
- void recalcParameters();
-
-public:
- DelayReverb();
- ~DelayReverb();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-}
-#endif
diff --git a/audio/softsynth/mt32/FreeverbModel.cpp b/audio/softsynth/mt32/FreeverbModel.cpp
deleted file mode 100644
index bd9c70b6f4..0000000000
--- a/audio/softsynth/mt32/FreeverbModel.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mt32emu.h"
-#include "FreeverbModel.h"
-
-#include "freeverb.h"
-
-namespace MT32Emu {
-
-FreeverbModel::FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp) {
- freeverb = NULL;
- scaleTuning = useScaleTuning;
- filtVal = useFiltVal;
- wet = useWet;
- room = useRoom;
- damp = useDamp;
-}
-
-FreeverbModel::~FreeverbModel() {
- delete freeverb;
-}
-
-void FreeverbModel::open() {
- if (freeverb == NULL) {
- freeverb = new revmodel(scaleTuning);
- }
- freeverb->mute();
-
- // entrance Lowpass filter factor
- freeverb->setfiltval(filtVal);
-
- // decay speed of high frequencies in the wet signal
- freeverb->setdamp(damp);
-}
-
-void FreeverbModel::close() {
- delete freeverb;
- freeverb = NULL;
-}
-
-void FreeverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- freeverb->process(inLeft, inRight, outLeft, outRight, numSamples);
-}
-
-void FreeverbModel::setParameters(Bit8u time, Bit8u level) {
- // wet signal level
- // FIXME: need to implement some sort of reverb level ramping
- freeverb->setwet((float)level / 7.0f * wet);
-
- // wet signal decay speed
- static float roomTable[] = {
- 0.25f, 0.37f, 0.54f, 0.71f, 0.78f, 0.86f, 0.93f, 1.00f,
- -1.00f, -0.50f, 0.00f, 0.30f, 0.51f, 0.64f, 0.77f, 0.90f,
- 0.50f, 0.57f, 0.70f, 0.77f, 0.85f, 0.93f, 0.96f, 1.01f};
- freeverb->setroomsize(roomTable[8 * room + time]);
-}
-
-bool FreeverbModel::isActive() const {
- // FIXME: Not bothering to do this properly since we'll be replacing Freeverb soon...
- return false;
-}
-
-}
diff --git a/audio/softsynth/mt32/FreeverbModel.h b/audio/softsynth/mt32/FreeverbModel.h
deleted file mode 100644
index 5ea11f1f40..0000000000
--- a/audio/softsynth/mt32/FreeverbModel.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_FREEVERB_MODEL_H
-#define MT32EMU_FREEVERB_MODEL_H
-
-class revmodel;
-
-namespace MT32Emu {
-
-class FreeverbModel : public ReverbModel {
- revmodel *freeverb;
- float scaleTuning;
- float filtVal;
- float wet;
- Bit8u room;
- float damp;
-public:
- FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp);
- ~FreeverbModel();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/LegacyWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 35ca975018..486942b75c 100644
--- a/audio/softsynth/mt32/LegacyWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -18,9 +18,7 @@
//#include <cmath>
#include "mt32emu.h"
#include "mmath.h"
-#include "LegacyWaveGenerator.h"
-
-#if MT32EMU_ACCURATE_WG == 1
+#include "LA32FloatWaveGenerator.h"
namespace MT32Emu {
@@ -317,7 +315,7 @@ void LA32PartialPair::generateNextSample(const PairType useMaster, const Bit32u
}
}
-Bit16s LA32PartialPair::nextOutSample() {
+float LA32PartialPair::nextOutSample() {
float outputSample;
if (ringModulated) {
float ringModulatedSample = masterOutputSample * slaveOutputSample;
@@ -325,7 +323,7 @@ Bit16s LA32PartialPair::nextOutSample() {
} else {
outputSample = masterOutputSample + slaveOutputSample;
}
- return Bit16s(outputSample * 8192.0f);
+ return outputSample;
}
void LA32PartialPair::deactivate(const PairType useMaster) {
@@ -343,5 +341,3 @@ bool LA32PartialPair::isActive(const PairType useMaster) const {
}
}
-
-#endif // #if MT32EMU_ACCURATE_WG == 1
diff --git a/audio/softsynth/mt32/LegacyWaveGenerator.h b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
index 81c1b9c713..9046160083 100644
--- a/audio/softsynth/mt32/LegacyWaveGenerator.h
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
@@ -15,8 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if MT32EMU_ACCURATE_WG == 1
-
#ifndef MT32EMU_LA32_WAVE_GENERATOR_H
#define MT32EMU_LA32_WAVE_GENERATOR_H
@@ -130,7 +128,7 @@ public:
void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff);
// Perform mixing / ring modulation and return the result
- Bit16s nextOutSample();
+ float nextOutSample();
// Deactivate the WG engine
void deactivate(const PairType master);
@@ -142,5 +140,3 @@ public:
} // namespace MT32Emu
#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
-
-#endif // #if MT32EMU_ACCURATE_WG == 1
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index 80650699fb..9ffc2ca32e 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -20,7 +20,9 @@
#include "mmath.h"
#include "LA32WaveGenerator.h"
-#if MT32EMU_ACCURATE_WG == 0
+#if MT32EMU_USE_FLOAT_SAMPLES
+#include "LA32FloatWaveGenerator.cpp"
+#else
namespace MT32Emu {
@@ -129,7 +131,8 @@ void LA32WaveGenerator::advancePosition() {
computePositions(highLinearLength, lowLinearLength, resonanceWaveLengthFactor);
// resonancePhase computation hack
- *(int*)&resonancePhase = ((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3;
+ int *resonancePhaseAlias = (int *)&resonancePhase;
+ *resonancePhaseAlias = ((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3;
}
void LA32WaveGenerator::generateNextSquareWaveLogSample() {
@@ -415,4 +418,4 @@ bool LA32PartialPair::isActive(const PairType useMaster) const {
}
-#endif // #if MT32EMU_ACCURATE_WG == 0
+#endif // #if MT32EMU_USE_FLOAT_SAMPLES
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.h b/audio/softsynth/mt32/LA32WaveGenerator.h
index 37a4aead85..4bc04c78d3 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.h
+++ b/audio/softsynth/mt32/LA32WaveGenerator.h
@@ -15,7 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if MT32EMU_ACCURATE_WG == 0
+#if MT32EMU_USE_FLOAT_SAMPLES
+#include "LA32FloatWaveGenerator.h"
+#else
#ifndef MT32EMU_LA32_WAVE_GENERATOR_H
#define MT32EMU_LA32_WAVE_GENERATOR_H
@@ -243,4 +245,4 @@ public:
#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
-#endif // #if MT32EMU_ACCURATE_WG == 0
+#endif // #if MT32EMU_USE_FLOAT_SAMPLES
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
index 88404316eb..8a0daf3b38 100644
--- a/audio/softsynth/mt32/Part.cpp
+++ b/audio/softsynth/mt32/Part.cpp
@@ -67,18 +67,12 @@ Part::Part(Synth *useSynth, unsigned int usePartNum) {
pitchBend = 0;
activePartialCount = 0;
memset(patchCache, 0, sizeof(patchCache));
- for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
- freePolys.prepend(new Poly(this));
- }
}
Part::~Part() {
while (!activePolys.isEmpty()) {
delete activePolys.takeFirst();
}
- while (!freePolys.isEmpty()) {
- delete freePolys.takeFirst();
- }
}
void Part::setDataEntryMSB(unsigned char midiDataEntryMSB) {
@@ -431,23 +425,10 @@ void Part::noteOn(unsigned int midiKey, unsigned int velocity) {
playPoly(patchCache, NULL, midiKey, key, velocity);
}
-void Part::abortPoly(Poly *poly) {
- if (poly->startAbort()) {
- while (poly->isActive()) {
- if (!synth->prerender()) {
- synth->printDebug("%s (%s): Ran out of prerender space to abort poly gracefully", name, currentInstr);
- poly->terminate();
- break;
- }
- }
- }
-}
-
bool Part::abortFirstPoly(unsigned int key) {
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
if (poly->getKey() == key) {
- abortPoly(poly);
- return true;
+ return poly->startAbort();
}
}
return false;
@@ -456,8 +437,7 @@ bool Part::abortFirstPoly(unsigned int key) {
bool Part::abortFirstPoly(PolyState polyState) {
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
if (poly->getState() == polyState) {
- abortPoly(poly);
- return true;
+ return poly->startAbort();
}
}
return false;
@@ -474,8 +454,7 @@ bool Part::abortFirstPoly() {
if (activePolys.isEmpty()) {
return false;
}
- abortPoly(activePolys.getFirst());
- return true;
+ return activePolys.getFirst()->startAbort();
}
void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity) {
@@ -489,6 +468,7 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt
if ((patchTemp->patch.assignMode & 2) == 0) {
// Single-assign mode
abortFirstPoly(key);
+ if (synth->isAbortingPoly()) return;
}
if (!synth->partialManager->freePartials(needPartials, partNum)) {
@@ -498,12 +478,13 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt
#endif
return;
}
+ if (synth->isAbortingPoly()) return;
- if (freePolys.isEmpty()) {
+ Poly *poly = synth->partialManager->assignPolyToPart(this);
+ if (poly == NULL) {
synth->printDebug("%s (%s): No free poly to play key %d (velocity %d)", name, currentInstr, midiKey, velocity);
return;
}
- Poly *poly = freePolys.takeFirst();
if (patchTemp->patch.assignMode & 1) {
// Priority to data first received
activePolys.prepend(poly);
@@ -596,6 +577,10 @@ unsigned int Part::getActivePartialCount() const {
return activePartialCount;
}
+const Poly *Part::getFirstActivePoly() const {
+ return activePolys.getFirst();
+}
+
unsigned int Part::getActiveNonReleasingPartialCount() const {
unsigned int activeNonReleasingPartialCount = 0;
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
@@ -606,11 +591,15 @@ unsigned int Part::getActiveNonReleasingPartialCount() const {
return activeNonReleasingPartialCount;
}
+Synth *Part::getSynth() const {
+ return synth;
+}
+
void Part::partialDeactivated(Poly *poly) {
activePartialCount--;
if (!poly->isActive()) {
activePolys.remove(poly);
- freePolys.prepend(poly);
+ synth->partialManager->polyFreed(poly);
synth->polyStateChanged(partNum);
}
}
diff --git a/audio/softsynth/mt32/Part.h b/audio/softsynth/mt32/Part.h
index b6585880fe..2aeeaf5bd7 100644
--- a/audio/softsynth/mt32/Part.h
+++ b/audio/softsynth/mt32/Part.h
@@ -51,13 +51,11 @@ private:
unsigned int activePartialCount;
PatchCache patchCache[4];
- PolyList freePolys;
PolyList activePolys;
void setPatch(const PatchParam *patch);
unsigned int midiKeyToKey(unsigned int midiKey);
- void abortPoly(Poly *poly);
bool abortFirstPoly(unsigned int key);
protected:
@@ -110,8 +108,10 @@ public:
virtual void setTimbre(TimbreParam *timbre);
virtual unsigned int getAbsTimbreNum() const;
const char *getCurrentInstr() const;
+ const Poly *getFirstActivePoly() const;
unsigned int getActivePartialCount() const;
unsigned int getActiveNonReleasingPartialCount() const;
+ Synth *getSynth() const;
const MemParams::PatchTemp *getPatchTemp() const;
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index b80a028515..c7848f02d8 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -131,6 +131,7 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
}
// FIXME: Sample analysis suggests that the use of panVal is linear, but there are some some quirks that still need to be resolved.
+ // FIXME: I suppose this should be panVal / 8 and undoubtly integer, clarify ASAP
stereoVolume.leftVol = panVal / 7.0f;
stereoVolume.rightVol = 1.0f - stereoVolume.leftVol;
@@ -198,9 +199,6 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
if (!hasRingModulatingSlave()) {
la32Pair.deactivate(LA32PartialPair::SLAVE);
}
- // Temporary integration hack
- stereoVolume.leftVol /= 8192.0f;
- stereoVolume.rightVol /= 8192.0f;
}
Bit32u Partial::getAmpValue() {
@@ -232,7 +230,7 @@ Bit32u Partial::getCutoffValue() {
return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal;
}
-unsigned long Partial::generateSamples(Bit16s *partialBuf, unsigned long length) {
+unsigned long Partial::generateSamples(Sample *partialBuf, unsigned long length) {
if (!isActive() || alreadyOutputed) {
return 0;
}
@@ -258,7 +256,7 @@ unsigned long Partial::generateSamples(Bit16s *partialBuf, unsigned long length)
}
}
}
- *partialBuf++ = la32Pair.nextOutSample();
+ *(partialBuf++) = la32Pair.nextOutSample();
}
unsigned long renderedSamples = sampleNum;
sampleNum = 0;
@@ -288,7 +286,18 @@ Synth *Partial::getSynth() const {
return synth;
}
-bool Partial::produceOutput(float *leftBuf, float *rightBuf, unsigned long length) {
+TVA *Partial::getTVA() const {
+ return tva;
+}
+
+void Partial::backupCache(const PatchCache &cache) {
+ if (patchCache == &cache) {
+ cachebackup = cache;
+ patchCache = &cachebackup;
+ }
+}
+
+bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long length) {
if (!isActive() || alreadyOutputed || isRingModulatingSlave()) {
return false;
}
@@ -296,14 +305,18 @@ bool Partial::produceOutput(float *leftBuf, float *rightBuf, unsigned long lengt
synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum);
return false;
}
- unsigned long numGenerated = generateSamples(myBuffer, length);
+ Sample buffer[MAX_SAMPLES_PER_RUN];
+ unsigned long numGenerated = generateSamples(buffer, length);
for (unsigned int i = 0; i < numGenerated; i++) {
- *leftBuf++ = myBuffer[i] * stereoVolume.leftVol;
- *rightBuf++ = myBuffer[i] * stereoVolume.rightVol;
- }
- for (; numGenerated < length; numGenerated++) {
- *leftBuf++ = 0.0f;
- *rightBuf++ = 0.0f;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *(leftBuf++) += buffer[i] * stereoVolume.leftVol;
+ *(rightBuf++) += buffer[i] * stereoVolume.rightVol;
+#else
+ *leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + Bit32s(buffer[i] * stereoVolume.leftVol));
+ *rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + Bit32s(buffer[i] * stereoVolume.rightVol));
+ leftBuf++;
+ rightBuf++;
+#endif
}
return true;
}
diff --git a/audio/softsynth/mt32/Partial.h b/audio/softsynth/mt32/Partial.h
index 21b1bfe376..358cb9d2d9 100644
--- a/audio/softsynth/mt32/Partial.h
+++ b/audio/softsynth/mt32/Partial.h
@@ -44,8 +44,6 @@ private:
int structurePosition; // 0 or 1 of a structure pair
StereoVolume stereoVolume;
- Bit16s myBuffer[MAX_SAMPLES_PER_RUN];
-
// Only used for PCM partials
int pcmNum;
// FIXME: Give this a better name (e.g. pcmWaveInfo)
@@ -56,6 +54,11 @@ private:
int pulseWidthVal;
Poly *poly;
+ Partial *pair;
+
+ TVA *tva;
+ TVP *tvp;
+ TVF *tvf;
LA32Ramp ampRamp;
LA32Ramp cutoffModifierRamp;
@@ -63,18 +66,13 @@ private:
// TODO: This should be owned by PartialPair
LA32PartialPair la32Pair;
+ const PatchCache *patchCache;
+ PatchCache cachebackup;
+
Bit32u getAmpValue();
Bit32u getCutoffValue();
public:
- const PatchCache *patchCache;
- TVA *tva;
- TVP *tvp;
- TVF *tvf;
-
- PatchCache cachebackup;
-
- Partial *pair;
bool alreadyOutputed;
Partial(Synth *synth, int debugPartialNum);
@@ -97,14 +95,17 @@ public:
bool isPCM() const;
const ControlROMPCMStruct *getControlROMPCMStruct() const;
Synth *getSynth() const;
+ TVA *getTVA() const;
+
+ void backupCache(const PatchCache &cache);
// Returns true only if data written to buffer
// This function (unlike the one below it) returns processed stereo samples
// made from combining this single partial with its pair, if it has one.
- bool produceOutput(float *leftBuf, float *rightBuf, unsigned long length);
+ bool produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long length);
// This function writes mono sample output to the provided buffer, and returns the number of samples written
- unsigned long generateSamples(Bit16s *partialBuf, unsigned long length);
+ unsigned long generateSamples(Sample *partialBuf, unsigned long length);
};
}
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
index 436e7a353e..905b5b8cf3 100644
--- a/audio/softsynth/mt32/PartialManager.cpp
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -25,19 +25,26 @@ namespace MT32Emu {
PartialManager::PartialManager(Synth *useSynth, Part **useParts) {
synth = useSynth;
parts = useParts;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ partialTable = new Partial *[synth->getPartialCount()];
+ freePolys = new Poly *[synth->getPartialCount()];
+ firstFreePolyIndex = 0;
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i] = new Partial(synth, i);
+ freePolys[i] = new Poly();
}
}
PartialManager::~PartialManager(void) {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
delete partialTable[i];
+ if (freePolys[i] != NULL) delete freePolys[i];
}
+ delete[] partialTable;
+ delete[] freePolys;
}
void PartialManager::clearAlreadyOutputed() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i]->alreadyOutputed = false;
}
}
@@ -46,12 +53,12 @@ bool PartialManager::shouldReverb(int i) {
return partialTable[i]->shouldReverb();
}
-bool PartialManager::produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength) {
+bool PartialManager::produceOutput(int i, Sample *leftBuf, Sample *rightBuf, Bit32u bufferLength) {
return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength);
}
void PartialManager::deactivateAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i]->deactivate();
}
}
@@ -69,7 +76,7 @@ Partial *PartialManager::allocPartial(int partNum) {
Partial *outPartial = NULL;
// Get the first inactive partial
- for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ for (unsigned int partialNum = 0; partialNum < synth->getPartialCount(); partialNum++) {
if (!partialTable[partialNum]->isActive()) {
outPartial = partialTable[partialNum];
break;
@@ -83,7 +90,7 @@ Partial *PartialManager::allocPartial(int partNum) {
unsigned int PartialManager::getFreePartialCount(void) {
int count = 0;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
if (!partialTable[i]->isActive()) {
count++;
}
@@ -94,7 +101,7 @@ unsigned int PartialManager::getFreePartialCount(void) {
// This function is solely used to gather data for debug output at the moment.
void PartialManager::getPerPartPartialUsage(unsigned int perPartPartialUsage[9]) {
memset(perPartPartialUsage, 0, 9 * sizeof(unsigned int));
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
if (partialTable[i]->isActive()) {
perPartPartialUsage[partialTable[i]->getOwnerPart()]++;
}
@@ -189,7 +196,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
break;
}
#endif
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -206,7 +213,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!abortFirstPolyPreferHeldWhereReserveExceeded(partNum)) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -222,7 +229,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!abortFirstPolyPreferHeldWhereReserveExceeded(-1)) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -233,7 +240,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!parts[partNum]->abortFirstPolyPreferHeld()) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -243,10 +250,39 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
}
const Partial *PartialManager::getPartial(unsigned int partialNum) const {
- if (partialNum > MT32EMU_MAX_PARTIALS - 1) {
+ if (partialNum > synth->getPartialCount() - 1) {
return NULL;
}
return partialTable[partialNum];
}
+Poly *PartialManager::assignPolyToPart(Part *part) {
+ if (firstFreePolyIndex < synth->getPartialCount()) {
+ Poly *poly = freePolys[firstFreePolyIndex];
+ freePolys[firstFreePolyIndex] = NULL;
+ firstFreePolyIndex++;
+ poly->setPart(part);
+ return poly;
+ }
+ return NULL;
+}
+
+void PartialManager::polyFreed(Poly *poly) {
+ if (0 == firstFreePolyIndex) {
+ synth->printDebug("Cannot return freed poly, currently active polys:\n");
+ for (Bit32u partNum = 0; partNum < 9; partNum++) {
+ const Poly *activePoly = synth->getPart(partNum)->getFirstActivePoly();
+ Bit32u polyCount = 0;
+ while (activePoly != NULL) {
+ activePoly->getNext();
+ polyCount++;
+ }
+ synth->printDebug("Part: %i, active poly count: %i\n", partNum, polyCount);
+ }
+ }
+ poly->setPart(NULL);
+ firstFreePolyIndex--;
+ freePolys[firstFreePolyIndex] = poly;
+}
+
}
diff --git a/audio/softsynth/mt32/PartialManager.h b/audio/softsynth/mt32/PartialManager.h
index a1c9266ea1..229b6e8121 100644
--- a/audio/softsynth/mt32/PartialManager.h
+++ b/audio/softsynth/mt32/PartialManager.h
@@ -24,17 +24,17 @@ class Synth;
class PartialManager {
private:
- Synth *synth; // Only used for sending debug output
+ Synth *synth;
Part **parts;
-
- Partial *partialTable[MT32EMU_MAX_PARTIALS];
+ Poly **freePolys;
+ Partial **partialTable;
Bit8u numReservedPartialsForPart[9];
+ Bit32u firstFreePolyIndex;
bool abortFirstReleasingPolyWhereReserveExceeded(int minPart);
bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart);
public:
-
PartialManager(Synth *synth, Part **parts);
~PartialManager();
Partial *allocPartial(int partNum);
@@ -43,10 +43,12 @@ public:
bool freePartials(unsigned int needed, int partNum);
unsigned int setReserve(Bit8u *rset);
void deactivateAll();
- bool produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength);
+ bool produceOutput(int i, Sample *leftBuf, Sample *rightBuf, Bit32u bufferLength);
bool shouldReverb(int i);
void clearAlreadyOutputed();
const Partial *getPartial(unsigned int partialNum) const;
+ Poly *assignPolyToPart(Part *part);
+ void polyFreed(Poly *poly);
};
}
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
index 46574f8967..1554881270 100644
--- a/audio/softsynth/mt32/Poly.cpp
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -19,8 +19,8 @@
namespace MT32Emu {
-Poly::Poly(Part *usePart) {
- part = usePart;
+Poly::Poly() {
+ part = NULL;
key = 255;
velocity = 255;
sustain = false;
@@ -32,10 +32,21 @@ Poly::Poly(Part *usePart) {
next = NULL;
}
+void Poly::setPart(Part *usePart) {
+ part = usePart;
+}
+
void Poly::reset(unsigned int newKey, unsigned int newVelocity, bool newSustain, Partial **newPartials) {
if (isActive()) {
- // FIXME: Throw out some big ugly debug output with a lot of exclamation marks - we should never get here
- terminate();
+ // This should never happen
+ part->getSynth()->printDebug("Resetting active poly. Active partial count: %i\n", activePartialCount);
+ for (int i = 0; i < 4; i++) {
+ if (partials[i] != NULL && partials[i]->isActive()) {
+ partials[i]->deactivate();
+ activePartialCount--;
+ }
+ }
+ state = POLY_Inactive;
}
key = newKey;
@@ -92,41 +103,24 @@ bool Poly::startDecay() {
}
bool Poly::startAbort() {
- if (state == POLY_Inactive) {
+ if (state == POLY_Inactive || part->getSynth()->isAbortingPoly()) {
return false;
}
for (int t = 0; t < 4; t++) {
Partial *partial = partials[t];
if (partial != NULL) {
partial->startAbort();
+ part->getSynth()->abortingPoly = this;
}
}
return true;
}
-void Poly::terminate() {
- if (state == POLY_Inactive) {
- return;
- }
- for (int t = 0; t < 4; t++) {
- Partial *partial = partials[t];
- if (partial != NULL) {
- partial->deactivate();
- }
- }
- if (state != POLY_Inactive) {
- // FIXME: Throw out lots of debug output - this should never happen
- // (Deactivating the partials above should've made them each call partialDeactivated(), ultimately changing the state to POLY_Inactive)
- state = POLY_Inactive;
- }
-}
-
void Poly::backupCacheToPartials(PatchCache cache[4]) {
for (int partialNum = 0; partialNum < 4; partialNum++) {
Partial *partial = partials[partialNum];
- if (partial != NULL && partial->patchCache == &cache[partialNum]) {
- partial->cachebackup = cache[partialNum];
- partial->patchCache = &partial->cachebackup;
+ if (partial != NULL) {
+ partial->backupCache(cache[partialNum]);
}
}
}
@@ -171,11 +165,14 @@ void Poly::partialDeactivated(Partial *partial) {
}
if (activePartialCount == 0) {
state = POLY_Inactive;
+ if (part->getSynth()->abortingPoly == this) {
+ part->getSynth()->abortingPoly = NULL;
+ }
}
part->partialDeactivated(this);
}
-Poly *Poly::getNext() {
+Poly *Poly::getNext() const {
return next;
}
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
index 068cf73d35..33abc35fdf 100644
--- a/audio/softsynth/mt32/Poly.h
+++ b/audio/softsynth/mt32/Poly.h
@@ -44,13 +44,13 @@ private:
Poly *next;
public:
- Poly(Part *part);
+ Poly();
+ void setPart(Part *usePart);
void reset(unsigned int key, unsigned int velocity, bool sustain, Partial **partials);
bool noteOff(bool pedalHeld);
bool stopPedalHold();
bool startDecay();
bool startAbort();
- void terminate();
void backupCacheToPartials(PatchCache cache[4]);
@@ -63,7 +63,7 @@ public:
void partialDeactivated(Partial *partial);
- Poly *getNext();
+ Poly *getNext() const;
void setNext(Poly *poly);
};
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
index 43d2d1f226..421e427fc0 100644
--- a/audio/softsynth/mt32/Structures.h
+++ b/audio/softsynth/mt32/Structures.h
@@ -38,6 +38,12 @@ typedef signed short int Bit16s;
typedef unsigned char Bit8u;
typedef signed char Bit8s;
+#if MT32EMU_USE_FLOAT_SAMPLES
+typedef float Sample;
+#else
+typedef Bit16s Sample;
+#endif
+
// The following structures represent the MT-32's memory
// Since sysex allows this memory to be written to in blocks of bytes,
// we keep this packed so that we can copy data into the various
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 1e1be06bc9..b76dc58b5f 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -26,15 +26,7 @@
#include "mt32emu.h"
#include "mmath.h"
#include "PartialManager.h"
-
-#if MT32EMU_USE_REVERBMODEL == 1
-#include "AReverbModel.h"
-#elif MT32EMU_USE_REVERBMODEL == 2
#include "BReverbModel.h"
-#else
-#include "FreeverbModel.h"
-#endif
-#include "DelayReverb.h"
namespace MT32Emu {
@@ -50,84 +42,22 @@ static const ControlROMMap ControlROMMaps[7] = {
// (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
};
-static inline Bit16s *streamOffset(Bit16s *stream, Bit32u pos) {
- return stream == NULL ? NULL : stream + pos;
-}
+static inline void muteStream(Sample *stream, Bit32u len) {
+ if (stream == NULL) return;
-static inline void clearIfNonNull(Bit16s *stream, Bit32u len) {
- if (stream != NULL) {
- memset(stream, 0, len * sizeof(Bit16s));
- }
-}
-
-static inline void mix(float *target, const float *stream, Bit32u len) {
- while (len--) {
- *target += *stream;
- stream++;
- target++;
- }
-}
-
-static inline void clearFloats(float *leftBuf, float *rightBuf, Bit32u len) {
+#if MT32EMU_USE_FLOAT_SAMPLES
// FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win)
while (len--) {
- *leftBuf++ = 0.0f;
- *rightBuf++ = 0.0f;
- }
-}
-
-static inline Bit16s clipBit16s(Bit32s a) {
- // Clamp values above 32767 to 32767, and values below -32768 to -32768
- if ((a + 32768) & ~65535) {
- return (a >> 31) ^ 32767;
- }
- return a;
-}
-
-static void floatToBit16s_nice(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 16384.0f;
- while (len--) {
- // Since we're not shooting for accuracy here, don't worry about the rounding mode.
- *target = clipBit16s((Bit32s)(*source * gain));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_pure(Bit16s *target, const float *source, Bit32u len, float /*outputGain*/) {
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * 8192.0f));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_reverb(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_generation1(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
- source++;
- target++;
+ *stream++ = 0.0f;
}
+#else
+ memset(stream, 0, len * sizeof(Sample));
+#endif
}
-static void floatToBit16s_generation2(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
- source++;
- target++;
+static inline void advanceStreamPosition(Sample *&stream, Bit32u posDelta) {
+ if (stream != NULL) {
+ stream += posDelta;
}
}
@@ -155,28 +85,19 @@ Synth::Synth(ReportHandler *useReportHandler) {
isDefaultReportHandler = false;
}
-#if MT32EMU_USE_REVERBMODEL == 1
- reverbModels[REVERB_MODE_ROOM] = new AReverbModel(REVERB_MODE_ROOM);
- reverbModels[REVERB_MODE_HALL] = new AReverbModel(REVERB_MODE_HALL);
- reverbModels[REVERB_MODE_PLATE] = new AReverbModel(REVERB_MODE_PLATE);
- reverbModels[REVERB_MODE_TAP_DELAY] = new DelayReverb();
-#elif MT32EMU_USE_REVERBMODEL == 2
reverbModels[REVERB_MODE_ROOM] = new BReverbModel(REVERB_MODE_ROOM);
reverbModels[REVERB_MODE_HALL] = new BReverbModel(REVERB_MODE_HALL);
reverbModels[REVERB_MODE_PLATE] = new BReverbModel(REVERB_MODE_PLATE);
reverbModels[REVERB_MODE_TAP_DELAY] = new BReverbModel(REVERB_MODE_TAP_DELAY);
-#else
- reverbModels[REVERB_MODE_ROOM] = new FreeverbModel(0.76f, 0.687770909f, 0.63f, 0, 0.5f);
- reverbModels[REVERB_MODE_HALL] = new FreeverbModel(2.0f, 0.712025098f, 0.86f, 1, 0.5f);
- reverbModels[REVERB_MODE_PLATE] = new FreeverbModel(0.4f, 0.939522749f, 0.38f, 2, 0.05f);
- reverbModels[REVERB_MODE_TAP_DELAY] = new DelayReverb();
-#endif
reverbModel = NULL;
setDACInputMode(DACInputMode_NICE);
+ setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
setOutputGain(1.0f);
- setReverbOutputGain(0.68f);
+ setReverbOutputGain(1.0f);
partialManager = NULL;
+ midiQueue = NULL;
+ lastReceivedMIDIEventTimestamp = 0;
memset(parts, 0, sizeof(parts));
renderedSampleCount = 0;
}
@@ -197,8 +118,8 @@ void ReportHandler::showLCDMessage(const char *data) {
}
void ReportHandler::printDebug(const char *fmt, va_list list) {
- vprintf(fmt, list);
- printf("\n");
+ vprintf(fmt, list);
+ printf("\n");
}
void Synth::polyStateChanged(int partNum) {
@@ -236,35 +157,37 @@ bool Synth::isReverbOverridden() const {
}
void Synth::setDACInputMode(DACInputMode mode) {
- switch(mode) {
- case DACInputMode_GENERATION1:
- la32FloatToBit16sFunc = floatToBit16s_generation1;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- case DACInputMode_GENERATION2:
- la32FloatToBit16sFunc = floatToBit16s_generation2;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- case DACInputMode_PURE:
- la32FloatToBit16sFunc = floatToBit16s_pure;
- reverbFloatToBit16sFunc = floatToBit16s_pure;
- break;
- case DACInputMode_NICE:
- default:
- la32FloatToBit16sFunc = floatToBit16s_nice;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- }
+ dacInputMode = mode;
+}
+
+DACInputMode Synth::getDACInputMode() const {
+ return dacInputMode;
+}
+
+void Synth::setMIDIDelayMode(MIDIDelayMode mode) {
+ midiDelayMode = mode;
+}
+
+MIDIDelayMode Synth::getMIDIDelayMode() const {
+ return midiDelayMode;
}
void Synth::setOutputGain(float newOutputGain) {
outputGain = newOutputGain;
}
+float Synth::getOutputGain() const {
+ return outputGain;
+}
+
void Synth::setReverbOutputGain(float newReverbOutputGain) {
reverbOutputGain = newReverbOutputGain;
}
+float Synth::getReverbOutputGain() const {
+ return reverbOutputGain;
+}
+
bool Synth::loadControlROM(const ROMImage &controlROMImage) {
if (&controlROMImage == NULL) return false;
Common::File *file = controlROMImage.getFile();
@@ -343,9 +266,9 @@ bool Synth::loadPCMROM(const ROMImage &pcmROMImage) {
bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) {
ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress];
for (int i = 0; i < count; i++) {
- size_t rAddr = tps[i].pos * 0x800;
- size_t rLenExp = (tps[i].len & 0x70) >> 4;
- size_t rLen = 0x800 << rLenExp;
+ Bit32u rAddr = tps[i].pos * 0x800;
+ Bit32u rLenExp = (tps[i].len & 0x70) >> 4;
+ Bit32u rLen = 0x800 << rLenExp;
if (rAddr + rLen > pcmROMSize) {
printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen);
return false;
@@ -407,17 +330,18 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTi
return true;
}
-bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage) {
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount) {
if (isOpen) {
return false;
}
- prerenderReadIx = prerenderWriteIx = 0;
+ partialCount = usePartialCount;
+ abortingPoly = NULL;
#if MT32EMU_MONITOR_INIT
printDebug("Initialising Constant Tables");
#endif
#if !MT32EMU_REDUCE_REVERB_MEMORY
- for (int i = 0; i < 4; i++) {
- reverbModels[i]->open(useProp.sampleRate);
+ for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
+ reverbModels[i]->open();
}
#endif
@@ -554,6 +478,8 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage) {
// For resetting mt32 mid-execution
mt32default = mt32ram;
+ midiQueue = new MidiEventQueue();
+
isOpen = true;
isEnabled = false;
@@ -568,6 +494,9 @@ void Synth::close() {
return;
}
+ delete midiQueue;
+ midiQueue = NULL;
+
delete partialManager;
partialManager = NULL;
@@ -588,12 +517,78 @@ void Synth::close() {
isOpen = false;
}
-void Synth::playMsg(Bit32u msg) {
+void Synth::flushMIDIQueue() {
+ if (midiQueue != NULL) {
+ for (;;) {
+ const MidiEvent *midiEvent = midiQueue->peekMidiEvent();
+ if (midiEvent == NULL) break;
+ if (midiEvent->sysexData == NULL) {
+ playMsgNow(midiEvent->shortMessageData);
+ } else {
+ playSysexNow(midiEvent->sysexData, midiEvent->sysexLength);
+ }
+ midiQueue->dropMidiEvent();
+ }
+ lastReceivedMIDIEventTimestamp = renderedSampleCount;
+ }
+}
+
+void Synth::setMIDIEventQueueSize(Bit32u useSize) {
+ if (midiQueue != NULL) {
+ flushMIDIQueue();
+ delete midiQueue;
+ midiQueue = new MidiEventQueue(useSize);
+ }
+}
+
+Bit32u Synth::getShortMessageLength(Bit32u msg) {
+ if ((msg & 0xF0) == 0xF0) return 1;
+ // NOTE: This calculation isn't quite correct
+ // as it doesn't consider the running status byte
+ return ((msg & 0xE0) == 0xC0) ? 2 : 3;
+}
+
+Bit32u Synth::addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp) {
+ Bit32u transferTime = Bit32u((double)len * MIDI_DATA_TRANSFER_RATE);
+ // Dealing with wrapping
+ if (Bit32s(timestamp - lastReceivedMIDIEventTimestamp) < 0) {
+ timestamp = lastReceivedMIDIEventTimestamp;
+ }
+ timestamp += transferTime;
+ lastReceivedMIDIEventTimestamp = timestamp;
+ return timestamp;
+}
+
+bool Synth::playMsg(Bit32u msg) {
+ return playMsg(msg, renderedSampleCount);
+}
+
+bool Synth::playMsg(Bit32u msg, Bit32u timestamp) {
+ if (midiQueue == NULL) return false;
+ if (midiDelayMode != MIDIDelayMode_IMMEDIATE) {
+ timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp);
+ }
+ return midiQueue->pushShortMessage(msg, timestamp);
+}
+
+bool Synth::playSysex(const Bit8u *sysex, Bit32u len) {
+ return playSysex(sysex, len, renderedSampleCount);
+}
+
+bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) {
+ if (midiQueue == NULL) return false;
+ if (midiDelayMode == MIDIDelayMode_DELAY_ALL) {
+ timestamp = addMIDIInterfaceDelay(len, timestamp);
+ }
+ return midiQueue->pushSysex(sysex, len, timestamp);
+}
+
+void Synth::playMsgNow(Bit32u msg) {
// FIXME: Implement active sensing
unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
unsigned char chan = (unsigned char)(msg & 0x00000F);
- unsigned char note = (unsigned char)((msg & 0x00FF00) >> 8);
- unsigned char velocity = (unsigned char)((msg & 0xFF0000) >> 16);
+ unsigned char note = (unsigned char)((msg & 0x007F00) >> 8);
+ unsigned char velocity = (unsigned char)((msg & 0x7F0000) >> 16);
isEnabled = true;
//printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
@@ -606,11 +601,6 @@ void Synth::playMsg(Bit32u msg) {
return;
}
playMsgOnPart(part, code, note, velocity);
-
- // This ensures minimum 1-sample delay between sequential MIDI events
- // Without this, a sequence of NoteOn and immediately succeeding NoteOff messages is always silent
- // Technically, it's also impossible to send events through the MIDI interface faster than about each millisecond
- prerender();
}
void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity) {
@@ -692,7 +682,7 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char
#if MT32EMU_MONITOR_MIDI > 0
printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
#endif
- break;
+ return;
}
break;
@@ -709,13 +699,12 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char
#if MT32EMU_MONITOR_MIDI > 0
printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
#endif
- break;
+ return;
}
-
- //midiOutShortMsg(m_out, msg);
+ reportHandler->onMIDIMessagePlayed();
}
-void Synth::playSysex(const Bit8u *sysex, Bit32u len) {
+void Synth::playSysexNow(const Bit8u *sysex, Bit32u len) {
if (len < 2) {
printDebug("playSysex: Message is too short for sysex (%d bytes)", len);
}
@@ -810,6 +799,7 @@ void Synth::readSysex(unsigned char /*device*/, const Bit8u * /*sysex*/, Bit32u
}
void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
+ reportHandler->onMIDIMessagePlayed();
Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]);
addr = MT32EMU_MEMADDR(addr);
sysex += 3;
@@ -1232,7 +1222,7 @@ void Synth::refreshSystemReverbParameters() {
reportHandler->onNewReverbTime(mt32ram.system.reverbTime);
reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel);
- ReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
+ BReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
#if MT32EMU_REDUCE_REVERB_MEMORY
if (reverbModel != newReverbModel) {
if (reverbModel != NULL) {
@@ -1308,179 +1298,226 @@ void Synth::reset() {
isEnabled = false;
}
-void Synth::render(Bit16s *stream, Bit32u len) {
- if (!isEnabled) {
- memset(stream, 0, len * sizeof(Bit16s) * 2);
- return;
+MidiEvent::~MidiEvent() {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
- while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
- for (Bit32u i = 0; i < thisLen; i++) {
- stream[0] = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
- stream[1] = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
- stream += 2;
- }
- len -= thisLen;
+}
+
+void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
+ shortMessageData = useShortMessageData;
+ timestamp = useTimestamp;
+ sysexData = NULL;
+ sysexLength = 0;
}
-bool Synth::prerender() {
- int newPrerenderWriteIx = (prerenderWriteIx + 1) % MAX_PRERENDER_SAMPLES;
- if (newPrerenderWriteIx == prerenderReadIx) {
- // The prerender buffer is full
- return false;
+void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
- doRenderStreams(
- prerenderNonReverbLeft + prerenderWriteIx,
- prerenderNonReverbRight + prerenderWriteIx,
- prerenderReverbDryLeft + prerenderWriteIx,
- prerenderReverbDryRight + prerenderWriteIx,
- prerenderReverbWetLeft + prerenderWriteIx,
- prerenderReverbWetRight + prerenderWriteIx,
- 1);
- prerenderWriteIx = newPrerenderWriteIx;
+ shortMessageData = 0;
+ timestamp = useTimestamp;
+ sysexLength = useSysexLength;
+ Bit8u *dstSysexData = new Bit8u[sysexLength];
+ sysexData = dstSysexData;
+ memcpy(dstSysexData, useSysexData, sysexLength);
+}
+
+MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBufferSize(useRingBufferSize) {
+ ringBuffer = new MidiEvent[ringBufferSize];
+ memset(ringBuffer, 0, ringBufferSize * sizeof(MidiEvent));
+ reset();
+}
+
+MidiEventQueue::~MidiEventQueue() {
+ delete[] ringBuffer;
+}
+
+void MidiEventQueue::reset() {
+ startPosition = 0;
+ endPosition = 0;
+}
+
+bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) {
+ unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ // Is ring buffer full?
+ if (startPosition == newEndPosition) return false;
+ ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp);
+ endPosition = newEndPosition;
return true;
}
-static inline void maybeCopy(Bit16s *out, Bit32u outPos, Bit16s *in, Bit32u inPos, Bit32u len) {
- if (out == NULL) {
- return;
- }
- memcpy(out + outPos, in + inPos, len * sizeof(Bit16s));
+bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) {
+ unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ // Is ring buffer full?
+ if (startPosition == newEndPosition) return false;
+ ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp);
+ endPosition = newEndPosition;
+ return true;
}
-void Synth::copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len) {
- maybeCopy(nonReverbLeft, pos, prerenderNonReverbLeft, prerenderReadIx, len);
- maybeCopy(nonReverbRight, pos, prerenderNonReverbRight, prerenderReadIx, len);
- maybeCopy(reverbDryLeft, pos, prerenderReverbDryLeft, prerenderReadIx, len);
- maybeCopy(reverbDryRight, pos, prerenderReverbDryRight, prerenderReadIx, len);
- maybeCopy(reverbWetLeft, pos, prerenderReverbWetLeft, prerenderReadIx, len);
- maybeCopy(reverbWetRight, pos, prerenderReverbWetRight, prerenderReadIx, len);
+const MidiEvent *MidiEventQueue::peekMidiEvent() {
+ return (startPosition == endPosition) ? NULL : &ringBuffer[startPosition];
}
-void Synth::checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len) {
- if (prerenderReadIx > prerenderWriteIx) {
- // There's data in the prerender buffer, and the write index has wrapped.
- Bit32u prerenderCopyLen = MAX_PRERENDER_SAMPLES - prerenderReadIx;
- if (prerenderCopyLen > len) {
- prerenderCopyLen = len;
- }
- copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
- len -= prerenderCopyLen;
- pos += prerenderCopyLen;
- prerenderReadIx = (prerenderReadIx + prerenderCopyLen) % MAX_PRERENDER_SAMPLES;
- }
- if (prerenderReadIx < prerenderWriteIx) {
- // There's data in the prerender buffer, and the write index is ahead of the read index.
- Bit32u prerenderCopyLen = prerenderWriteIx - prerenderReadIx;
- if (prerenderCopyLen > len) {
- prerenderCopyLen = len;
- }
- copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
- len -= prerenderCopyLen;
- pos += prerenderCopyLen;
- prerenderReadIx += prerenderCopyLen;
- }
- if (prerenderReadIx == prerenderWriteIx) {
- // If the ring buffer's empty, reset it to start at 0 to minimise wrapping,
- // which requires two writes instead of one.
- prerenderReadIx = prerenderWriteIx = 0;
- }
-}
-
-void Synth::renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
- if (!isEnabled) {
- clearIfNonNull(nonReverbLeft, len);
- clearIfNonNull(nonReverbRight, len);
- clearIfNonNull(reverbDryLeft, len);
- clearIfNonNull(reverbDryRight, len);
- clearIfNonNull(reverbWetLeft, len);
- clearIfNonNull(reverbWetRight, len);
- return;
+void MidiEventQueue::dropMidiEvent() {
+ // Is ring buffer empty?
+ if (startPosition != endPosition) {
+ startPosition = (startPosition + 1) % ringBufferSize;
}
- Bit32u pos = 0;
+}
- // First, check for data in the prerender buffer and spit that out before generating anything new.
- // Note that the prerender buffer is rarely used - see comments elsewhere for details.
- checkPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, len);
+void Synth::render(Sample *stream, Bit32u len) {
+ Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
while (len > 0) {
Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- doRenderStreams(
- streamOffset(nonReverbLeft, pos),
- streamOffset(nonReverbRight, pos),
- streamOffset(reverbDryLeft, pos),
- streamOffset(reverbDryRight, pos),
- streamOffset(reverbWetLeft, pos),
- streamOffset(reverbWetRight, pos),
- thisLen);
+ renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
+ for (Bit32u i = 0; i < thisLen; i++) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *(stream++) = tmpNonReverbLeft[i] + tmpReverbDryLeft[i] + tmpReverbWetLeft[i];
+ *(stream++) = tmpNonReverbRight[i] + tmpReverbDryRight[i] + tmpReverbWetRight[i];
+#else
+ *(stream++) = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
+ *(stream++) = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
+#endif
+ }
len -= thisLen;
- pos += thisLen;
}
}
-// FIXME: Using more temporary buffers than we need to
-void Synth::doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
- clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
- if (!reverbEnabled) {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
- }
- }
- if (nonReverbLeft != NULL) {
- la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
- }
- if (nonReverbRight != NULL) {
- la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
- }
- clearIfNonNull(reverbDryLeft, len);
- clearIfNonNull(reverbDryRight, len);
- clearIfNonNull(reverbWetLeft, len);
- clearIfNonNull(reverbWetRight, len);
- } else {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
+void Synth::renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
+ while (len > 0) {
+ // We need to ensure zero-duration notes will play so add minimum 1-sample delay.
+ Bit32u thisLen = 1;
+ if (!isAbortingPoly()) {
+ const MidiEvent *nextEvent = midiQueue->peekMidiEvent();
+ Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - renderedSampleCount) : MAX_SAMPLES_PER_RUN;
+ if (samplesToNextEvent > 0) {
+ thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ if (thisLen > (Bit32u)samplesToNextEvent) {
+ thisLen = samplesToNextEvent;
+ }
+ } else {
+ if (nextEvent->sysexData == NULL) {
+ playMsgNow(nextEvent->shortMessageData);
+ // If a poly is aborting we don't drop the event from the queue.
+ // Instead, we'll return to it again when the abortion is done.
+ if (!isAbortingPoly()) {
+ midiQueue->dropMidiEvent();
+ }
+ } else {
+ playSysexNow(nextEvent->sysexData, nextEvent->sysexLength);
+ midiQueue->dropMidiEvent();
}
}
}
- if (nonReverbLeft != NULL) {
- la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
+ doRenderStreams(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, thisLen);
+ advanceStreamPosition(nonReverbLeft, thisLen);
+ advanceStreamPosition(nonReverbRight, thisLen);
+ advanceStreamPosition(reverbDryLeft, thisLen);
+ advanceStreamPosition(reverbDryRight, thisLen);
+ advanceStreamPosition(reverbWetLeft, thisLen);
+ advanceStreamPosition(reverbWetRight, thisLen);
+ len -= thisLen;
+ }
+}
+
+void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb) {
+ if (target == NULL) return;
+
+ if (dacInputMode == DACInputMode_PURE) {
+ memcpy(target, source, len * sizeof(Sample));
+ return;
+ }
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+ float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : 2.0f * outputGain;
+ while (len--) {
+ *(target++) = *(source++) * gain;
+ }
+#else
+ float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : outputGain;
+ if (!reverb) {
+ switch (dacInputMode) {
+ case DACInputMode_NICE:
+ // Since we're not shooting for accuracy here, don't worry about the rounding mode.
+ gain *= 2.0f;
+ break;
+ case DACInputMode_GENERATION1:
+ while (len--) {
+ *target = clipBit16s(Bit32s(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
+ source++;
+ target++;
+ }
+ return;
+ case DACInputMode_GENERATION2:
+ while (len--) {
+ *target = clipBit16s(Bit32s(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
+ source++;
+ target++;
+ }
+ return;
+ default:
+ break;
}
- if (nonReverbRight != NULL) {
- la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
+ }
+ while (len--) {
+ *(target++) = clipBit16s(Bit32s(*(source++) * gain));
+ }
+#endif
+}
+
+void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
+ if (isEnabled) {
+ Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
+ muteStream(tmpBufMixLeft, len);
+ muteStream(tmpBufMixRight, len);
+ for (unsigned int i = 0; i < getPartialCount(); i++) {
+ if (!reverbEnabled || !partialManager->shouldReverb(i)) {
+ partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
+ }
}
+ convertSamplesToOutput(nonReverbLeft, tmpBufMixLeft, len, false);
+ convertSamplesToOutput(nonReverbRight, tmpBufMixRight, len, false);
+ } else {
+ muteStream(nonReverbLeft, len);
+ muteStream(nonReverbRight, len);
+ }
- clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (isEnabled && reverbEnabled) {
+ Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
+ muteStream(tmpBufMixLeft, len);
+ muteStream(tmpBufMixRight, len);
+ for (unsigned int i = 0; i < getPartialCount(); i++) {
if (partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
- }
+ partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
}
}
- if (reverbDryLeft != NULL) {
- la32FloatToBit16sFunc(reverbDryLeft, &tmpBufMixLeft[0], len, outputGain);
- }
- if (reverbDryRight != NULL) {
- la32FloatToBit16sFunc(reverbDryRight, &tmpBufMixRight[0], len, outputGain);
- }
+ convertSamplesToOutput(reverbDryLeft, tmpBufMixLeft, len, false);
+ convertSamplesToOutput(reverbDryRight, tmpBufMixRight, len, false);
- // FIXME: Note that on the real devices, reverb input and output are signed linear 16-bit (well, kinda, there's some fudging) PCM, not float.
- reverbModel->process(&tmpBufMixLeft[0], &tmpBufMixRight[0], &tmpBufReverbOutLeft[0], &tmpBufReverbOutRight[0], len);
- if (reverbWetLeft != NULL) {
- reverbFloatToBit16sFunc(reverbWetLeft, &tmpBufReverbOutLeft[0], len, reverbOutputGain);
- }
- if (reverbWetRight != NULL) {
- reverbFloatToBit16sFunc(reverbWetRight, &tmpBufReverbOutRight[0], len, reverbOutputGain);
- }
+ Sample tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
+ reverbModel->process(tmpBufMixLeft, tmpBufMixRight, tmpBufReverbOutLeft, tmpBufReverbOutRight, len);
+ convertSamplesToOutput(reverbWetLeft, tmpBufReverbOutLeft, len, true);
+ convertSamplesToOutput(reverbWetRight, tmpBufReverbOutRight, len, true);
+ } else {
+ muteStream(reverbDryLeft, len);
+ muteStream(reverbDryRight, len);
+ muteStream(reverbWetLeft, len);
+ muteStream(reverbWetRight, len);
}
+
partialManager->clearAlreadyOutputed();
renderedSampleCount += len;
}
@@ -1489,19 +1526,14 @@ void Synth::printPartialUsage(unsigned long sampleOffset) {
unsigned int partialUsage[9];
partialManager->getPerPartPartialUsage(partialUsage);
if (sampleOffset > 0) {
- printDebug("[+%lu] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ printDebug("[+%lu] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount());
} else {
- printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount());
}
}
bool Synth::hasActivePartials() const {
- if (prerenderReadIx != prerenderWriteIx) {
- // Data in the prerender buffer means that the current isActive() states are "in the future".
- // It also means that partials are definitely active at this render point.
- return true;
- }
- for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) {
if (partialManager->getPartial(partialNum)->isActive()) {
return true;
}
@@ -1509,6 +1541,10 @@ bool Synth::hasActivePartials() const {
return false;
}
+bool Synth::isAbortingPoly() const {
+ return abortingPoly != NULL;
+}
+
bool Synth::isActive() const {
if (hasActivePartials()) {
return true;
@@ -1523,6 +1559,10 @@ const Partial *Synth::getPartial(unsigned int partialNum) const {
return partialManager->getPartial(partialNum);
}
+unsigned int Synth::getPartialCount() const {
+ return partialCount;
+}
+
const Part *Synth::getPart(unsigned int partNum) const {
if (partNum > 8) {
return NULL;
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index b85e7ae507..783d6e2747 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -27,6 +27,7 @@ class Partial;
class PartialManager;
class Part;
class ROMImage;
+class BReverbModel;
/**
* Methods for emulating the connection between the LA32 and the DAC, which involves
@@ -44,6 +45,7 @@ enum DACInputMode {
// * Much less likely to overdrive than any other mode.
// * Half the volume of any of the other modes, meaning its volume relative to the reverb
// output when mixed together directly will sound wrong.
+ // * Output gain is ignored for both LA32 and reverb output.
// * Perfect for developers while debugging :)
DACInputMode_PURE,
@@ -58,7 +60,17 @@ enum DACInputMode {
DACInputMode_GENERATION2
};
-typedef void (*FloatToBit16sFunc)(Bit16s *target, const float *source, Bit32u len, float outputGain);
+enum MIDIDelayMode {
+ // Process incoming MIDI events immediately.
+ MIDIDelayMode_IMMEDIATE,
+
+ // Delay incoming short MIDI messages as if they where transferred via a MIDI cable to a real hardware unit and immediate sysex processing.
+ // This ensures more accurate timing of simultaneous NoteOn messages.
+ MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY,
+
+ // Delay all incoming MIDI events as if they where transferred via a MIDI cable to a real hardware unit.
+ MIDIDelayMode_DELAY_ALL
+};
const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
@@ -217,18 +229,6 @@ public:
ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
};
-class ReverbModel {
-public:
- virtual ~ReverbModel() {}
- // After construction or a close(), open() will be called at least once before any other call (with the exception of close()).
- virtual void open() = 0;
- // May be called multiple times without an open() in between.
- virtual void close() = 0;
- virtual void setParameters(Bit8u time, Bit8u level) = 0;
- virtual void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) = 0;
- virtual bool isActive() const = 0;
-};
-
class ReportHandler {
friend class Synth;
@@ -244,22 +244,63 @@ protected:
virtual void onErrorControlROM() {}
virtual void onErrorPCMROM() {}
virtual void showLCDMessage(const char *message);
+ virtual void onMIDIMessagePlayed() {}
virtual void onDeviceReset() {}
virtual void onDeviceReconfig() {}
virtual void onNewReverbMode(Bit8u /* mode */) {}
virtual void onNewReverbTime(Bit8u /* time */) {}
virtual void onNewReverbLevel(Bit8u /* level */) {}
- virtual void onPartStateChanged(int /* partNum */, bool /* hasActiveNonReleasingPolys */) {}
virtual void onPolyStateChanged(int /* partNum */) {}
- virtual void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {}
virtual void onProgramChanged(int /* partNum */, int /* bankNum */, const char * /* patchName */) {}
};
+/**
+ * Used to safely store timestamped MIDI events in a local queue.
+ */
+struct MidiEvent {
+ Bit32u shortMessageData;
+ const Bit8u *sysexData;
+ Bit32u sysexLength;
+ Bit32u timestamp;
+
+ ~MidiEvent();
+ void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+};
+
+/**
+ * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
+ * It is intended to:
+ * - get rid of prerenderer while retaining graceful partial abortion
+ * - add fair emulation of the MIDI interface delays
+ * - extend the synth interface with the default implementation of a typical rendering loop.
+ * THREAD SAFETY:
+ * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
+ * and one performs only writing. More complicated usage requires external synchronisation.
+ */
+class MidiEventQueue {
+private:
+ MidiEvent *ringBuffer;
+ Bit32u ringBufferSize;
+ volatile Bit32u startPosition;
+ volatile Bit32u endPosition;
+
+public:
+ MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE);
+ ~MidiEventQueue();
+ void reset();
+ bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+ const MidiEvent *peekMidiEvent();
+ void dropMidiEvent();
+};
+
class Synth {
friend class Part;
friend class RhythmPart;
friend class Poly;
friend class Partial;
+friend class PartialManager;
friend class Tables;
friend class MemoryRegion;
friend class TVA;
@@ -286,20 +327,22 @@ private:
Bit16s *pcmROMData;
size_t pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM
- Bit8s chantable[32];
-
- Bit32u renderedSampleCount;
+ unsigned int partialCount;
+ Bit8s chantable[32]; // FIXME: Need explanation why 32 is set, obviously it should be 16
+ MidiEventQueue *midiQueue;
+ volatile Bit32u lastReceivedMIDIEventTimestamp;
+ volatile Bit32u renderedSampleCount;
MemParams mt32ram, mt32default;
- ReverbModel *reverbModels[4];
- ReverbModel *reverbModel;
+ BReverbModel *reverbModels[4];
+ BReverbModel *reverbModel;
bool reverbEnabled;
bool reverbOverridden;
- FloatToBit16sFunc la32FloatToBit16sFunc;
- FloatToBit16sFunc reverbFloatToBit16sFunc;
+ MIDIDelayMode midiDelayMode;
+ DACInputMode dacInputMode;
float outputGain;
float reverbOutputGain;
@@ -311,41 +354,18 @@ private:
PartialManager *partialManager;
Part *parts[9];
- // FIXME: We can reorganise things so that we don't need all these separate tmpBuf, tmp and prerender buffers.
- // This should be rationalised when things have stabilised a bit (if prerender buffers don't die in the mean time).
-
- float tmpBufPartialLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufPartialRight[MAX_SAMPLES_PER_RUN];
- float tmpBufMixLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufMixRight[MAX_SAMPLES_PER_RUN];
- float tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
-
- Bit16s tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
-
- // These ring buffers are only used to simulate delays present on the real device.
- // In particular, when a partial needs to be aborted to free it up for use by a new Poly,
+ // When a partial needs to be aborted to free it up for use by a new Poly,
// the controller will busy-loop waiting for the sound to finish.
- Bit16s prerenderNonReverbLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderNonReverbRight[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbDryLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbDryRight[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbWetLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbWetRight[MAX_PRERENDER_SAMPLES];
- int prerenderReadIx;
- int prerenderWriteIx;
-
- bool prerender();
- void copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len);
- void checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len);
- void doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
-
- void playAddressedSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
+ // We emulate this by delaying new MIDI events processing until abortion finishes.
+ Poly *abortingPoly;
+
+ Bit32u getShortMessageLength(Bit32u msg);
+ Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp);
+
+ void convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb);
+ bool isAbortingPoly() const;
+ void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
+
void readSysex(unsigned char channel, const Bit8u *sysex, Bit32u len) const;
void initMemoryRegions();
void deleteMemoryRegions();
@@ -375,6 +395,14 @@ private:
void printDebug(const char *fmt, ...);
public:
+ static inline Bit16s clipBit16s(Bit32s sample) {
+ // Clamp values above 32767 to 32767, and values below -32768 to -32768
+ if ((sample + 32768) & ~65535) {
+ return (sample >> 31) ^ 32767;
+ }
+ return (Bit16s)sample;
+ }
+
static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
// Optionally sets callbacks for reporting various errors, information and debug messages
@@ -384,18 +412,44 @@ public:
// Used to initialise the MT-32. Must be called before any other function.
// Returns true if initialization was sucessful, otherwise returns false.
// controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth.
- bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage);
+ // usePartialCount sets the maximum number of partials playing simultaneously for this session.
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS);
// Closes the MT-32 and deallocates any memory used by the synthesizer
void close(void);
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback
- void playMsg(Bit32u msg);
+ // All the enqueued events are processed by the synth immediately.
+ void flushMIDIQueue();
+
+ // Sets size of the internal MIDI event queue.
+ // The queue is flushed before reallocation.
+ void setMIDIEventQueueSize(Bit32u);
+
+ // Enqueues a MIDI event for subsequent playback.
+ // The minimum delay involves the delay introduced while the event is transferred via MIDI interface
+ // and emulation of the MCU busy-loop while it frees partials for use by a new Poly.
+ // Calls from multiple threads must be synchronised, although,
+ // no synchronisation is required with the rendering thread.
+
+ // The MIDI event will be processed not before the specified timestamp.
+ // The timestamp is measured as the global rendered sample count since the synth was created.
+ bool playMsg(Bit32u msg, Bit32u timestamp);
+ bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp);
+ // The MIDI event will be processed ASAP.
+ bool playMsg(Bit32u msg);
+ bool playSysex(const Bit8u *sysex, Bit32u len);
+
+ // WARNING:
+ // The methods below don't ensure minimum 1-sample delay between sequential MIDI events,
+ // and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent.
+
+ // Sends a 4-byte MIDI message to the MT-32 for immediate playback.
+ void playMsgNow(Bit32u msg);
void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
// Sends a string of Sysex commands to the MT-32 for immediate interpretation
// The length is in bytes
- void playSysex(const Bit8u *sysex, Bit32u len);
+ void playSysexNow(const Bit8u *sysex, Bit32u len);
void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len);
void playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len);
void writeSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
@@ -405,20 +459,31 @@ public:
void setReverbOverridden(bool reverbOverridden);
bool isReverbOverridden() const;
void setDACInputMode(DACInputMode mode);
+ DACInputMode getDACInputMode() const;
+ void setMIDIDelayMode(MIDIDelayMode mode);
+ MIDIDelayMode getMIDIDelayMode() const;
// Sets output gain factor. Applied to all output samples and unrelated with the synth's Master volume.
+ // Ignored in DACInputMode_PURE
void setOutputGain(float);
+ float getOutputGain() const;
// Sets output gain factor for the reverb wet output. setOutputGain() doesn't change reverb output gain.
+ // Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely
+ // corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
+ // there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
+ // of that for LA32 analogue output. This factor is applied to the reverb output gain.
+ // Ignored in DACInputMode_PURE
void setReverbOutputGain(float);
+ float getReverbOutputGain() const;
// Renders samples to the specified output stream.
// The length is in frames, not bytes (in 16-bit stereo,
// one frame is 4 bytes).
- void render(Bit16s *stream, Bit32u len);
+ void render(Sample *stream, Bit32u len);
// Renders samples to the specified output streams (any or all of which may be NULL).
- void renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
+ void renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
// Returns true when there is at least one active partial, otherwise false.
bool hasActivePartials() const;
@@ -428,6 +493,9 @@ public:
const Partial *getPartial(unsigned int partialNum) const;
+ // Returns the maximum number of partials playing simultaneously.
+ unsigned int getPartialCount() const;
+
void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
// partNum should be 0..7 for Part 1..8, or 8 for Rhythm
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
index c3e64c18d0..8f68245753 100644
--- a/audio/softsynth/mt32/TVP.cpp
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -181,7 +181,7 @@ void TVP::updatePitch() {
pitch = (Bit16u)newPitch;
// FIXME: We're doing this here because that's what the CM-32L does - we should probably move this somewhere more appropriate in future.
- partial->tva->recalcSustain();
+ partial->getTVA()->recalcSustain();
}
void TVP::targetPitchOffsetReached() {
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
index 8b4580df0e..bfb80e121e 100644
--- a/audio/softsynth/mt32/Tables.h
+++ b/audio/softsynth/mt32/Tables.h
@@ -25,6 +25,11 @@ namespace MT32Emu {
// The output from the synth is supposed to be resampled to convert the sample rate.
const unsigned int SAMPLE_RATE = 32000;
+// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
+const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
+
+const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
+
const int MIDDLEC = 60;
class Synth;
diff --git a/audio/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp
deleted file mode 100644
index 181b878596..0000000000
--- a/audio/softsynth/mt32/freeverb.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-// Allpass filter implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-#include "freeverb.h"
-
-allpass::allpass()
-{
- bufidx = 0;
-}
-
-void allpass::setbuffer(float *buf, int size)
-{
- buffer = buf;
- bufsize = size;
-}
-
-void allpass::mute()
-{
- for (int i=0; i<bufsize; i++)
- buffer[i]=0;
-}
-
-void allpass::setfeedback(float val)
-{
- feedback = val;
-}
-
-float allpass::getfeedback()
-{
- return feedback;
-}
-
-void allpass::deletebuffer()
-{
- delete[] buffer;
- buffer = 0;
-}
-// Comb filter implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-comb::comb()
-{
- filterstore = 0;
- bufidx = 0;
-}
-
-void comb::setbuffer(float *buf, int size)
-{
- buffer = buf;
- bufsize = size;
-}
-
-void comb::mute()
-{
- for (int i=0; i<bufsize; i++)
- buffer[i]=0;
-}
-
-void comb::setdamp(float val)
-{
- damp1 = val;
- damp2 = 1-val;
-}
-
-float comb::getdamp()
-{
- return damp1;
-}
-
-void comb::setfeedback(float val)
-{
- feedback = val;
-}
-
-float comb::getfeedback()
-{
- return feedback;
-}
-
-void comb::deletebuffer()
-{
- delete[] buffer;
- buffer = 0;
-}
-// Reverb model implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// Modifications by Jerome Fisher, 2009, 2011
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-revmodel::revmodel(float scaletuning)
-{
- int i;
- int bufsize;
-
- // Allocate buffers for the components
- for (i = 0; i < numcombs; i++) {
- bufsize = int(scaletuning * combtuning[i]);
- combL[i].setbuffer(new float[bufsize], bufsize);
- bufsize += int(scaletuning * stereospread);
- combR[i].setbuffer(new float[bufsize], bufsize);
- }
- for (i = 0; i < numallpasses; i++) {
- bufsize = int(scaletuning * allpasstuning[i]);
- allpassL[i].setbuffer(new float[bufsize], bufsize);
- allpassL[i].setfeedback(0.5f);
- bufsize += int(scaletuning * stereospread);
- allpassR[i].setbuffer(new float[bufsize], bufsize);
- allpassR[i].setfeedback(0.5f);
- }
-
- // Set default values
- dry = initialdry;
- wet = initialwet*scalewet;
- damp = initialdamp*scaledamp;
- roomsize = (initialroom*scaleroom) + offsetroom;
- width = initialwidth;
- mode = initialmode;
- update();
-
- // Buffer will be full of rubbish - so we MUST mute them
- mute();
-}
-
-revmodel::~revmodel()
-{
- int i;
-
- for (i = 0; i < numcombs; i++) {
- combL[i].deletebuffer();
- combR[i].deletebuffer();
- }
- for (i = 0; i < numallpasses; i++) {
- allpassL[i].deletebuffer();
- allpassR[i].deletebuffer();
- }
-}
-
-void revmodel::mute()
-{
- int i;
-
- if (getmode() >= freezemode)
- return;
-
- for (i=0;i<numcombs;i++)
- {
- combL[i].mute();
- combR[i].mute();
- }
- for (i=0;i<numallpasses;i++)
- {
- allpassL[i].mute();
- allpassR[i].mute();
- }
-
- // Init LPF history
- filtprev1 = 0;
- filtprev2 = 0;
-}
-
-void revmodel::process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples)
-{
- float outL,outR,input;
-
- while (numsamples-- > 0)
- {
- int i;
-
- outL = outR = 0;
- input = (*inputL + *inputR) * gain;
-
- // Implementation of 2-stage IIR single-pole low-pass filter
- // found at the entrance of reverb processing on real devices
- filtprev1 += (input - filtprev1) * filtval;
- filtprev2 += (filtprev1 - filtprev2) * filtval;
- input = filtprev2;
-
- int s = -1;
- // Accumulate comb filters in parallel
- for (i=0; i<numcombs; i++)
- {
- outL += s * combL[i].process(input);
- outR += s * combR[i].process(input);
- s = -s;
- }
-
- // Feed through allpasses in series
- for (i=0; i<numallpasses; i++)
- {
- outL = allpassL[i].process(outL);
- outR = allpassR[i].process(outR);
- }
-
- // Calculate output REPLACING anything already there
- *outputL = outL*wet1 + outR*wet2;
- *outputR = outR*wet1 + outL*wet2;
-
- inputL++;
- inputR++;
- outputL++;
- outputR++;
- }
-}
-
-void revmodel::update()
-{
-// Recalculate internal values after parameter change
-
- int i;
-
- wet1 = wet*(width/2 + 0.5f);
- wet2 = wet*((1-width)/2);
-
- if (mode >= freezemode)
- {
- roomsize1 = 1;
- damp1 = 0;
- gain = muted;
- }
- else
- {
- roomsize1 = roomsize;
- damp1 = damp;
- gain = fixedgain;
- }
-
- for (i=0; i<numcombs; i++)
- {
- combL[i].setfeedback(roomsize1);
- combR[i].setfeedback(roomsize1);
- }
-
- for (i=0; i<numcombs; i++)
- {
- combL[i].setdamp(damp1);
- combR[i].setdamp(damp1);
- }
-}
-
-// The following get/set functions are not inlined, because
-// speed is never an issue when calling them, and also
-// because as you develop the reverb model, you may
-// wish to take dynamic action when they are called.
-
-void revmodel::setroomsize(float value)
-{
- roomsize = (value*scaleroom) + offsetroom;
- update();
-}
-
-float revmodel::getroomsize()
-{
- return (roomsize-offsetroom)/scaleroom;
-}
-
-void revmodel::setdamp(float value)
-{
- damp = value*scaledamp;
- update();
-}
-
-float revmodel::getdamp()
-{
- return damp/scaledamp;
-}
-
-void revmodel::setwet(float value)
-{
- wet = value*scalewet;
- update();
-}
-
-float revmodel::getwet()
-{
- return wet/scalewet;
-}
-
-void revmodel::setdry(float value)
-{
- dry = value*scaledry;
-}
-
-float revmodel::getdry()
-{
- return dry/scaledry;
-}
-
-void revmodel::setwidth(float value)
-{
- width = value;
- update();
-}
-
-float revmodel::getwidth()
-{
- return width;
-}
-
-void revmodel::setmode(float value)
-{
- mode = value;
- update();
-}
-
-float revmodel::getmode()
-{
- if (mode >= freezemode)
- return 1;
- else
- return 0;
-}
-
-void revmodel::setfiltval(float value)
-{
- filtval = value;
-}
diff --git a/audio/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h
deleted file mode 100644
index ae4d48169e..0000000000
--- a/audio/softsynth/mt32/freeverb.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#ifndef _freeverb_
-#define _freeverb_
-
-// Reverb model tuning values
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-const int numcombs = 8;
-const int numallpasses = 4;
-const float muted = 0;
-const float fixedgain = 0.015f;
-const float scalewet = 3;
-const float scaledry = 2;
-const float scaledamp = 0.4f;
-const float scaleroom = 0.28f;
-const float offsetroom = 0.7f;
-const float initialroom = 0.5f;
-const float initialdamp = 0.5f;
-const float initialwet = 1/scalewet;
-const float initialdry = 0;
-const float initialwidth = 1;
-const float initialmode = 0;
-const float freezemode = 0.5f;
-const int stereospread = 23;
-
-const int combtuning[] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};
-const int allpasstuning[] = {556, 441, 341, 225};
-
-// Macro for killing denormalled numbers
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// Based on IS_DENORMAL macro by Jon Watte
-// This code is public domain
-
-static inline float undenormalise(float x) {
- union {
- float f;
- unsigned int i;
- } u;
- u.f = x;
- if ((u.i & 0x7f800000) == 0) {
- return 0.0f;
- }
- return x;
-}
-
-// Allpass filter declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class allpass
-{
-public:
- allpass();
- void setbuffer(float *buf, int size);
- void deletebuffer();
- inline float process(float inp);
- void mute();
- void setfeedback(float val);
- float getfeedback();
-// private:
- float feedback;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float allpass::process(float input)
-{
- float output;
- float bufout;
-
- bufout = undenormalise(buffer[bufidx]);
-
- output = -input + bufout;
- buffer[bufidx] = input + (bufout*feedback);
-
- if (++bufidx>=bufsize) bufidx = 0;
-
- return output;
-}
-
-// Comb filter class declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class comb
-{
-public:
- comb();
- void setbuffer(float *buf, int size);
- void deletebuffer();
- inline float process(float inp);
- void mute();
- void setdamp(float val);
- float getdamp();
- void setfeedback(float val);
- float getfeedback();
-private:
- float feedback;
- float filterstore;
- float damp1;
- float damp2;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float comb::process(float input)
-{
- float output;
-
- output = undenormalise(buffer[bufidx]);
-
- filterstore = undenormalise((output*damp2) + (filterstore*damp1));
-
- buffer[bufidx] = input + (filterstore*feedback);
-
- if (++bufidx>=bufsize) bufidx = 0;
-
- return output;
-}
-
-// Reverb model declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// Modifications by Jerome Fisher, 2009
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class revmodel
-{
-public:
- revmodel(float scaletuning);
- ~revmodel();
- void mute();
- void process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples);
- void setroomsize(float value);
- float getroomsize();
- void setdamp(float value);
- float getdamp();
- void setwet(float value);
- float getwet();
- void setdry(float value);
- float getdry();
- void setwidth(float value);
- float getwidth();
- void setmode(float value);
- float getmode();
- void setfiltval(float value);
-private:
- void update();
-private:
- float gain;
- float roomsize,roomsize1;
- float damp,damp1;
- float wet,wet1,wet2;
- float dry;
- float width;
- float mode;
-
- // LPF stuff
- float filtval;
- float filtprev1;
- float filtprev2;
-
- // Comb filters
- comb combL[numcombs];
- comb combR[numcombs];
-
- // Allpass filters
- allpass allpassL[numallpasses];
- allpass allpassR[numallpasses];
-};
-
-#endif//_freeverb_
diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk
index e7afdfd2b4..1c8aa125ab 100644
--- a/audio/softsynth/mt32/module.mk
+++ b/audio/softsynth/mt32/module.mk
@@ -1,24 +1,19 @@
MODULE := audio/softsynth/mt32
MODULE_OBJS := \
- AReverbModel.o \
BReverbModel.o \
- DelayReverb.o \
- FreeverbModel.o \
LA32Ramp.o \
LA32WaveGenerator.o \
- LegacyWaveGenerator.o \
Part.o \
Partial.o \
PartialManager.o \
Poly.o \
ROMInfo.o \
Synth.o \
+ Tables.o \
TVA.o \
TVF.o \
- TVP.o \
- Tables.o \
- freeverb.o
+ TVP.o
# Include common rules
include $(srcdir)/rules.mk
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index 971a0886d5..ab963886ac 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -60,27 +60,24 @@
#define MT32EMU_MONITOR_TVF 0
// Configuration
-// The maximum number of partials playing simultaneously
-#define MT32EMU_MAX_PARTIALS 32
-// The maximum number of notes playing simultaneously per part.
-// No point making it more than MT32EMU_MAX_PARTIALS, since each note needs at least one partial.
-#define MT32EMU_MAX_POLY 32
// If non-zero, deletes reverb buffers that are not in use to save memory.
// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
#define MT32EMU_REDUCE_REVERB_MEMORY 1
-// 0: Use legacy Freeverb
-// 1: Use Accurate Reverb model aka AReverb
-// 2: Use Bit-perfect Boss Reverb model aka BReverb (for developers, not much practical use)
-#define MT32EMU_USE_REVERBMODEL 1
+// 0: Maximum speed at the cost of a bit lower emulation accuracy.
+// 1: Maximum achievable emulation accuracy.
+#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
-// 0: Use refined wave generator based on logarithmic fixed-point computations and LUTs
-// 1: Use legacy accurate wave generator based on float computations
-#define MT32EMU_ACCURATE_WG 0
+// 0: Use 16-bit signed samples and refined wave generator based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed.
+// 1: Use float samples in the wave generator and renderer. Maximum output quality and minimum noise.
+#define MT32EMU_USE_FLOAT_SAMPLES 0
namespace MT32Emu
{
+// The default value for the maximum number of partials playing simultaneously.
+const unsigned int DEFAULT_MAX_PARTIALS = 32;
+
// The higher this number, the more memory will be used, but the more samples can be processed in one run -
// various parts of sample generation can be processed more efficiently in a single run.
// A run's maximum length is that given to Synth::render(), so giving a value here higher than render() is ever
@@ -90,11 +87,14 @@ namespace MT32Emu
// This value must be >= 1.
const unsigned int MAX_SAMPLES_PER_RUN = 4096;
-// This determines the amount of memory available for simulating delays.
-// If set too low, partials aborted to allow other partials to play will not end gracefully, but will terminate
-// abruptly and potentially cause a pop/crackle in the audio output.
-// This value must be >= 1.
-const unsigned int MAX_PRERENDER_SAMPLES = 1024;
+// The default size of the internal MIDI event queue.
+// It holds the incoming MIDI events before the rendering engine actually processes them.
+// The main goal is to fairly emulate the real hardware behaviour which obviously
+// uses an internal MIDI event queue to gather incoming data as well as the delays
+// introduced by transferring data via the MIDI interface.
+// This also facilitates building of an external rendering loop
+// as the queue stores timestamped MIDI events.
+const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = 1024;
}
#include "Structures.h"
@@ -103,7 +103,6 @@ const unsigned int MAX_PRERENDER_SAMPLES = 1024;
#include "Poly.h"
#include "LA32Ramp.h"
#include "LA32WaveGenerator.h"
-#include "LegacyWaveGenerator.h"
#include "TVA.h"
#include "TVP.h"
#include "TVF.h"
diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp
index 3e0005dedd..3e95c3e26a 100644
--- a/backends/base-backend.cpp
+++ b/backends/base-backend.cpp
@@ -57,7 +57,7 @@ void BaseBackend::initBackend() {
void BaseBackend::fillScreen(uint32 col) {
Graphics::Surface *screen = lockScreen();
- if (screen && screen->pixels)
- memset(screen->pixels, col, screen->h * screen->pitch);
+ if (screen && screen->getPixels())
+ memset(screen->getPixels(), col, screen->h * screen->pitch);
unlockScreen();
}
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 48e2663d44..84be83d524 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -357,7 +357,7 @@ void OpenGLGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x,
// Copy buffer data to game screen internal buffer
const byte *src = (const byte *)buf;
- byte *dst = (byte *)_screenData.pixels + y * _screenData.pitch + x * _screenData.format.bytesPerPixel;
+ byte *dst = (byte *)_screenData.getBasePtr(x, y);
for (int i = 0; i < h; i++) {
memcpy(dst, src, w * _screenData.format.bytesPerPixel);
src += pitch;
@@ -385,15 +385,15 @@ void OpenGLGraphicsManager::fillScreen(uint32 col) {
#ifdef USE_RGB_COLOR
if (_screenFormat.bytesPerPixel == 1) {
- memset(_screenData.pixels, col, _screenData.h * _screenData.pitch);
+ memset(_screenData.getPixels(), col, _screenData.h * _screenData.pitch);
} else if (_screenFormat.bytesPerPixel == 2) {
- uint16 *pixels = (uint16 *)_screenData.pixels;
+ 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.pixels;
+ uint8 *pixels = (uint8 *)_screenData.getPixels();
byte r = (col >> 16) & 0xFF;
byte g = (col >> 8) & 0xFF;
byte b = col & 0xFF;
@@ -404,13 +404,13 @@ void OpenGLGraphicsManager::fillScreen(uint32 col) {
pixels += 3;
}
} else if (_screenFormat.bytesPerPixel == 4) {
- uint32 *pixels = (uint32 *)_screenData.pixels;
+ uint32 *pixels = (uint32 *)_screenData.getPixels();
for (int i = 0; i < _screenData.w * _screenData.h; i++) {
pixels[i] = col;
}
}
#else
- memset(_screenData.pixels, col, _screenData.h * _screenData.pitch);
+ memset(_screenData.getPixels(), col, _screenData.h * _screenData.pitch);
#endif
_screenNeedsRedraw = true;
}
@@ -463,12 +463,12 @@ Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
void OpenGLGraphicsManager::clearOverlay() {
// Set all pixels to 0
- memset(_overlayData.pixels, 0, _overlayData.h * _overlayData.pitch);
+ memset(_overlayData.getPixels(), 0, _overlayData.h * _overlayData.pitch);
_overlayNeedsRedraw = true;
}
void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
- const byte *src = (byte *)_overlayData.pixels;
+ const byte *src = (byte *)_overlayData.getPixels();
byte *dst = (byte *)buf;
for (int i = 0; i < _overlayData.h; i++) {
// Copy overlay data to buffer
@@ -509,7 +509,7 @@ void OpenGLGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x,
return;
// Copy buffer data to internal overlay surface
- byte *dst = (byte *)_overlayData.pixels + y * _overlayData.pitch;
+ 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;
@@ -609,7 +609,7 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
_cursorData.create(w, h, _cursorFormat);
// Save cursor data
- memcpy(_cursorData.pixels, buf, h * _cursorData.pitch);
+ memcpy(_cursorData.getPixels(), buf, h * _cursorData.pitch);
// Set cursor info
_cursorState.w = w;
@@ -688,7 +688,7 @@ void OpenGLGraphicsManager::refreshGameScreen() {
byte *surface = new byte[w * h * 3];
// Convert the paletted buffer to RGB888
- const byte *src = (byte *)_screenData.pixels + y * _screenData.pitch;
+ const byte *src = (byte *)_screenData.getBasePtr(0, y);
src += x * _screenData.format.bytesPerPixel;
byte *dst = surface;
for (int i = 0; i < h; i++) {
@@ -708,8 +708,7 @@ void OpenGLGraphicsManager::refreshGameScreen() {
delete[] surface;
} else {
// Update the texture
- _gameTexture->updateBuffer((byte *)_screenData.pixels + y * _screenData.pitch +
- x * _screenData.format.bytesPerPixel, _screenData.pitch, x, y, w, h);
+ _gameTexture->updateBuffer((byte *)_screenData.getBasePtr(x, y), _screenData.pitch, x, y, w, h);
}
_screenNeedsRedraw = false;
@@ -730,7 +729,7 @@ void OpenGLGraphicsManager::refreshOverlay() {
byte *surface = new byte[w * h * 3];
// Convert the paletted buffer to RGB888
- const byte *src = (byte *)_overlayData.pixels + y * _overlayData.pitch;
+ const byte *src = (byte *)_overlayData.getBasePtr(0, y);
src += x * _overlayData.format.bytesPerPixel;
byte *dst = surface;
for (int i = 0; i < h; i++) {
@@ -750,8 +749,7 @@ void OpenGLGraphicsManager::refreshOverlay() {
delete[] surface;
} else {
// Update the texture
- _overlayTexture->updateBuffer((byte *)_overlayData.pixels + y * _overlayData.pitch +
- x * _overlayData.format.bytesPerPixel, _overlayData.pitch, x, y, w, h);
+ _overlayTexture->updateBuffer((byte *)_overlayData.getBasePtr(x, y), _overlayData.pitch, x, y, w, h);
}
_overlayNeedsRedraw = false;
@@ -780,7 +778,7 @@ void OpenGLGraphicsManager::refreshCursor() {
palette = _cursorPalette;
// Convert the paletted cursor to RGBA8888
- const byte *src = (byte *)_cursorData.pixels;
+ const byte *src = (byte *)_cursorData.getPixels();
for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
// Check for keycolor
if (src[i] != _cursorKeyColor) {
@@ -796,7 +794,7 @@ void OpenGLGraphicsManager::refreshCursor() {
// Convert the RGB cursor to RGBA8888
if (_cursorFormat.bytesPerPixel == 2) {
- const uint16 *src = (uint16 *)_cursorData.pixels;
+ const uint16 *src = (uint16 *)_cursorData.getPixels();
for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
// Check for keycolor
if (src[i] != _cursorKeyColor) {
@@ -808,7 +806,7 @@ void OpenGLGraphicsManager::refreshCursor() {
dst += 4;
}
} else if (_cursorFormat.bytesPerPixel == 4) {
- const uint32 *src = (uint32 *)_cursorData.pixels;
+ const uint32 *src = (uint32 *)_cursorData.getPixels();
for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
// Check for keycolor
if (src[i] != _cursorKeyColor) {
@@ -1356,7 +1354,7 @@ void OpenGLGraphicsManager::updateOSD() {
_osdSurface.create(_osdTexture->getWidth(), _osdTexture->getHeight(), _overlayFormat);
else
// Clear everything
- memset(_osdSurface.pixels, 0, _osdSurface.h * _osdSurface.pitch);
+ memset(_osdSurface.getPixels(), 0, _osdSurface.h * _osdSurface.pitch);
// Determine a rect which would contain the message string (clipped to the
// screen dimensions).
@@ -1390,7 +1388,7 @@ void OpenGLGraphicsManager::updateOSD() {
}
// Update the texture
- _osdTexture->updateBuffer(_osdSurface.pixels, _osdSurface.pitch, 0, 0,
+ _osdTexture->updateBuffer(_osdSurface.getPixels(), _osdSurface.pitch, 0, 0,
_osdSurface.w, _osdSurface.h);
}
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 1ebd019488..871c6c49b2 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -773,7 +773,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
if (_displayDisabled) {
_hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
- } else
+ } else
#endif
{
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
@@ -1308,15 +1308,13 @@ Graphics::Surface *SurfaceSdlGraphicsManager::lockScreen() {
if (SDL_LockSurface(_screen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
- _framebuffer.pixels = _screen->pixels;
- _framebuffer.w = _screen->w;
- _framebuffer.h = _screen->h;
- _framebuffer.pitch = _screen->pitch;
+ _framebuffer.init(_screen->w, _screen->h, _screen->pitch, _screen->pixels,
#ifdef USE_RGB_COLOR
- _framebuffer.format = _screenFormat;
+ _screenFormat
#else
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
+ Graphics::PixelFormat::createFormatCLUT8()
#endif
+ );
return &_framebuffer;
}
@@ -1340,8 +1338,8 @@ void SurfaceSdlGraphicsManager::unlockScreen() {
void SurfaceSdlGraphicsManager::fillScreen(uint32 col) {
Graphics::Surface *screen = lockScreen();
- if (screen && screen->pixels)
- memset(screen->pixels, col, screen->h * screen->pitch);
+ if (screen && screen->getPixels())
+ memset(screen->getPixels(), col, screen->h * screen->pitch);
unlockScreen();
}
@@ -2062,15 +2060,12 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
error("displayMessageOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
Graphics::Surface dst;
- dst.pixels = _osdSurface->pixels;
- dst.w = _osdSurface->w;
- dst.h = _osdSurface->h;
- dst.pitch = _osdSurface->pitch;
- dst.format = Graphics::PixelFormat(_osdSurface->format->BytesPerPixel,
- 8 - _osdSurface->format->Rloss, 8 - _osdSurface->format->Gloss,
- 8 - _osdSurface->format->Bloss, 8 - _osdSurface->format->Aloss,
- _osdSurface->format->Rshift, _osdSurface->format->Gshift,
- _osdSurface->format->Bshift, _osdSurface->format->Ashift);
+ dst.init(_osdSurface->w, _osdSurface->h, _osdSurface->pitch, _osdSurface->pixels,
+ Graphics::PixelFormat(_osdSurface->format->BytesPerPixel,
+ 8 - _osdSurface->format->Rloss, 8 - _osdSurface->format->Gloss,
+ 8 - _osdSurface->format->Bloss, 8 - _osdSurface->format->Aloss,
+ _osdSurface->format->Rshift, _osdSurface->format->Gshift,
+ _osdSurface->format->Bshift, _osdSurface->format->Ashift));
// The font we are going to use:
const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp
index 5cefe668cd..d2c60bec9d 100644
--- a/backends/midi/timidity.cpp
+++ b/backends/midi/timidity.cpp
@@ -148,7 +148,7 @@ MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() {
int MidiDriver_TIMIDITY::open() {
char *res;
- char timidity_host[MAXHOSTNAMELEN];
+ char timidity_host[NI_MAXHOST];
int timidity_port, data_port, i;
/* count ourselves open */
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index d84df75439..6afe06aeca 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -142,9 +142,15 @@ void ModularBackend::fillScreen(uint32 col) {
}
void ModularBackend::updateScreen() {
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.preDrawOverlayGui();
+#endif
+
_graphicsManager->updateScreen();
+
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.postDrawOverlayGui();
+#endif
}
void ModularBackend::setShakePos(int shakeOffset) {
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index cd0fd88484..882dcff9a4 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -552,7 +552,7 @@ Graphics::Surface *OSystem_Android::lockScreen() {
GLTHREADCHECK;
Graphics::Surface *surface = _game_texture->surface();
- assert(surface->pixels);
+ assert(surface->getPixels());
return surface;
}
@@ -645,7 +645,7 @@ void OSystem_Android::grabOverlay(void *buf, int pitch) {
assert(surface->format.bytesPerPixel == sizeof(uint16));
byte *dst = (byte *)buf;
- const byte *src = (const byte *)surface->pixels;
+ const byte *src = (const byte *)surface->getPixels();
uint h = surface->h;
do {
diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index b174e93191..cc41c0d8a6 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -233,7 +233,7 @@ void GLESTexture::allocBuffer(GLuint w, GLuint h) {
_pixels = new byte[w * h * _surface.format.bytesPerPixel];
assert(_pixels);
- _surface.pixels = _pixels;
+ _surface.setPixels(_pixels);
fillBuffer(0);
@@ -256,7 +256,7 @@ void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
}
void GLESTexture::fillBuffer(uint32 color) {
- assert(_surface.pixels);
+ assert(_surface.getPixels());
if (_pixelFormat.bytesPerPixel == 1 ||
((color & 0xff) == ((color >> 8) & 0xff)))
@@ -377,7 +377,7 @@ void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
assert(_pixels);
// fixup surface, for the outside this is a CLUT8 surface
- _surface.pixels = _pixels;
+ _surface.setPixels(_pixels);
fillBuffer(0);
@@ -386,8 +386,8 @@ void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) {
}
void GLESFakePaletteTexture::fillBuffer(uint32 color) {
- assert(_surface.pixels);
- memset(_surface.pixels, color & 0xff, _surface.pitch * _surface.h);
+ assert(_surface.getPixels());
+ memset(_surface.getPixels(), color & 0xff, _surface.pitch * _surface.h);
setDirty();
}
diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp
index cc5798fc10..54ee6000ed 100644
--- a/backends/platform/dc/display.cpp
+++ b/backends/platform/dc/display.cpp
@@ -711,11 +711,7 @@ Graphics::Surface *OSystem_Dreamcast::lockScreen()
if (!screen)
return 0;
- _framebuffer.pixels = screen;
- _framebuffer.w = _screen_w;
- _framebuffer.h = _screen_h;
- _framebuffer.pitch = SCREEN_W*2;
- _framebuffer.format = screenFormats[_screenFormat];
+ _framebuffer.init(_screen_w, _screen_h, SCREEN_W*2, screen, screenFormats[_screenFormat]);
return &_framebuffer;
}
diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp
index 339e5df62d..4026c7dde6 100644
--- a/backends/platform/dc/selector.cpp
+++ b/backends/platform/dc/selector.cpp
@@ -219,7 +219,7 @@ static int findGames(Game *games, int max, bool use_ini)
if (use_ini) {
ConfMan.loadDefaultConfigFile();
- Common::ConfigManager::DomainMap &game_domains = ConfMan.getGameDomains();
+ const Common::ConfigManager::DomainMap &game_domains = ConfMan.getGameDomains();
for(Common::ConfigManager::DomainMap::const_iterator i =
game_domains.begin(); curr_game < max && i != game_domains.end(); i++) {
Common::String path = (*i)._value["path"];
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 2f6358d8ee..f109983fbc 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -296,7 +296,7 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
// to save a few pennies/euro cents on the hardware.
if (_frameBufferExists) {
- bg = (u16 *)_framebuffer.pixels;
+ bg = (u16 *)_framebuffer.getPixels();
stride = _framebuffer.pitch;
} else {
bg = (u16 *)DS::get8BitBackBuffer();
@@ -455,7 +455,7 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
dmaCopyHalfWords(3, src, dest1, w);
- if ((!_frameBufferExists) || (buf == _framebuffer.pixels)) {
+ if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
dmaCopyHalfWords(2, src, dest2, w);
}
@@ -476,7 +476,7 @@ void OSystem_DS::updateScreen() {
_frameBufferExists = false;
// Copy temp framebuffer back to screen
- copyRectToScreen((byte *)_framebuffer.pixels, _framebuffer.pitch, 0, 0, _framebuffer.w, _framebuffer.h);
+ copyRectToScreen((byte *)_framebuffer.getPixels(), _framebuffer.pitch, 0, 0, _framebuffer.w, _framebuffer.h);
}
DS::displayMode16BitFlipBuffer();
@@ -755,11 +755,8 @@ Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
if (DS::isCpuScalerEnabled()) {
- _framebuffer.pixels = DS::getScalerBuffer();
- _framebuffer.w = DS::getGameWidth();
- _framebuffer.h = DS::getGameHeight();
- _framebuffer.pitch = DS::getGameWidth();
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
+ _framebuffer.init(DS::getGameWidth(), DS::getGameHeight(), DS::getGameWidth(),
+ DS::getScalerBuffer(), Graphics::PixelFormat::createFormatCLUT8());
} else {
@@ -780,11 +777,7 @@ Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
dmaCopyHalfWords(3, srcLine, destLine, width);
}
- _framebuffer.pixels = dest;
- _framebuffer.w = width;
- _framebuffer.h = height;
- _framebuffer.pitch = width;
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
+ _framebuffer.init(width, height, width, dest, Graphics::PixelFormat::createFormatCLUT8());
}
@@ -798,8 +791,8 @@ Graphics::Surface *OSystem_DS::createTempFrameBuffer() {
for (int y = 0; y < DS::getGameHeight(); y++) {
DC_FlushRange(image + (y * imageStrideInWords), DS::getGameWidth());
for (int x = 0; x < DS::getGameWidth() >> 1; x++) {
- *(((u16 *) (_framebuffer.pixels)) + y * (DS::getGameWidth() >> 1) + x) = image[(y * imageStrideInWords) + x];
-// *(((u16 *) (surf->pixels)) + y * (DS::getGameWidth() >> 1) + x) = image[y * imageStrideInWords + x];
+ *(((u16 *) (_framebuffer.getPixels())) + y * (DS::getGameWidth() >> 1) + x) = image[(y * imageStrideInWords) + x];
+// *(((u16 *) (surf->getPixels())) + y * (DS::getGameWidth() >> 1) + x) = image[y * imageStrideInWords + x];
}
}*/
diff --git a/backends/platform/iphone/iphone_video.mm b/backends/platform/iphone/iphone_video.mm
index 0bfae30fc7..f2c1527658 100644
--- a/backends/platform/iphone/iphone_video.mm
+++ b/backends/platform/iphone/iphone_video.mm
@@ -365,7 +365,7 @@ const char *iPhone_getDocumentsDir() {
_mouseTexCoords[5] = _mouseTexCoords[7] = _videoContext.mouseHeight / (GLfloat)_videoContext.mouseTexture.h;
glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.mouseTexture.w, _videoContext.mouseTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.mouseTexture.pixels); printOpenGLError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.mouseTexture.w, _videoContext.mouseTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.mouseTexture.getPixels()); printOpenGLError();
}
- (void)updateMainSurface {
@@ -377,7 +377,7 @@ const char *iPhone_getDocumentsDir() {
// Unfortunately we have to update the whole texture every frame, since glTexSubImage2D is actually slower in all cases
// due to the iPhone internals having to convert the whole texture back from its internal format when used.
// In the future we could use several tiled textures instead.
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _videoContext.screenTexture.pixels); printOpenGLError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _videoContext.screenTexture.getPixels()); printOpenGLError();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
}
@@ -386,7 +386,7 @@ const char *iPhone_getDocumentsDir() {
glTexCoordPointer(2, GL_FLOAT, 0, _overlayTexCoords); printOpenGLError();
glBindTexture(GL_TEXTURE_2D, _overlayTexture); printOpenGLError();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.overlayTexture.w, _videoContext.overlayTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.overlayTexture.pixels); printOpenGLError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.overlayTexture.w, _videoContext.overlayTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.overlayTexture.getPixels()); printOpenGLError();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
}
diff --git a/backends/platform/iphone/osys_main.cpp b/backends/platform/iphone/osys_main.cpp
index 460d3fd2ac..a814495b80 100644
--- a/backends/platform/iphone/osys_main.cpp
+++ b/backends/platform/iphone/osys_main.cpp
@@ -77,8 +77,8 @@ OSystem_IPHONE::~OSystem_IPHONE() {
delete _mixer;
// Prevent accidental freeing of the screen texture here. This needs to be
// checked since we might use the screen texture as framebuffer in the case
- // of hi-color games for example.
- if (_framebuffer.pixels == _videoContext->screenTexture.pixels)
+ // of hi-color games for example. Otherwise this can lead to a double free.
+ if (_framebuffer.getPixels() != _videoContext->screenTexture.getPixels())
_framebuffer.free();
_mouseBuffer.free();
}
diff --git a/backends/platform/iphone/osys_video.mm b/backends/platform/iphone/osys_video.mm
index a11bf32c54..ce7f94f5bd 100644
--- a/backends/platform/iphone/osys_video.mm
+++ b/backends/platform/iphone/osys_video.mm
@@ -76,8 +76,8 @@ void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelForm
// In case we use the screen texture as frame buffer we reset the pixels
// pointer here to avoid freeing the screen texture.
- if (_framebuffer.pixels == _videoContext->screenTexture.pixels)
- _framebuffer.pixels = 0;
+ if (_framebuffer.getPixels() == _videoContext->screenTexture.getPixels())
+ _framebuffer.setPixels(0);
// Create the screen texture right here. We need to do this here, since
// when a game requests hi-color mode, we actually set the framebuffer
@@ -310,7 +310,7 @@ void OSystem_IPHONE::hideOverlay() {
void OSystem_IPHONE::clearOverlay() {
//printf("clearOverlay()\n");
- bzero(_videoContext->overlayTexture.getBasePtr(0, 0), _videoContext->overlayTexture.h * _videoContext->overlayTexture.pitch);
+ bzero(_videoContext->overlayTexture.getPixels(), _videoContext->overlayTexture.h * _videoContext->overlayTexture.pitch);
dirtyFullOverlayScreen();
}
@@ -319,7 +319,7 @@ void OSystem_IPHONE::grabOverlay(void *buf, int pitch) {
int h = _videoContext->overlayHeight;
byte *dst = (byte *)buf;
- const byte *src = (const byte *)_videoContext->overlayTexture.getBasePtr(0, 0);
+ const byte *src = (const byte *)_videoContext->overlayTexture.getPixels();
do {
memcpy(dst, src, _videoContext->overlayWidth * sizeof(uint16));
src += _videoContext->overlayTexture.pitch;
@@ -417,7 +417,7 @@ void OSystem_IPHONE::setMouseCursor(const void *buf, uint w, uint h, int hotspot
#endif
assert(pixelFormat.bytesPerPixel == 1 || pixelFormat.bytesPerPixel == 2);
- if (_mouseBuffer.w != w || _mouseBuffer.h != h || _mouseBuffer.format != pixelFormat || !_mouseBuffer.pixels)
+ if (_mouseBuffer.w != w || _mouseBuffer.h != h || _mouseBuffer.format != pixelFormat || !_mouseBuffer.getPixels())
_mouseBuffer.create(w, h, pixelFormat);
_videoContext->mouseWidth = w;
@@ -428,7 +428,7 @@ void OSystem_IPHONE::setMouseCursor(const void *buf, uint w, uint h, int hotspot
_mouseKeyColor = keycolor;
- memcpy(_mouseBuffer.getBasePtr(0, 0), buf, h * _mouseBuffer.pitch);
+ memcpy(_mouseBuffer.getPixels(), buf, h * _mouseBuffer.pitch);
_mouseDirty = true;
_mouseNeedTextureUpdate = true;
@@ -464,7 +464,7 @@ void OSystem_IPHONE::updateMouseTexture() {
else
palette = _gamePaletteRGBA5551;
- uint16 *mouseBuf = (uint16 *)mouseTexture.getBasePtr(0, 0);
+ uint16 *mouseBuf = (uint16 *)mouseTexture.getPixels();
for (uint x = 0; x < _videoContext->mouseWidth; ++x) {
for (uint y = 0; y < _videoContext->mouseHeight; ++y) {
const byte color = *(const byte *)_mouseBuffer.getBasePtr(x, y);
@@ -475,12 +475,12 @@ void OSystem_IPHONE::updateMouseTexture() {
}
}
} else {
- if (crossBlit((byte *)mouseTexture.getBasePtr(0, 0), (const byte *)_mouseBuffer.getBasePtr(0, 0), mouseTexture.pitch,
+ if (crossBlit((byte *)mouseTexture.getPixels(), (const byte *)_mouseBuffer.getPixels(), mouseTexture.pitch,
_mouseBuffer.pitch, _mouseBuffer.w, _mouseBuffer.h, mouseTexture.format, _mouseBuffer.format)) {
if (!_mouseBuffer.format.aBits()) {
// Apply color keying since the original cursor had no alpha channel.
- const uint16 *src = (const uint16 *)_mouseBuffer.getBasePtr(0, 0);
- uint8 *dstRaw = (uint8 *)mouseTexture.getBasePtr(0, 0);
+ const uint16 *src = (const uint16 *)_mouseBuffer.getPixels();
+ uint8 *dstRaw = (uint8 *)mouseTexture.getPixels();
for (uint y = 0; y < _mouseBuffer.h; ++y, dstRaw += mouseTexture.pitch) {
uint16 *dst = (uint16 *)dstRaw;
@@ -495,7 +495,7 @@ void OSystem_IPHONE::updateMouseTexture() {
} else {
// TODO: Log this!
// Make the cursor all transparent... we really need a better fallback ;-).
- memset(mouseTexture.getBasePtr(0, 0), 0, mouseTexture.h * mouseTexture.pitch);
+ memset(mouseTexture.getPixels(), 0, mouseTexture.h * mouseTexture.pitch);
}
}
diff --git a/backends/platform/n64/osys_n64_base.cpp b/backends/platform/n64/osys_n64_base.cpp
index afd93f5e09..36e5085764 100644
--- a/backends/platform/n64/osys_n64_base.cpp
+++ b/backends/platform/n64/osys_n64_base.cpp
@@ -605,11 +605,7 @@ void OSystem_N64::updateScreen() {
}
Graphics::Surface *OSystem_N64::lockScreen() {
- _framebuffer.pixels = _offscreen_pal;
- _framebuffer.w = _gameWidth;
- _framebuffer.h = _gameHeight;
- _framebuffer.pitch = _screenWidth;
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
+ _framebuffer.init(_gameWidth, _gameHeight, _screenWidth, _offscreen_pal, Graphics::PixelFormat::createFormatCLUT8());
return &_framebuffer;
}
diff --git a/backends/platform/ps2/Gs2dScreen.cpp b/backends/platform/ps2/Gs2dScreen.cpp
index e818305c29..58667c0230 100644
--- a/backends/platform/ps2/Gs2dScreen.cpp
+++ b/backends/platform/ps2/Gs2dScreen.cpp
@@ -392,12 +392,8 @@ void Gs2dScreen::copyScreenRect(const uint8 *buf, int pitch, int x, int y, int w
Graphics::Surface *Gs2dScreen::lockScreen() {
WaitSema(g_DmacSema);
- _framebuffer.pixels = _screenBuf;
- _framebuffer.w = _width;
- _framebuffer.h = _height;
- _framebuffer.pitch = _width; // -not- _pitch; ! It's EE mem, not Tex
- _framebuffer.format = Graphics::PixelFormat::createFormatCLUT8();
-
+ // -not- _pitch; ! It's EE mem, not Tex
+ _framebuffer.init(_width, _height, _width, _screenBuf, Graphics::PixelFormat::createFormatCLUT8());
return &_framebuffer;
}
diff --git a/backends/platform/psp/default_display_client.cpp b/backends/platform/psp/default_display_client.cpp
index bc252144fa..6d6eb641f7 100644
--- a/backends/platform/psp/default_display_client.cpp
+++ b/backends/platform/psp/default_display_client.cpp
@@ -192,11 +192,8 @@ void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
Graphics::Surface *Screen::lockAndGetForEditing() {
DEBUG_ENTER_FUNC();
- _frameBuffer.pixels = _buffer.getPixels();
- _frameBuffer.w = _buffer.getSourceWidth();
- _frameBuffer.h = _buffer.getSourceHeight();
- _frameBuffer.pitch = _buffer.getBytesPerPixel() * _buffer.getWidth();
- _frameBuffer.format = _pixelFormat;
+ _frameBuffer.init(_buffer.getSourceWidth(), _buffer.getSourceHeight(), _buffer.getBytesPerPixel() * _buffer.getWidth(),
+ _buffer.getPixels(), _pixelFormat);
// We'll set to dirty once we unlock the screen
return &_frameBuffer;
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index f55dd277c7..7ab367d4a4 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -98,7 +98,13 @@ OSystem_SDL::~OSystem_SDL() {
delete _mixerManager;
_mixerManager = 0;
+#ifdef ENABLE_EVENTRECORDER
+ // HACK HACK HACK
+ // This is nasty.
delete g_eventRec.getTimerManager();
+#else
+ delete _timerManager;
+#endif
_timerManager = 0;
delete _mutexManager;
@@ -193,9 +199,15 @@ void OSystem_SDL::initBackend() {
// Setup and start mixer
_mixerManager->init();
}
+
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.registerMixerManager(_mixerManager);
g_eventRec.registerTimerManager(new SdlTimerManager());
+#else
+ if (_timerManager == 0)
+ _timerManager = new SdlTimerManager();
+#endif
if (_audiocdManager == 0) {
// Audio CD support was removed with SDL 1.3
@@ -470,12 +482,18 @@ void OSystem_SDL::setupIcon() {
uint32 OSystem_SDL::getMillis(bool skipRecord) {
uint32 millis = SDL_GetTicks();
+
+#ifdef ENABLE_EVENTRECORDER
g_eventRec.processMillis(millis, skipRecord);
+#endif
+
return millis;
}
void OSystem_SDL::delayMillis(uint msecs) {
+#ifdef ENABLE_EVENTRECORDER
if (!g_eventRec.processDelayMillis())
+#endif
SDL_Delay(msecs);
}
@@ -498,11 +516,20 @@ Audio::Mixer *OSystem_SDL::getMixer() {
SdlMixerManager *OSystem_SDL::getMixerManager() {
assert(_mixerManager);
+
+#ifdef ENABLE_EVENTRECORDER
return g_eventRec.getMixerManager();
+#else
+ return _mixerManager;
+#endif
}
Common::TimerManager *OSystem_SDL::getTimerManager() {
+#ifdef ENABLE_EVENTRECORDER
return g_eventRec.getTimerManager();
+#else
+ return _timerManager;
+#endif
}
#ifdef USE_OPENGL
diff --git a/backends/platform/tizen/application.cpp b/backends/platform/tizen/application.cpp
index 8236ebef67..a73efacf58 100644
--- a/backends/platform/tizen/application.cpp
+++ b/backends/platform/tizen/application.cpp
@@ -31,7 +31,7 @@ Application *TizenScummVM::createInstance() {
return new TizenScummVM();
}
-TizenScummVM::TizenScummVM() : _appForm(0) {
+TizenScummVM::TizenScummVM() : _appForm(NULL) {
logEntered();
}
@@ -41,7 +41,7 @@ TizenScummVM::~TizenScummVM() {
TizenSystem *system = (TizenSystem *)g_system;
system->destroyBackend();
delete system;
- g_system = 0;
+ g_system = NULL;
}
}
@@ -68,17 +68,19 @@ bool TizenScummVM::OnAppTerminating(AppRegistry &appRegistry, bool forcedTermina
}
void TizenScummVM::OnUserEventReceivedN(RequestId requestId, IList *args) {
+ logEntered();
MessageBox messageBox;
int modalResult;
+ String *message;
- logEntered();
-
- if (requestId == USER_MESSAGE_EXIT) {
+ switch (requestId) {
+ case USER_MESSAGE_EXIT:
// normal program termination
Terminate();
- } else if (requestId == USER_MESSAGE_EXIT_ERR) {
+ break;
+
+ case USER_MESSAGE_EXIT_ERR:
// assertion failure termination
- String *message = NULL;
if (args) {
message = (String *)args->GetAt(0);
}
@@ -88,12 +90,15 @@ void TizenScummVM::OnUserEventReceivedN(RequestId requestId, IList *args) {
messageBox.Construct(L"Oops...", *message, MSGBOX_STYLE_OK);
messageBox.ShowAndWait(modalResult);
Terminate();
- } else if (requestId == USER_MESSAGE_EXIT_ERR_CONFIG) {
+ break;
+
+ case USER_MESSAGE_EXIT_ERR_CONFIG:
// the config file was corrupted
messageBox.Construct(L"Config file corrupted",
L"Settings have been reverted, please restart.", MSGBOX_STYLE_OK);
messageBox.ShowAndWait(modalResult);
Terminate();
+ break;
}
}
@@ -132,7 +137,6 @@ void TizenScummVM::pauseGame(bool pause) {
if (pause && g_engine && !g_engine->isPaused()) {
_appForm->pushKey(Common::KEYCODE_SPACE);
}
-
if (g_system) {
((TizenSystem *)g_system)->setMute(pause);
}
diff --git a/backends/platform/tizen/audio.cpp b/backends/platform/tizen/audio.cpp
index 313a10eaa8..f9ac80a583 100644
--- a/backends/platform/tizen/audio.cpp
+++ b/backends/platform/tizen/audio.cpp
@@ -26,8 +26,9 @@
#include "backends/platform/tizen/audio.h"
#include "backends/platform/tizen/system.h"
-#define TIMER_INTERVAL 10
-#define VOLUME 99
+#define TIMER_INTERVAL 10
+#define VOLUME 96
+#define MIN_TIMER_INTERVAL 5
AudioThread::AudioThread() :
_mixer(0),
@@ -38,6 +39,7 @@ AudioThread::AudioThread() :
_ready(0),
_interval(TIMER_INTERVAL),
_playing(-1),
+ _size(0),
_muted(true) {
}
@@ -70,7 +72,7 @@ void AudioThread::setMute(bool on) {
if (on) {
_timer->Cancel();
} else {
- _timer->StartAsRepeatable(_interval);
+ _timer->Start(_interval);
}
}
}
@@ -105,13 +107,14 @@ bool AudioThread::OnStart(void) {
}
}
+ _size = _audioBuffer[0].GetCapacity();
_timer = new Timer();
if (!_timer || IsFailed(_timer->Construct(*this))) {
AppLog("Failed to create audio timer");
return false;
}
- if (IsFailed(_timer->StartAsRepeatable(_interval))) {
+ if (IsFailed(_timer->Start(_interval))) {
AppLog("failed to start audio timer");
return false;
}
@@ -137,6 +140,7 @@ void AudioThread::OnStop(void) {
if (_audioOut) {
_audioOut->Reset();
+ _audioOut->Unprepare();
delete _audioOut;
}
}
@@ -161,21 +165,33 @@ void AudioThread::OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src) {
_tail = (_tail + 1) % NUM_AUDIO_BUFFERS;
_ready--;
} else {
- // audio buffer empty: decrease timer inverval
+ // audio buffer empty: decrease timer interval
_playing = -1;
+ _interval -= 1;
+ if (_interval < MIN_TIMER_INTERVAL) {
+ _interval = MIN_TIMER_INTERVAL;
+ }
}
+
}
void AudioThread::OnTimerExpired(Timer &timer) {
if (_ready < NUM_AUDIO_BUFFERS) {
- uint len = _audioBuffer[_head].GetCapacity();
- int samples = _mixer->mixCallback((byte *)_audioBuffer[_head].GetPointer(), len);
- if (samples) {
- _head = (_head + 1) % NUM_AUDIO_BUFFERS;
- _ready++;
+ if (_playing != _head) {
+ if (_mixer->mixCallback((byte *)_audioBuffer[_head].GetPointer(), _size)) {
+ _head = (_head + 1) % NUM_AUDIO_BUFFERS;
+ _ready++;
+ }
}
+ } else {
+ // audio buffer full: restore timer interval
+ _interval = TIMER_INTERVAL;
}
+
if (_ready && _playing == -1) {
OnAudioOutBufferEndReached(*_audioOut);
}
+
+ _timer->Start(_interval);
}
+
diff --git a/backends/platform/tizen/audio.h b/backends/platform/tizen/audio.h
index 8d7835042d..a304231578 100644
--- a/backends/platform/tizen/audio.h
+++ b/backends/platform/tizen/audio.h
@@ -54,6 +54,7 @@ public:
bool isSilentMode();
void setMute(bool on);
+private:
bool OnStart(void);
void OnStop(void);
void OnAudioOutErrorOccurred(Tizen::Media::AudioOut &src, result r);
@@ -62,12 +63,11 @@ public:
void OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src);
void OnTimerExpired(Timer &timer);
-private:
Audio::MixerImpl *_mixer;
Tizen::Base::Runtime::Timer *_timer;
Tizen::Media::AudioOut *_audioOut;
Tizen::Base::ByteBuffer _audioBuffer[NUM_AUDIO_BUFFERS];
- int _head, _tail, _ready, _interval, _playing;
+ int _head, _tail, _ready, _interval, _playing, _size;
bool _muted;
};
diff --git a/backends/platform/tizen/form.cpp b/backends/platform/tizen/form.cpp
index cce4b99557..10d51cc610 100644
--- a/backends/platform/tizen/form.cpp
+++ b/backends/platform/tizen/form.cpp
@@ -52,7 +52,7 @@ TizenAppForm::TizenAppForm() :
_eventQueueLock(NULL),
_state(kInitState),
_buttonState(kLeftButton),
- _shortcut(kShowKeypad) {
+ _shortcut(kEscapeKey) {
}
result TizenAppForm::Construct() {
@@ -157,6 +157,8 @@ result TizenAppForm::OnInitializing(void) {
AddOrientationEventListener(*this);
AddTouchEventListener(*this);
SetMultipointTouchEnabled(true);
+ SetFormBackEventListener(this);
+ SetFormMenuEventListener(this);
// set focus to enable receiving key events
SetEnabled(true);
@@ -354,8 +356,6 @@ void TizenAppForm::OnTouchDoublePressed(const Control &source,
if (_buttonState != kMoveOnly) {
pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN,
currentPosition);
- pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN,
- currentPosition);
}
}
@@ -417,3 +417,16 @@ void TizenAppForm::OnTouchReleased(const Control &source,
}
}
+void TizenAppForm::OnFormBackRequested(Form &source) {
+ logEntered();
+ if (_state == kActiveState) {
+ invokeShortcut();
+ }
+}
+
+void TizenAppForm::OnFormMenuRequested(Form &source) {
+ logEntered();
+ if (_state == kActiveState) {
+ setShortcut();
+ }
+}
diff --git a/backends/platform/tizen/form.h b/backends/platform/tizen/form.h
index 64c447d409..e419c14d24 100644
--- a/backends/platform/tizen/form.h
+++ b/backends/platform/tizen/form.h
@@ -29,6 +29,8 @@
#include <FBase.h>
#include <FUiITouchEventListener.h>
#include <FUiITextEventListener.h>
+#include <FUiCtrlIFormBackEventListener.h>
+#include <FUiCtrlIFormMenuEventListener.h>
#include "config.h"
#include "common/scummsys.h"
@@ -40,6 +42,7 @@
using namespace Tizen::Ui;
using namespace Tizen::Graphics;
using namespace Tizen::Base::Runtime;
+using namespace Tizen::Ui::Controls;
//
// TizenAppForm
@@ -48,7 +51,9 @@ class TizenAppForm :
public Controls::Form,
public IRunnable,
public IOrientationEventListener,
- public ITouchEventListener {
+ public ITouchEventListener,
+ public IFormBackEventListener,
+ public IFormMenuEventListener {
public:
TizenAppForm();
@@ -89,6 +94,8 @@ private:
void OnTouchReleased(const Control &source,
const Point &currentPosition,
const TouchEventInfo &touchInfo);
+ void OnFormBackRequested(Form &source);
+ void OnFormMenuRequested(Form &source);
void pushEvent(Common::EventType type, const Point &currentPosition);
void terminate();
diff --git a/backends/platform/tizen/fs.cpp b/backends/platform/tizen/fs.cpp
index f8b32f4239..8145cd5638 100644
--- a/backends/platform/tizen/fs.cpp
+++ b/backends/platform/tizen/fs.cpp
@@ -339,7 +339,6 @@ bool TizenFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
if (_isVirtualDir && mode != Common::FSNode::kListFilesOnly && _path == "/") {
// present well known TIZEN file system areas
myList.push_back(new TizenFilesystemNode(kData));
- myList.push_back(new TizenFilesystemNode(kResource));
myList.push_back(new TizenFilesystemNode(kSdCard));
myList.push_back(new TizenFilesystemNode(kMedia));
myList.push_back(new TizenFilesystemNode(kShared));
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index bf255cd264..2cafb9f781 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -100,6 +100,8 @@ void TizenGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
void TizenGraphicsManager::setReady() {
+ logEntered();
+ _appForm->GetVisualElement()->SetShowState(true);
_initState = false;
}
@@ -176,7 +178,9 @@ bool TizenGraphicsManager::loadEgl() {
systemError("eglMakeCurrent() failed");
return false;
}
-
+ if (!_initState) {
+ _appForm->GetVisualElement()->SetShowState(true);
+ }
logLeaving();
return true;
}
@@ -213,6 +217,7 @@ void TizenGraphicsManager::internUpdateScreen() {
void TizenGraphicsManager::unloadGFXMode() {
logEntered();
+ _appForm->GetVisualElement()->SetShowState(false);
if (_eglDisplay != EGL_NO_DISPLAY) {
eglMakeCurrent(_eglDisplay, NULL, NULL, NULL);
diff --git a/backends/platform/tizen/sscanf.cpp b/backends/platform/tizen/sscanf.cpp
index aa846698f6..75f009cc61 100644
--- a/backends/platform/tizen/sscanf.cpp
+++ b/backends/platform/tizen/sscanf.cpp
@@ -93,7 +93,7 @@ bool scanStringUntil(const char **in, va_list *ap, char c_end) {
char *arg = va_arg(*ap, char*);
while (**in && **in != c_end) {
*arg = **in;
- *arg++;
+ arg++;
(*in)++;
}
*arg = 0;
diff --git a/backends/platform/tizen/system.cpp b/backends/platform/tizen/system.cpp
index 54d92146e5..3448dc1421 100644
--- a/backends/platform/tizen/system.cpp
+++ b/backends/platform/tizen/system.cpp
@@ -513,13 +513,15 @@ TizenAppForm *systemStart(Tizen::App::Application *app) {
}
if (E_SUCCESS != appForm->Construct() ||
- E_SUCCESS != appFrame->AddControl(*appForm)) {
+ E_SUCCESS != appFrame->AddControl(appForm)) {
delete appForm;
AppLog("Failed to construct appForm");
return NULL;
}
appFrame->SetCurrentForm(appForm);
+ appForm->GetVisualElement()->SetShowState(false);
+
logLeaving();
return appForm;
}
@@ -531,7 +533,7 @@ void systemError(const char *message) {
AppLog("Fatal system error: %s", message);
if (strspn(message, "Config file buggy:") > 0) {
- Tizen::Io::File::Remove(DEFAULT_CONFIG_FILE);
+ Tizen::Io::File::Remove(App::GetInstance()->GetAppDataPath() + DEFAULT_CONFIG_FILE);
Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR_CONFIG, NULL);
} else {
ArrayList *args = new ArrayList();
diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp
index a9bcdbb8d1..92c890b0a9 100644
--- a/backends/platform/wii/osystem_gfx.cpp
+++ b/backends/platform/wii/osystem_gfx.cpp
@@ -528,16 +528,13 @@ void OSystem_Wii::updateScreen() {
}
Graphics::Surface *OSystem_Wii::lockScreen() {
- _surface.pixels = _gamePixels;
- _surface.w = _gameWidth;
- _surface.h = _gameHeight;
+ _surface.init(_gameWidth, _gameHeight,
#ifdef USE_RGB_COLOR
- _surface.pitch = _gameWidth * _pfGame.bytesPerPixel;
- _surface.format = _pfGame;
+ _gameWidth * _pfGame.bytesPerPixel, _gamePixels, _pfGame
#else
- _surface.pitch = _gameWidth;
- _surface.format = Graphics::PixelFormat::createFormatCLUT8();
+ _gameWidth, _gamePixels, Graphics::PixelFormat::createFormatCLUT8()
#endif
+ );
return &_surface;
}
diff --git a/backends/vkeybd/virtual-keyboard-gui.cpp b/backends/vkeybd/virtual-keyboard-gui.cpp
index 75de86472f..ec4cbf1de2 100644
--- a/backends/vkeybd/virtual-keyboard-gui.cpp
+++ b/backends/vkeybd/virtual-keyboard-gui.cpp
@@ -32,11 +32,9 @@
namespace Common {
-static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, OverlayColor transparent) {
- if (surf_dst->format.bytesPerPixel != sizeof(OverlayColor) || surf_src->format.bytesPerPixel != sizeof(OverlayColor))
- return;
-
- const OverlayColor *src = (const OverlayColor *)surf_src->pixels;
+template<typename ColorType>
+static void blitImplementation(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, ColorType transparent) {
+ const ColorType *src = (const ColorType *)surf_src->getPixels();
int blitW = surf_src->w;
int blitH = surf_src->h;
@@ -58,13 +56,13 @@ static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16
if (blitW <= 0 || blitH <= 0)
return;
- OverlayColor *dst = (OverlayColor *)surf_dst->getBasePtr(x, y);
+ ColorType *dst = (ColorType *)surf_dst->getBasePtr(x, y);
int dstAdd = surf_dst->w - blitW;
int srcAdd = surf_src->w - blitW;
for (int i = 0; i < blitH; ++i) {
for (int j = 0; j < blitW; ++j, ++dst, ++src) {
- OverlayColor col = *src;
+ ColorType col = *src;
if (col != transparent)
*dst = col;
}
@@ -73,6 +71,16 @@ static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16
}
}
+static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, uint32 transparent) {
+ if (surf_dst->format.bytesPerPixel != surf_src->format.bytesPerPixel)
+ return;
+
+ if (surf_dst->format.bytesPerPixel == 2)
+ blitImplementation<uint16>(surf_dst, surf_src, x, y, transparent);
+ else if (surf_dst->format.bytesPerPixel == 4)
+ blitImplementation<uint32>(surf_dst, surf_src, x, y, transparent);
+}
+
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
: _kbd(kbd), _displaying(false), _drag(false),
_drawCaret(false), _displayEnabled(false), _firstRun(true),
@@ -111,7 +119,7 @@ void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
}
}
-void VirtualKeyboardGUI::setupDisplayArea(Rect &r, OverlayColor forecolor) {
+void VirtualKeyboardGUI::setupDisplayArea(Rect &r, uint32 forecolor) {
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
if (!fontIsSuitable(_dispFont, r)) {
@@ -161,7 +169,7 @@ void VirtualKeyboardGUI::run() {
_system->clearOverlay();
}
_overlayBackup.create(_screenW, _screenH, _system->getOverlayFormat());
- _system->grabOverlay(_overlayBackup.pixels, _overlayBackup.pitch);
+ _system->grabOverlay(_overlayBackup.getPixels(), _overlayBackup.pitch);
setupCursor();
@@ -171,7 +179,7 @@ void VirtualKeyboardGUI::run() {
removeCursor();
- _system->copyRectToOverlay(_overlayBackup.pixels, _overlayBackup.pitch, 0, 0, _overlayBackup.w, _overlayBackup.h);
+ _system->copyRectToOverlay(_overlayBackup.getPixels(), _overlayBackup.pitch, 0, 0, _overlayBackup.w, _overlayBackup.h);
if (!g_gui.isActive()) _system->hideOverlay();
_overlayBackup.free();
@@ -262,7 +270,7 @@ void VirtualKeyboardGUI::screenChanged() {
_screenH = newScreenH;
_overlayBackup.create(_screenW, _screenH, _system->getOverlayFormat());
- _system->grabOverlay(_overlayBackup.pixels, _overlayBackup.pitch);
+ _system->grabOverlay(_overlayBackup.getPixels(), _overlayBackup.pitch);
if (!_kbd->checkModeResolutions()) {
_displaying = false;
@@ -356,13 +364,13 @@ void VirtualKeyboardGUI::redraw() {
Graphics::Surface surf;
surf.create(w, h, _system->getOverlayFormat());
- OverlayColor *dst = (OverlayColor *)surf.pixels;
- const OverlayColor *src = (OverlayColor *) _overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
+ byte *dst = (byte *)surf.getPixels();
+ const byte *src = (const byte *)_overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
while (h--) {
- memcpy(dst, src, surf.w * sizeof(OverlayColor));
- dst += surf.w;
- src += _overlayBackup.w;
+ memcpy(dst, src, surf.pitch);
+ dst += surf.pitch;
+ src += _overlayBackup.pitch;
}
blit(&surf, _kbdSurface, _kbdBound.left - _dirtyRect.left,
@@ -371,7 +379,7 @@ void VirtualKeyboardGUI::redraw() {
blit(&surf, &_dispSurface, _dispX - _dirtyRect.left,
_dispY - _dirtyRect.top, _dispBackColor);
}
- _system->copyRectToOverlay(surf.pixels, surf.pitch,
+ _system->copyRectToOverlay(surf.getPixels(), surf.pitch,
_dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
surf.free();
diff --git a/backends/vkeybd/virtual-keyboard-gui.h b/backends/vkeybd/virtual-keyboard-gui.h
index d0f9c884ed..a2000adea0 100644
--- a/backends/vkeybd/virtual-keyboard-gui.h
+++ b/backends/vkeybd/virtual-keyboard-gui.h
@@ -99,7 +99,7 @@ private:
VirtualKeyboard *_kbd;
Rect _kbdBound;
Graphics::Surface *_kbdSurface;
- OverlayColor _kbdTransparentColor;
+ uint32 _kbdTransparentColor;
Point _dragPoint;
bool _drag;
@@ -113,7 +113,7 @@ private:
const Graphics::Font *_dispFont;
int16 _dispX, _dispY;
uint _dispI;
- OverlayColor _dispForeColor, _dispBackColor;
+ uint32 _dispForeColor, _dispBackColor;
int _lastScreenChanged;
int16 _screenW, _screenH;
@@ -121,7 +121,7 @@ private:
bool _displaying;
bool _firstRun;
- void setupDisplayArea(Rect &r, OverlayColor forecolor);
+ void setupDisplayArea(Rect &r, uint32 forecolor);
void move(int16 x, int16 y);
void moveToDefaultPosition();
void screenChanged();
diff --git a/backends/vkeybd/virtual-keyboard.h b/backends/vkeybd/virtual-keyboard.h
index 4ab5ad446d..3b2b2196bd 100644
--- a/backends/vkeybd/virtual-keyboard.h
+++ b/backends/vkeybd/virtual-keyboard.h
@@ -112,11 +112,11 @@ protected:
String resolution;
String bitmapName;
Graphics::Surface *image;
- OverlayColor transparentColor;
+ uint32 transparentColor;
ImageMap imageMap;
VKEventMap events;
Rect displayArea;
- OverlayColor displayFontColor;
+ uint32 displayFontColor;
Mode() : image(0) {}
~Mode() {
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index a39c748adc..a032f37a25 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -827,9 +827,8 @@ void upgradeTargets() {
printf("Upgrading all your existing targets\n");
- Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
- Common::ConfigManager::DomainMap::iterator iter = domains.begin();
- for (iter = domains.begin(); iter != domains.end(); ++iter) {
+ Common::ConfigManager::DomainMap::iterator iter = ConfMan.beginGameDomains();
+ for (; iter != ConfMan.endGameDomains(); ++iter) {
Common::ConfigManager::Domain &dom = iter->_value;
Common::String name(iter->_key);
Common::String gameid(dom.getVal("gameid"));
diff --git a/base/main.cpp b/base/main.cpp
index 3f51c97949..103d743bbc 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -427,6 +427,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// take place after the backend is initiated and the screen has been setup
system.getEventManager()->init();
+#ifdef ENABLE_EVENTRECORDER
// Directly after initializing the event manager, we will initialize our
// event recorder.
//
@@ -434,6 +435,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// our event recorder, we might do this at another place. Or even change
// the whole API for that ;-).
g_eventRec.RegisterEventSource();
+#endif
// Now as the event manager is created, setup the keymapper
setupKeymapper(system);
@@ -471,9 +473,11 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// Try to run the game
Common::Error result = runGame(plugin, system, specialDebug);
+#ifdef ENABLE_EVENTRECORDER
// Flush Event recorder file. The recorder does not get reinitialized for next game
// which is intentional. Only single game per session is allowed.
g_eventRec.deinit();
+#endif
#if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES)
// do our best to prevent fragmentation by unloading as soon as we can
@@ -526,7 +530,9 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
GUI::GuiManager::destroy();
Common::ConfigManager::destroy();
Common::DebugManager::destroy();
+#ifdef ENABLE_EVENTRECORDER
GUI::EventRecorder::destroy();
+#endif
Common::SearchManager::destroy();
#ifdef USE_TRANSLATION
Common::TranslationManager::destroy();
diff --git a/common/config-manager.h b/common/config-manager.h
index d43a7bec51..6bf56749c5 100644
--- a/common/config-manager.h
+++ b/common/config-manager.h
@@ -24,7 +24,6 @@
#define COMMON_CONFIG_MANAGER_H
#include "common/array.h"
-//#include "common/config-file.h"
#include "common/hashmap.h"
#include "common/singleton.h"
#include "common/str.h"
@@ -47,12 +46,33 @@ class ConfigManager : public Singleton<ConfigManager> {
public:
- class Domain : public StringMap {
+ class Domain {
private:
+ StringMap _entries;
StringMap _keyValueComments;
String _domainComment;
public:
+ typedef StringMap::const_iterator const_iterator;
+ const_iterator begin() const { return _entries.begin(); }
+ const_iterator end() const { return _entries.end(); }
+
+ bool empty() const { return _entries.empty(); }
+
+ bool contains(const String &key) const { return _entries.contains(key); }
+
+ String &operator[](const String &key) { return _entries[key]; }
+ const String &operator[](const String &key) const { return _entries[key]; }
+
+ void setVal(const String &key, const String &value) { _entries.setVal(key, value); }
+
+ String &getVal(const String &key) { return _entries.getVal(key); }
+ const String &getVal(const String &key) const { return _entries.getVal(key); }
+
+ void clear() { _entries.clear(); }
+
+ void erase(const String &key) { _entries.erase(key); }
+
void setDomainComment(const String &comment);
const String &getDomainComment() const;
@@ -143,7 +163,8 @@ public:
bool hasMiscDomain(const String &domName) const;
const DomainMap & getGameDomains() const { return _gameDomains; }
- DomainMap & getGameDomains() { return _gameDomains; }
+ DomainMap::iterator beginGameDomains() { return _gameDomains.begin(); }
+ DomainMap::iterator endGameDomains() { return _gameDomains.end(); }
static void defragment(); // move in memory to reduce fragmentation
void copyFrom(ConfigManager &source);
diff --git a/common/config-file.cpp b/common/ini-file.cpp
index 0ce6dcf0c8..be5247dcfb 100644
--- a/common/config-file.cpp
+++ b/common/ini-file.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -28,24 +28,24 @@
namespace Common {
-bool ConfigFile::isValidName(const String &name) {
+bool INIFile::isValidName(const String &name) {
const char *p = name.c_str();
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
return *p == 0;
}
-ConfigFile::ConfigFile() {
+INIFile::INIFile() {
}
-ConfigFile::~ConfigFile() {
+INIFile::~INIFile() {
}
-void ConfigFile::clear() {
+void INIFile::clear() {
_sections.clear();
}
-bool ConfigFile::loadFromFile(const String &filename) {
+bool INIFile::loadFromFile(const String &filename) {
File file;
if (file.open(filename))
return loadFromStream(file);
@@ -53,7 +53,7 @@ bool ConfigFile::loadFromFile(const String &filename) {
return false;
}
-bool ConfigFile::loadFromSaveFile(const char *filename) {
+bool INIFile::loadFromSaveFile(const char *filename) {
assert(g_system);
SaveFileManager *saveFileMan = g_system->getSavefileManager();
SeekableReadStream *loadFile;
@@ -67,7 +67,7 @@ bool ConfigFile::loadFromSaveFile(const char *filename) {
return status;
}
-bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
+bool INIFile::loadFromStream(SeekableReadStream &stream) {
Section section;
KeyValue kv;
String comment;
@@ -112,9 +112,9 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
p++;
if (*p == '\0')
- error("ConfigFile::loadFromStream: missing ] in line %d", lineno);
+ error("INIFile::loadFromStream: missing ] in line %d", lineno);
else if (*p != ']')
- error("ConfigFile::loadFromStream: Invalid character '%c' occurred in section name in line %d", *p, lineno);
+ error("INIFile::loadFromStream: Invalid character '%c' occurred in section name in line %d", *p, lineno);
// Previous section is finished now, store it.
if (!section.name.empty())
@@ -140,7 +140,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// If no section has been set, this config file is invalid!
if (section.name.empty()) {
- error("ConfigFile::loadFromStream: Key/value pair found outside a section in line %d", lineno);
+ error("INIFile::loadFromStream: Key/value pair found outside a section in line %d", lineno);
}
// Split string at '=' into 'key' and 'value'. First, find the "=" delimeter.
@@ -173,7 +173,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
return (!stream.err() || stream.eos());
}
-bool ConfigFile::saveToFile(const String &filename) {
+bool INIFile::saveToFile(const String &filename) {
DumpFile file;
if (file.open(filename))
return saveToStream(file);
@@ -181,7 +181,7 @@ bool ConfigFile::saveToFile(const String &filename) {
return false;
}
-bool ConfigFile::saveToSaveFile(const char *filename) {
+bool INIFile::saveToSaveFile(const char *filename) {
assert(g_system);
SaveFileManager *saveFileMan = g_system->getSavefileManager();
WriteStream *saveFile;
@@ -195,7 +195,7 @@ bool ConfigFile::saveToSaveFile(const char *filename) {
return status;
}
-bool ConfigFile::saveToStream(WriteStream &stream) {
+bool INIFile::saveToStream(WriteStream &stream) {
for (List<Section>::iterator i = _sections.begin(); i != _sections.end(); ++i) {
// Write out the section comment, if any
if (! i->comment.empty()) {
@@ -226,7 +226,7 @@ bool ConfigFile::saveToStream(WriteStream &stream) {
return !stream.err();
}
-void ConfigFile::addSection(const String &section) {
+void INIFile::addSection(const String &section) {
Section *s = getSection(section);
if (s)
return;
@@ -236,7 +236,7 @@ void ConfigFile::addSection(const String &section) {
_sections.push_back(newSection);
}
-void ConfigFile::removeSection(const String &section) {
+void INIFile::removeSection(const String &section) {
assert(isValidName(section));
for (List<Section>::iterator i = _sections.begin(); i != _sections.end(); ++i) {
if (section.equalsIgnoreCase(i->name)) {
@@ -246,13 +246,13 @@ void ConfigFile::removeSection(const String &section) {
}
}
-bool ConfigFile::hasSection(const String &section) const {
+bool INIFile::hasSection(const String &section) const {
assert(isValidName(section));
const Section *s = getSection(section);
return s != 0;
}
-void ConfigFile::renameSection(const String &oldName, const String &newName) {
+void INIFile::renameSection(const String &oldName, const String &newName) {
assert(isValidName(oldName));
assert(isValidName(newName));
@@ -262,7 +262,7 @@ void ConfigFile::renameSection(const String &oldName, const String &newName) {
// HACK: For now we just print a warning, for more info see the TODO
// below.
if (ns)
- warning("ConfigFile::renameSection: Section name \"%s\" already used", newName.c_str());
+ warning("INIFile::renameSection: Section name \"%s\" already used", newName.c_str());
else
os->name = newName;
}
@@ -274,7 +274,7 @@ void ConfigFile::renameSection(const String &oldName, const String &newName) {
}
-bool ConfigFile::hasKey(const String &key, const String &section) const {
+bool INIFile::hasKey(const String &key, const String &section) const {
assert(isValidName(key));
assert(isValidName(section));
@@ -284,7 +284,7 @@ bool ConfigFile::hasKey(const String &key, const String &section) const {
return s->hasKey(key);
}
-void ConfigFile::removeKey(const String &key, const String &section) {
+void INIFile::removeKey(const String &key, const String &section) {
assert(isValidName(key));
assert(isValidName(section));
@@ -293,7 +293,7 @@ void ConfigFile::removeKey(const String &key, const String &section) {
s->removeKey(key);
}
-bool ConfigFile::getKey(const String &key, const String &section, String &value) const {
+bool INIFile::getKey(const String &key, const String &section, String &value) const {
assert(isValidName(key));
assert(isValidName(section));
@@ -307,7 +307,7 @@ bool ConfigFile::getKey(const String &key, const String &section, String &value)
return true;
}
-void ConfigFile::setKey(const String &key, const String &section, const String &value) {
+void INIFile::setKey(const String &key, const String &section, const String &value) {
assert(isValidName(key));
assert(isValidName(section));
// TODO: Verify that value is valid, too. In particular, it shouldn't
@@ -329,13 +329,13 @@ void ConfigFile::setKey(const String &key, const String &section, const String &
}
}
-const ConfigFile::SectionKeyList ConfigFile::getKeys(const String &section) const {
+const INIFile::SectionKeyList INIFile::getKeys(const String &section) const {
const Section *s = getSection(section);
return s->getKeys();
}
-ConfigFile::Section *ConfigFile::getSection(const String &section) {
+INIFile::Section *INIFile::getSection(const String &section) {
for (List<Section>::iterator i = _sections.begin(); i != _sections.end(); ++i) {
if (section.equalsIgnoreCase(i->name)) {
return &(*i);
@@ -344,7 +344,7 @@ ConfigFile::Section *ConfigFile::getSection(const String &section) {
return 0;
}
-const ConfigFile::Section *ConfigFile::getSection(const String &section) const {
+const INIFile::Section *INIFile::getSection(const String &section) const {
for (List<Section>::const_iterator i = _sections.begin(); i != _sections.end(); ++i) {
if (section.equalsIgnoreCase(i->name)) {
return &(*i);
@@ -353,11 +353,11 @@ const ConfigFile::Section *ConfigFile::getSection(const String &section) const {
return 0;
}
-bool ConfigFile::Section::hasKey(const String &key) const {
+bool INIFile::Section::hasKey(const String &key) const {
return getKey(key) != 0;
}
-const ConfigFile::KeyValue* ConfigFile::Section::getKey(const String &key) const {
+const INIFile::KeyValue* INIFile::Section::getKey(const String &key) const {
for (List<KeyValue>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
if (key.equalsIgnoreCase(i->key)) {
return &(*i);
@@ -366,7 +366,7 @@ const ConfigFile::KeyValue* ConfigFile::Section::getKey(const String &key) const
return 0;
}
-void ConfigFile::Section::setKey(const String &key, const String &value) {
+void INIFile::Section::setKey(const String &key, const String &value) {
for (List<KeyValue>::iterator i = keys.begin(); i != keys.end(); ++i) {
if (key.equalsIgnoreCase(i->key)) {
i->value = value;
@@ -380,7 +380,7 @@ void ConfigFile::Section::setKey(const String &key, const String &value) {
keys.push_back(newKV);
}
-void ConfigFile::Section::removeKey(const String &key) {
+void INIFile::Section::removeKey(const String &key) {
for (List<KeyValue>::iterator i = keys.begin(); i != keys.end(); ++i) {
if (key.equalsIgnoreCase(i->key)) {
keys.erase(i);
diff --git a/common/config-file.h b/common/ini-file.h
index 8bba851110..1d94ce7bdc 100644
--- a/common/config-file.h
+++ b/common/ini-file.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef COMMON_CONFIG_FILE_H
-#define COMMON_CONFIG_FILE_H
+#ifndef COMMON_INI_FILE_H
+#define COMMON_INI_FILE_H
#include "common/hash-str.h"
#include "common/list.h"
@@ -34,9 +34,6 @@ class WriteStream;
/**
* This class allows reading/writing INI style config files.
- * It is used by the ConfigManager for storage, but can also
- * be used by other code if it needs to read/write custom INI
- * files.
*
* Lines starting with a '#' are ignored (i.e. treated as comments).
* Some effort is made to preserve comments, though.
@@ -47,10 +44,8 @@ class WriteStream;
* from/to files, but of course is not appropriate for fast access.
* The main reason is that this class is indeed geared toward doing precisely
* that!
- * If you need fast access to the game config, use higher level APIs, like the
- * one provided by ConfigManager.
*/
-class ConfigFile {
+class INIFile {
public:
struct KeyValue {
String key;
@@ -60,12 +55,12 @@ public:
typedef List<KeyValue> SectionKeyList;
- /** A section in a config file. I.e. corresponds to something like this:
+ /** A section in a ini file. I.e. corresponds to something like this:
* [mySection]
* key=value
*
* Comments are also stored, to keep users happy who like editing their
- * config files manually.
+ * ini files manually.
*/
struct Section {
String name;
@@ -82,8 +77,8 @@ public:
typedef List<Section> SectionList;
public:
- ConfigFile();
- ~ConfigFile();
+ INIFile();
+ ~INIFile();
// TODO: Maybe add a copy constructor etc.?
@@ -95,7 +90,7 @@ public:
*/
static bool isValidName(const String &name);
- /** Reset everything stored in this config file. */
+ /** Reset everything stored in this ini file. */
void clear();
bool loadFromFile(const String &filename);
@@ -127,14 +122,6 @@ private:
const Section *getSection(const String &section) const;
};
-/*
-- ConfigMan owns a config file
-- allow direct access to that config file (for the launcher)
-- simplify and unify the regular ConfigMan API in exchange
-
-
-*/
-
} // End of namespace Common
#endif
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 00562f746a..ba44caafd9 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -102,18 +102,18 @@ String MacResManager::computeResForkMD5AsString(uint32 length) const {
return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize));
}
-bool MacResManager::open(String filename) {
+bool MacResManager::open(const String &fileName) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
- String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc";
+ String fullPath = ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
- _baseFileName = filename;
+ _baseFileName = fileName;
return true;
}
@@ -123,38 +123,39 @@ bool MacResManager::open(String filename) {
File *file = new File();
- // First, let's try to see if the Mac converted name exists
- if (file->open(constructAppleDoubleName(filename)) && loadFromAppleDouble(*file)) {
- _baseFileName = filename;
+ // Prefer standalone files first, starting with raw forks
+ if (file->open(fileName + ".rsrc") && loadFromRawFork(*file)) {
+ _baseFileName = fileName;
return true;
}
file->close();
- // Check .bin too
- if (file->open(filename + ".bin") && loadFromMacBinary(*file)) {
- _baseFileName = filename;
+ // Then try for AppleDouble using Apple's naming
+ if (file->open(constructAppleDoubleName(fileName)) && loadFromAppleDouble(*file)) {
+ _baseFileName = fileName;
return true;
}
file->close();
- // Maybe we have a dumped fork?
- if (file->open(filename + ".rsrc") && loadFromRawFork(*file)) {
- _baseFileName = filename;
+ // Check .bin for MacBinary next
+ if (file->open(fileName + ".bin") && loadFromMacBinary(*file)) {
+ _baseFileName = fileName;
return true;
}
file->close();
- // Fine, what about just the data fork?
- if (file->open(filename)) {
- _baseFileName = filename;
+ // As a last resort, see if just the data fork exists
+ if (file->open(fileName)) {
+ _baseFileName = fileName;
+ // FIXME: Is this really needed?
if (isMacBinary(*file)) {
- file->seek(0, SEEK_SET);
+ file->seek(0);
if (loadFromMacBinary(*file))
return true;
}
- file->seek(0, SEEK_SET);
+ file->seek(0);
_stream = file;
return true;
}
@@ -165,18 +166,18 @@ bool MacResManager::open(String filename) {
return false;
}
-bool MacResManager::open(FSNode path, String filename) {
+bool MacResManager::open(const FSNode &path, const String &fileName) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
- String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc";
+ String fullPath = path.getPath() + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
- _baseFileName = filename;
+ _baseFileName = fileName;
return true;
}
@@ -184,52 +185,53 @@ bool MacResManager::open(FSNode path, String filename) {
}
#endif
- // First, let's try to see if the Mac converted name exists
- FSNode fsNode = path.getChild(constructAppleDoubleName(filename));
+ // Prefer standalone files first, starting with raw forks
+ FSNode fsNode = path.getChild(fileName + ".rsrc");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
- if (loadFromAppleDouble(*stream)) {
- _baseFileName = filename;
+ if (loadFromRawFork(*stream)) {
+ _baseFileName = fileName;
return true;
}
delete stream;
}
- // Check .bin too
- fsNode = path.getChild(filename + ".bin");
+ // Then try for AppleDouble using Apple's naming
+ fsNode = path.getChild(constructAppleDoubleName(fileName));
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
- if (loadFromMacBinary(*stream)) {
- _baseFileName = filename;
+ if (loadFromAppleDouble(*stream)) {
+ _baseFileName = fileName;
return true;
}
delete stream;
}
- // Maybe we have a dumped fork?
- fsNode = path.getChild(filename + ".rsrc");
+ // Check .bin for MacBinary next
+ fsNode = path.getChild(fileName + ".bin");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
- if (loadFromRawFork(*stream)) {
- _baseFileName = filename;
+ if (loadFromMacBinary(*stream)) {
+ _baseFileName = fileName;
return true;
}
delete stream;
}
- // Fine, what about just the data fork?
- fsNode = path.getChild(filename);
+ // As a last resort, see if just the data fork exists
+ fsNode = path.getChild(fileName);
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
- _baseFileName = filename;
+ _baseFileName = fileName;
+ // FIXME: Is this really needed?
if (isMacBinary(*stream)) {
- stream->seek(0, SEEK_SET);
+ stream->seek(0);
if (loadFromMacBinary(*stream))
return true;
}
- stream->seek(0, SEEK_SET);
+ stream->seek(0);
_stream = stream;
return true;
}
@@ -238,22 +240,22 @@ bool MacResManager::open(FSNode path, String filename) {
return false;
}
-bool MacResManager::exists(const String &filename) {
+bool MacResManager::exists(const String &fileName) {
// Try the file name by itself
- if (Common::File::exists(filename))
+ if (File::exists(fileName))
return true;
// Try the .rsrc extension
- if (Common::File::exists(filename + ".rsrc"))
+ if (File::exists(fileName + ".rsrc"))
return true;
// Check if we have a MacBinary file
- Common::File tempFile;
- if (tempFile.open(filename + ".bin") && isMacBinary(tempFile))
+ File tempFile;
+ if (tempFile.open(fileName + ".bin") && isMacBinary(tempFile))
return true;
// Check if we have an AppleDouble file
- if (tempFile.open(constructAppleDoubleName(filename)) && tempFile.readUint32BE() == 0x00051607)
+ if (tempFile.open(constructAppleDoubleName(fileName)) && tempFile.readUint32BE() == 0x00051607)
return true;
return false;
@@ -480,10 +482,10 @@ SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 resID) {
return _stream->readStream(len);
}
-SeekableReadStream *MacResManager::getResource(const String &filename) {
+SeekableReadStream *MacResManager::getResource(const String &fileName) {
for (uint32 i = 0; i < _resMap.numTypes; i++) {
for (uint32 j = 0; j < _resTypes[i].items; j++) {
- if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) {
+ if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) {
_stream->seek(_dataOffset + _resLists[i][j].dataOffset);
uint32 len = _stream->readUint32BE();
@@ -499,13 +501,13 @@ SeekableReadStream *MacResManager::getResource(const String &filename) {
return 0;
}
-SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &filename) {
+SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &fileName) {
for (uint32 i = 0; i < _resMap.numTypes; i++) {
if (_resTypes[i].id != typeID)
continue;
for (uint32 j = 0; j < _resTypes[i].items; j++) {
- if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) {
+ if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) {
_stream->seek(_dataOffset + _resLists[i][j].dataOffset);
uint32 len = _stream->readUint32BE();
@@ -574,7 +576,7 @@ void MacResManager::readMap() {
}
}
-Common::String MacResManager::constructAppleDoubleName(Common::String name) {
+String MacResManager::constructAppleDoubleName(String name) {
// Insert "._" before the last portion of a path name
for (int i = name.size() - 1; i >= 0; i--) {
if (i == 0) {
diff --git a/common/macresman.h b/common/macresman.h
index ed74da9cc6..cca6592f21 100644
--- a/common/macresman.h
+++ b/common/macresman.h
@@ -54,27 +54,32 @@ public:
/**
* Open a Mac data/resource fork pair.
+ *
+ * This uses SearchMan to find the data/resource forks. This should only be used
+ * from inside an engine.
+ *
* @param filename The base file name of the file
* @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
* @return True on success
*/
- bool open(String filename);
+ bool open(const String &fileName);
/**
* Open a Mac data/resource fork pair.
+ *
* @param path The path that holds the forks
* @param filename The base file name of the file
* @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
* @return True on success
*/
- bool open(FSNode path, String filename);
+ bool open(const FSNode &path, const String &fileName);
/**
* See if a Mac data/resource fork pair exists.
* @param filename The base file name of the file
* @return True if either a data fork or resource fork with this name exists
*/
- static bool exists(const String &filename);
+ static bool exists(const String &fileName);
/**
* Close the Mac data/resource fork pair.
@@ -94,12 +99,6 @@ public:
bool hasResFork() const;
/**
- * Check if the given stream is in the MacBinary format.
- * @param stream The stream we're checking
- */
- static bool isMacBinary(SeekableReadStream &stream);
-
- /**
* Read resource from the MacBinary file
* @param typeID FourCC of the type
* @param resID Resource ID to fetch
@@ -176,7 +175,13 @@ private:
bool loadFromMacBinary(SeekableReadStream &stream);
bool loadFromAppleDouble(SeekableReadStream &stream);
- static Common::String constructAppleDoubleName(Common::String name);
+ static String constructAppleDoubleName(String name);
+
+ /**
+ * Check if the given stream is in the MacBinary format.
+ * @param stream The stream we're checking
+ */
+ static bool isMacBinary(SeekableReadStream &stream);
enum {
kResForkNone = 0,
diff --git a/common/math.h b/common/math.h
index b85ec0d22a..ba137101e4 100644
--- a/common/math.h
+++ b/common/math.h
@@ -52,14 +52,6 @@
#endif
#endif
-#ifndef M_SQRT1_2
- #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
-#endif
-
-#ifndef M_PI
- #define M_PI 3.14159265358979323846
-#endif
-
#ifndef FLT_MIN
#define FLT_MIN 1E-37
#endif
diff --git a/common/module.mk b/common/module.mk
index 9f9126c8ef..1b34d151d0 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -2,7 +2,6 @@ MODULE := common
MODULE_OBJS := \
archive.o \
- config-file.o \
config-manager.o \
coroutines.o \
dcl.o \
@@ -15,6 +14,7 @@ MODULE_OBJS := \
gui_options.o \
hashmap.o \
iff_container.o \
+ ini-file.o \
installshield_cab.o \
language.o \
localization.o \
diff --git a/common/random.cpp b/common/random.cpp
index a74ab831ea..de1269b485 100644
--- a/common/random.cpp
+++ b/common/random.cpp
@@ -30,8 +30,12 @@ RandomSource::RandomSource(const String &name) {
// Use system time as RNG seed. Normally not a good idea, if you are using
// a RNG for security purposes, but good enough for our purposes.
assert(g_system);
- uint32 seed = g_eventRec.getRandomSeed(name);
- setSeed(seed);
+
+#ifdef ENABLE_EVENTRECORDER
+ setSeed(g_eventRec.getRandomSeed(name));
+#else
+ setSeed(g_system->getMillis());
+#endif
}
void RandomSource::setSeed(uint32 seed) {
diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp
index 60c47e11ce..d08bc599f1 100644
--- a/common/recorderfile.cpp
+++ b/common/recorderfile.cpp
@@ -39,6 +39,12 @@ PlaybackFile::PlaybackFile() : _tmpRecordFile(_tmpBuffer, kRecordBuffSize), _tmp
_writeStream = NULL;
_screenshotsFile = NULL;
_mode = kClosed;
+
+ _recordFile = 0;
+ _headerDumped = false;
+ _recordCount = 0;
+ _eventsSize = 0;
+ memset(_tmpBuffer, 1, kRecordBuffSize);
}
PlaybackFile::~PlaybackFile() {
diff --git a/common/scummsys.h b/common/scummsys.h
index 291de87dc9..3e9d5ef063 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -144,6 +144,63 @@
#endif
#endif
+// The following math constants are usually defined by the system math.h header, but
+// they are not part of the ANSI C++ standards and so can NOT be relied upon to be
+// present i.e. when -std=c++11 is passed to GCC, enabling strict ANSI compliance.
+// As we rely on these being present, we define them if they are not set.
+
+#ifndef M_E
+ #define M_E 2.7182818284590452354 /* e */
+#endif
+
+#ifndef M_LOG2E
+ #define M_LOG2E 1.4426950408889634074 /* log_2 e */
+#endif
+
+#ifndef M_LOG10E
+ #define M_LOG10E 0.43429448190325182765 /* log_10 e */
+#endif
+
+#ifndef M_LN2
+ #define M_LN2 0.69314718055994530942 /* log_e 2 */
+#endif
+
+#ifndef M_LN10
+ #define M_LN10 2.30258509299404568402 /* log_e 10 */
+#endif
+
+#ifndef M_PI
+ #define M_PI 3.14159265358979323846 /* pi */
+#endif
+
+#ifndef M_PI_2
+ #define M_PI_2 1.57079632679489661923 /* pi/2 */
+#endif
+
+#ifndef M_PI_4
+ #define M_PI_4 0.78539816339744830962 /* pi/4 */
+#endif
+
+#ifndef M_1_PI
+ #define M_1_PI 0.31830988618379067154 /* 1/pi */
+#endif
+
+#ifndef M_2_PI
+ #define M_2_PI 0.63661977236758134308 /* 2/pi */
+#endif
+
+#ifndef M_2_SQRTPI
+ #define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#endif
+
+#ifndef M_SQRT2
+ #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#endif
+
+#ifndef M_SQRT1_2
+ #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+#endif
+
// Include our C++11 compatability header for pre-C++11 compilers.
#if __cplusplus < 201103L
#include "common/c++11-compat.h"
diff --git a/common/util.h b/common/util.h
index 4ca1c42929..392ced1ffe 100644
--- a/common/util.h
+++ b/common/util.h
@@ -41,10 +41,10 @@
#undef MAX
#endif
-template<typename T> inline T ABS (T x) { return (x>=0) ? x : -x; }
-template<typename T> inline T MIN (T a, T b) { return (a<b) ? a : b; }
-template<typename T> inline T MAX (T a, T b) { return (a>b) ? a : b; }
-template<typename T> inline T CLIP (T v, T amin, T amax)
+template<typename T> inline T ABS(T x) { return (x >= 0) ? x : -x; }
+template<typename T> inline T MIN(T a, T b) { return (a < b) ? a : b; }
+template<typename T> inline T MAX(T a, T b) { return (a > b) ? a : b; }
+template<typename T> inline T CLIP(T v, T amin, T amax)
{ if (v < amin) return amin; else if (v > amax) return amax; else return v; }
/**
diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 6bb40e0980..c3698d5fce 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -231,7 +231,7 @@ bool NEResources::readResourceTable(uint32 offset) {
if (id & 0x8000)
res.id = id & 0x7FFF;
else
- res.id = getResourceString(*_exe, offset + id);
+ res.id = getResourceString(*_exe, offset + id);
if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames)) && s_resTypeNames[typeID & 0x7FFF][0] != 0)
debug(2, "Found resource %s %s", s_resTypeNames[typeID & 0x7FFF], res.id.toString().c_str());
diff --git a/configure b/configure
index 5a7b310fd4..1da7d7fb78 100755
--- a/configure
+++ b/configure
@@ -1785,7 +1785,8 @@ android | gamecube | psp | tizen | wii | webos)
*)
# ICC does not support pedantic, while GCC and clang do.
if test "$have_icc" = no ; then
- CXXFLAGS="$CXXFLAGS -pedantic"
+ # We *do* want the 'long long' extension.
+ CXXFLAGS="$CXXFLAGS -pedantic -Wno-long-long"
fi
;;
esac
@@ -1843,7 +1844,7 @@ esac
# Determine a data type with the given length
#
find_type_with_size() {
- for datatype in int short char long "long long" unknown; do
+ for datatype in int short char long "long long" __int64 "long long int" unknown; do
cat > tmp_find_type_with_size.cpp << EOF
typedef $datatype ac__type_sizeof_;
int main() {
@@ -2374,7 +2375,8 @@ if test -n "$_host"; then
DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER"
DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE"
DEFINES="$DEFINES -DDISABLE_COMMAND_LINE"
- if test "$_release_build" = yes; then
+ # Enable serial debugging output only when --enable-debug is passed
+ if test "$_release_build" = yes -o "$_debug_build" != yes; then
DEFINES="$DEFINES -DNOSERIAL"
fi
_optimization_level=-O3
@@ -2706,7 +2708,8 @@ case $_backend in
LDFLAGS="$LDFLAGS -nostartfiles"
LDFLAGS="$LDFLAGS "'$(ronindir)/lib/crt0.o'
LDFLAGS="$LDFLAGS "'-L$(ronindir)/lib'
- if test "$_release_build" = yes; then
+ # Enable serial debugging output only when --enable-debug is passed
+ if test "$_release_build" = yes -o "$_debug_build" != yes; then
LIBS="$LIBS -lronin-noserial -lm"
else
LIBS="$LIBS -lronin -lm"
@@ -3946,7 +3949,14 @@ fi
test "x$prefix" = xNONE && prefix=/usr/local
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\""
+case $_host_os in
+ mingw*)
+ # Windows stores all the external data files in executable file.
+ ;;
+ *)
+ DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\""
+ ;;
+esac
case $_backend in
openpandora)
diff --git a/devtools/README b/devtools/README
index c7f08d6dfa..482c24edc2 100644
--- a/devtools/README
+++ b/devtools/README
@@ -63,6 +63,13 @@ create_lure (dreammaster)
the lure.dat file.
+create_mort (Strangerke)
+-----------
+ Gathers several information found in the original DOS executable:
+ - Font data
+ - French, German and fan-made English translation
+
+
create_project (LordHoto, Littleboy)
--------------
Creates project files for Visual Studio 2005, 2008, 2010, 2012, Xcode and
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index ca809e0aac..01cde620e7 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -2350,8 +2350,10 @@ bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList
for (const int *id = needList; *id != -1; ++id) {
WRITE_BE_UINT16(dst, *id); dst += 2;
const ExtractFilename *fDesc = getFilenameDesc(*id);
- if (!fDesc)
+ if (!fDesc) {
+ delete[] map;
return false;
+ }
*dst++ = getTypeID(fDesc->type);
WRITE_BE_UINT32(dst, getFilename(eI, *id)); dst += 4;
}
@@ -2359,15 +2361,18 @@ bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList
char filename[12];
if (!getFilename(filename, eI, 0)) {
fprintf(stderr, "ERROR: Could not create ID map for game\n");
+ delete[] map;
return false;
}
out.removeFile(filename);
if (!out.addFile(filename, map, mapSize)) {
fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
+ delete[] map;
return false;
}
+ delete[] map;
return true;
}
diff --git a/devtools/create_kyradat/pak.cpp b/devtools/create_kyradat/pak.cpp
index 0203285a8f..0d085f563c 100644
--- a/devtools/create_kyradat/pak.cpp
+++ b/devtools/create_kyradat/pak.cpp
@@ -142,6 +142,7 @@ bool PAKFile::outputAllFiles() {
printf("OK\n");
} else {
printf("FAILED\n");
+ fclose(file);
return false;
}
fclose(file);
@@ -168,6 +169,7 @@ bool PAKFile::outputFileAs(const char *f, const char *fn) {
printf("OK\n");
} else {
printf("FAILED\n");
+ fclose(file);
return false;
}
fclose(file);
diff --git a/devtools/create_lure/process_actions.cpp b/devtools/create_lure/process_actions.cpp
index db965730cb..d1ddbf03f2 100644
--- a/devtools/create_lure/process_actions.cpp
+++ b/devtools/create_lure/process_actions.cpp
@@ -149,6 +149,7 @@ uint16 process_action_sequence_entry(int supportIndex, byte *data, uint16 remain
if (startOffset == 0x7328) { startOffset = 0x72ae; maxOffset = 0x7382; }
if (startOffset == 0x702f) { startOffset = 0x6f3d; maxOffset = 0x70a3; }
if (startOffset == 0x7886) { startOffset = 0x742a; maxOffset = 0x7896; }
+ break;
case DE_DEU:
if (startOffset == 0x7edb) { startOffset = 0x7ead; maxOffset = 0x7f05; }
if (startOffset == 0x7ab8) { startOffset = 0x796c; maxOffset = 0x7ae2; }
diff --git a/devtools/create_mortdat/create_mortdat.cpp b/devtools/create_mortdat/create_mortdat.cpp
new file mode 100644
index 0000000000..5a491eea2f
--- /dev/null
+++ b/devtools/create_mortdat/create_mortdat.cpp
@@ -0,0 +1,279 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 is a utility for extracting needed resource data from different language
+ * version of the Lure of the Temptress lure.exe executable files into a new file
+ * lure.dat - this file is required for the ScummVM Lure of the Temptress module
+ * to work properly
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/endian.h"
+#include "create_mortdat.h"
+#include "enginetext.h"
+#include "gametext.h"
+#include "menudata.h"
+
+
+bool File::open(const char *filename, AccessMode mode) {
+ f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb");
+ return (f != NULL);
+}
+
+void File::close() {
+ fclose(f);
+ f = NULL;
+}
+
+int File::seek(int32 offset, int whence) {
+ return fseek(f, offset, whence);
+}
+
+long File::read(void *buffer, int len) {
+ return fread(buffer, 1, len, f);
+}
+void File::write(const void *buffer, int len) {
+ fwrite(buffer, 1, len, f);
+}
+
+byte File::readByte() {
+ byte v;
+ read(&v, sizeof(byte));
+ return v;
+}
+
+uint16 File::readWord() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_LE_16(v);
+}
+
+uint32 File::readLong() {
+ uint32 v;
+ read(&v, sizeof(uint32));
+ return FROM_LE_32(v);
+}
+
+void File::writeByte(byte v) {
+ write(&v, sizeof(byte));
+}
+
+void File::writeWord(uint16 v) {
+ uint16 vTemp = TO_LE_16(v);
+ write(&vTemp, sizeof(uint16));
+}
+
+void File::writeLong(uint32 v) {
+ uint32 vTemp = TO_LE_32(v);
+ write(&vTemp, sizeof(uint32));
+}
+
+void File::writeString(const char *s) {
+ write(s, strlen(s) + 1);
+}
+
+uint32 File::pos() {
+ return ftell(f);
+}
+
+/*-------------------------------------------------------------------------*/
+
+void openOutputFile(const char *outFilename) {
+ outputFile.open(outFilename, kFileWriteMode);
+
+ // Write header
+ outputFile.write("MORT", 4);
+ outputFile.writeByte(VERSION_MAJOR);
+ outputFile.writeByte(VERSION_MINOR);
+}
+
+/**
+ * Write out the data for the font
+ */
+void writeFontBlock() {
+ const int knownAddr[3] = {0x30cd, 0x36b0, 0x36c0};
+ byte checkBuffer[7];
+ byte fontBuffer[121 * 6];
+
+ // Move to just prior the font data and verify that we're reading the known mort.com
+ for (int i = 0; i <= 3; ++i) {
+ if ( i == 3) {
+ printf("Invalid mort.com input file");
+ exit(0);
+ }
+
+ mortCom.seek(knownAddr[i]);
+ mortCom.read(checkBuffer, 7);
+
+ if ((checkBuffer[0] == 0x59) && (checkBuffer[1] == 0x5B) && (checkBuffer[2] == 0x58) &&
+ (checkBuffer[3] == 0xC3) && (checkBuffer[4] == 0xE8) && (checkBuffer[5] == 0xD6) &&
+ (checkBuffer[6] == 0x02)) {
+ break;
+ }
+ }
+
+ // Read in the data
+ mortCom.read(fontBuffer, 121 * 6);
+
+ // Write out a section header to the output file and the font data
+ const char fontHeader[4] = { 'F', 'O', 'N', 'T' };
+ outputFile.write(fontHeader, 4); // Section Id
+ outputFile.writeWord(121 * 6); // Section size
+
+ outputFile.write(fontBuffer, 121 * 6);
+}
+
+void writeStaticStrings(const char **strings, DataType dataType, int languageId) {
+ // Write out a section header
+ const char sStaticStrings[4] = { 'S', 'S', 'T', 'R' };
+ const char sGameStrings[4] = { 'G', 'S', 'T', 'R' };
+
+ if (dataType == kStaticStrings)
+ outputFile.write(sStaticStrings, 4);
+ else if (dataType == kGameStrings)
+ outputFile.write(sGameStrings, 4);
+
+ // Figure out the block size
+ int blockSize = 1;
+ const char **s = &strings[0];
+ while (*s) {
+ blockSize += strlen(*s) + 1;
+ ++s;
+ }
+
+ outputFile.writeWord(blockSize);
+
+ // Write out a byte indicating the language for this block
+ outputFile.writeByte(languageId);
+
+ // Write out each of the strings
+ s = &strings[0];
+ while (*s) {
+ outputFile.writeString(*s);
+ ++s;
+ }
+}
+
+/**
+ * Write out the strings previously hard-coded into the engine
+ */
+void writeEngineStrings() {
+ writeStaticStrings(engineDataEn, kStaticStrings, 1);
+ writeStaticStrings(engineDataFr, kStaticStrings, 0);
+ writeStaticStrings(engineDataDe, kStaticStrings, 2);
+}
+
+/**
+ * Write out the strings used in the game
+ */
+void writeGameStrings() {
+ writeStaticStrings(gameDataEn, kGameStrings, 1);
+ writeStaticStrings(gameDataFr, kGameStrings, 0);
+ writeStaticStrings(gameDataDe, kGameStrings, 2);
+}
+
+/**
+ * Write out the data for the English menu
+ */
+void writeMenuData(const char *menuData, int languageId) {
+ // Write out a section header to the output file and the menu data
+ const char menuHeader[4] = { 'M', 'E', 'N', 'U' };
+ outputFile.write(menuHeader, 4); // Section Id
+ int size = strlen(menuData) / 8 + 1; // Language code + Menu data size
+ outputFile.writeWord(size);
+
+ outputFile.writeByte(languageId);
+ // Write each 8-characters block as a byte (one bit per character)
+ // ' ' -> 0, anything else -> 1
+ byte value;
+ int valueCpt = 0;
+ const char* str = menuData;
+ while (*str != 0) {
+ if (*(str++) != ' ')
+ value |= (1 << (7 - valueCpt));
+ ++valueCpt;
+ if (valueCpt == 8) {
+ outputFile.writeByte(value);
+ value = 0;
+ valueCpt = 0;
+ }
+ }
+}
+
+void writeMenuBlock() {
+ writeMenuData(menuDataEn, 1);
+ writeMenuData(menuDataDe, 2);
+}
+
+void writeVerbNums(const int *verbs, int languageId) {
+ // Write out a section header to the output file
+ const char menuHeader[4] = { 'V', 'E', 'R', 'B' };
+ outputFile.write(menuHeader, 4); // Section Id
+ int size = 52 + 1; // Language code + 26 words
+ outputFile.writeWord(size);
+
+ outputFile.writeByte(languageId);
+ for (int i = 0; i < 26; i++)
+ outputFile.writeWord(verbs[i]);
+}
+
+void writeMenuVerbs() {
+ writeVerbNums(verbsEn, 1);
+ writeVerbNums(verbsFr, 0);
+ writeVerbNums(verbsDe, 2);
+}
+
+void process() {
+ writeFontBlock();
+ writeGameStrings();
+ writeEngineStrings();
+ writeMenuVerbs();
+ writeMenuBlock();
+}
+
+/**
+ * Main method
+ */
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ printf("Usage:\n%s input_filename\nWhere input_filename is the name of the Mortevielle DOS executable.\n", argv[0]);
+ exit(0);
+ }
+
+ mortCom.open(argv[1], kFileReadMode);
+ openOutputFile(MORT_DAT);
+
+ process();
+
+ mortCom.close();
+ outputFile.close();
+}
diff --git a/devtools/create_mortdat/create_mortdat.h b/devtools/create_mortdat/create_mortdat.h
new file mode 100644
index 0000000000..e5007ae653
--- /dev/null
+++ b/devtools/create_mortdat/create_mortdat.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a utility for extracting needed resource data from different language
+ * version of the Mortevielle executable files into a new file mort.dat - this
+ * is required for the ScummVM Mortevielle module to work properly
+ */
+
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 2
+
+enum AccessMode {
+ kFileReadMode = 1,
+ kFileWriteMode = 2
+};
+
+enum DataType {
+ kStaticStrings = 0,
+ kGameStrings = 1,
+ kEncryptionArrays = 2
+};
+
+#define MORT_DAT "mort.dat"
+
+class File {
+private:
+ FILE *f;
+public:
+ bool open(const char *filename, AccessMode mode = kFileReadMode);
+ void close();
+ int seek(int32 offset, int whence = SEEK_SET);
+ uint32 pos();
+ long read(void *buffer, int len);
+ void write(const void *buffer, int len);
+
+ byte readByte();
+ uint16 readWord();
+ uint32 readLong();
+ void writeByte(byte v);
+ void writeWord(uint16 v);
+ void writeLong(uint32 v);
+ void writeString(const char *s);
+};
+
+File outputFile, mortCom;
+
diff --git a/devtools/create_mortdat/enginetext.h b/devtools/create_mortdat/enginetext.h
new file mode 100644
index 0000000000..e1c40f898b
--- /dev/null
+++ b/devtools/create_mortdat/enginetext.h
@@ -0,0 +1,189 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a utility for extracting needed resource data from different language
+ * version of the Mortevielle executable files into a new file mort.dat - this
+ * is required for the ScummVM Mortevielle module to work properly
+ */
+
+#ifndef ENGINEDATA_H
+#define ENGINEDATA_H
+
+const char *engineDataEn[] = {
+ "[2][ ][YES][NO]",
+ "Go to",
+ "Someone enters, looks surprised, but says nothing",
+ " Cool ",
+ "Oppressive",
+ " Tense ",
+ "Idem",
+ "You",
+ "are",
+ "Alone",
+
+ "Gosh! You hear some noise...",
+ " | You should have noticed, | ",
+ "% of hints...",
+ "Do you want to wake up?",
+ "OK",
+ "",
+ " Save",
+
+ " Load",
+ " Restart",
+ "F3: Repeat",
+ "F8: Proceed",
+ "Hide self",
+ "take",
+ " probe ",
+ " raise ",
+ " -MORE- ",
+ " -STOP- ",
+ "[1] [So, use the DEP menu] [Ok]",
+ "lift",
+ "read",
+
+ "look",
+ "search",
+ "open",
+ "put",
+ "turn",
+ "tie",
+ "close",
+ "hit",
+ "pose",
+ "smash",
+
+ "smell",
+ "scratch",
+ "probe",
+ "[1] [ | Before, use the DEP menu...] [Ok]",
+ "& day",
+ NULL
+};
+
+const char *engineDataFr[] = {
+ "[2][ ][OUI][NON]",
+ "aller",
+ "quelqu'un entre, parait \202tonn\202 mais ne dit rien",
+ "Cool",
+ " Lourde ",
+ "Malsaine",
+ "Idem",
+ "Vous",
+ "\210tes",
+ "SEUL",
+
+ "Mince! Vous entendez du bruit...",
+ " | Vous devriez avoir remarqu\202| ",
+ "% des indices...",
+ "D\202sirez-vous vous r\202veiller?",
+ "OK",
+ "",
+ " Sauvegarde",
+
+ " Chargement",
+ " Recommence ",
+ "F3: Encore",
+ "F8: Suite",
+ "se cacher",
+
+ "prendre",
+ "sonder",
+ "soulever",
+ " -SUITE- ",
+ " -STOP- ",
+ "[1][Alors, utilisez le menu DEP...][ok]",
+ "soulever",
+ "lire",
+
+ "regarder",
+ "fouiller",
+ "ouvrir",
+ "mettre",
+ "tourner",
+ "attacher",
+ "fermer",
+ "frapper",
+ "poser",
+ "d\202foncer",
+
+ "sentir",
+ "gratter",
+ "sonder",
+ "[1][ | Avant, utilisez le menu DEP...][ok]",
+ "& jour",
+ NULL
+};
+
+const char *engineDataDe[] = {
+ "[2][ ][JA][NEIN]",
+ "gehen",
+ "Jemand kommt herein, scheint erstaunt, sagt nichts",
+ "Cool",
+ "Schwer",
+ "Ungesund",
+ "Idem",
+ "Sie",
+ "sind",
+ "allein",
+
+ "Verdammt! Sie hoeren ein Geraeush...",
+ "Sie haetten ",
+ "% der Hinweise| bemerken muessen...",
+ "Moechten Sie aufwachen?",
+ "OK",
+ "",
+ " schreiben",
+
+ " lesen",
+ " wieder ",
+ "F3: nochmals",
+ "F8: stop",
+ " sich verstecken",
+ " nehmen",
+ " sondieren",
+ " hochheben",
+ " -WEITER- ",
+ " -STOP- ",
+ "[1][ Benutzen Sie jetzt das Menue DEP...][OK]",
+ "hochheben",
+ "lesen",
+
+ "anschauen",
+ "durchsuchen",
+ "oeffnen",
+ "setzen",
+ "drehen",
+ "befestigen",
+ "schliessen",
+ "klopfen",
+ "hinlegen",
+ "eindruecken",
+
+ "fuehlen",
+ "abkratzen",
+ "sondieren",
+ "[1][ Benutzen Sie jetzt das Menue DEP...][OK]",
+ "& tag",
+ NULL
+};
+
+#endif
diff --git a/devtools/create_mortdat/gametext.h b/devtools/create_mortdat/gametext.h
new file mode 100644
index 0000000000..4f7b1f9776
--- /dev/null
+++ b/devtools/create_mortdat/gametext.h
@@ -0,0 +1,1794 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 is a utility for extracting needed resource data from different language
+ * version of the Mortevielle executable files into a new file mort.dat - this
+ * is required for the ScummVM Mortevielle module to work properly
+ */
+
+#ifndef GAMEDATA_H
+#define GAMEDATA_H
+
+const char *gameDataEn[] = {
+ "Calm within the storm$",
+ "Discussed in colours$",
+ "Your mauve!$",
+ "Be kind enough to leave the room...$",
+ "If you're NOT overdrawn...$",
+ "If you're feeling blue...$",
+ "Read what's on the walls?$",
+ "Water sports$",
+ "Room for envy?$",
+ "A glance at the forbidden$",
+ "Smell of a woodfire and tobacco$",
+ "Tobacco and old books$",
+ "Onions, cinnamon and spirits$",
+ "A place seldom visited$",
+ "Humidity and decay$",
+ "Sorry, no ""door to door""$",
+ "Rotting corpse: deady cryptomania$",
+ "And what's more, there are disused traps$",
+ "It's already open$",
+ "Danger: avalanches$",
+ "Proper Charlie's place?$",
+ "An imposing building$",
+ "The other side of the mystery$",
+ "Strange horoscope$",
+ "Look out... but she wishes well?$",
+ "An oak door$",
+ "A photograph$",
+ "The coat of arms$",
+ "$",
+ "Max, the servant, welcomes you and shows you to your room$",
+ "Mortville 6/2/51@ My dear Jerome@Regarding my telegram, I must tell you the reason for my wor-@ries. A year ago, Murielle, my lady companion, disappeared. The de@part may have had something to do@with the financial success of themanor, or... A silence hard to un@derstand for my son Guy. Not ha@ving been able to see the light of day over this affair, I count @on you to sort things out. If my state of health doesn't improve, @take the decisions that you feel @are apropriate.@ Kind regards, Julia DEFRANCK$",
+ "Later, Guy will inform you of Leo's suicide after a@heavy bet at the races$",
+ "F3: AGAIN F8: STOP$",
+ "The master of the premises$",
+ "The future heir$",
+ "JULIA's son$",
+ "A pretty picture$",
+ "Superman!$",
+ "Ida's husband$",
+ "Interesting remarks?$",
+ "Service included!$",
+ "Nothing underneath$",
+ "You could hear a pin drop$",
+ "Half an hour passes: nothing! Wait any longer?$",
+ "Admire! Contemplate!$",
+ "No! Nothing!$",
+ "Impossible$",
+ "That stains!$",
+ "A treatise on the history of the area$",
+ "A few coins...$",
+ "First commandment...$",
+ "Pleasing to the nostrils!$",
+ "Spades, Hearts...$",
+ "Just a spoonful of sugar...$",
+ "A romantic novel$",
+ "Worth more than a penny, (whistle)$",
+ "Just needs a little patience$",
+ "Watch the sharp bends$",
+ "Deep and dark$",
+ "Normal sensations$",
+ "Sniff!$",
+ "Not discreet! Be content to watch!$",
+ "Bless you! Dusty!$",
+ "The canvas is signed, the wallpaper is not!$",
+ "Nothing, Unlucky!$",
+ "Be more discreet!$",
+ "The shutters are closed$",
+ "Snow! And more snow!$",
+ "Brilliant! The work of a master!$",
+ "No doubt at all! A genuine fake!$",
+ "Hmm! A cheap reproduction!$",
+ "A rare and valuable piece$",
+ "Nothing special$",
+ "Linen, personal belongings...$",
+ "Not just anywhere!$",
+ "It's not time!$",
+ "One doesn't speak with ones mouth full! So once the meal is over...$",
+ "Someone comes in, messes about then goes out again$",
+ "Someone's approaching your hiding-place$",
+ "Someone surprises you!$",
+ "Impossible! You're too loaded!$",
+ "Try again!$",
+ "Still puzzled!?$",
+ "You leave Mortville.In Paris a message awaits you...$",
+ "You hurt yourself$",
+ "Nothing more here$",
+ "The sound seems normal$",
+ "It doesn't move$",
+ "You are answered$",
+ "Not the right moment!$",
+ "The same matter, from another angle!$",
+ "The reflection is tarnished, but the frame is gold!$",
+ "Bric-a-brac$",
+ "Facing failure!$",
+ "Smells like something you'd rather not see!$",
+ "Cleaning products$",
+ "Got an itch?$",
+ "It's stuck, frozen. Brrr!$",
+ "All the locks are jammed!$",
+ "Papers$",
+ "No! Father christmas hasn't got himself stuck!$",
+ "It leads onto a corridor$",
+ "China, silverware...$",
+ "No! It's not Julia's remains!$",
+ "An old engraving$",
+ "You find a deep diamond-shaped opening$",
+ "The wall slides open! A passage! Do you follow it?$",
+ "The passageway closes$",
+ "A secret drawer: a notebook! Do you read it?$",
+ "The drawer shuts$",
+ "Nothing! Flesh and blood stuck to the stone$",
+ "Certain details lead you to believe death was not immediate!$",
+ "A rotten affair!$",
+ "Did she cling to dear life with just one finger?$",
+ "Has the treasure packed its trunk?$",
+ "A slot the size of a coin$",
+ "Part of the stone wall pivots.A crypt! Do you enter?$",
+ "The ring turns, the wall closes$",
+ "A stone column behind the altar$",
+ "There is a noise!$",
+ "Occupied!$",
+ "Take another chance?$",
+ "Too deep!$",
+ "The cellar wall pivots$",
+ "Nothing$",
+ "The one and only!$",
+ "The object slides to the bottom$",
+ "You have nothing in hand$",
+ "It is not open$",
+ "There is already something$",
+ "The door is locked$",
+ "No reply$",
+ "A solid wooden ball$",
+ "There's no more space$",
+ "A wooden ball pierced through the side$",
+ "? ?$",
+ "Your move$",
+ "OK !$",
+ "Suddenly Max arrives with your suitcase: \"Thank you for your visit!\".@Mister discreet \"private eye\" (in need of a private optician!). Thoroughly demoralised, you leave the manor. You are useless!$",
+ "Leo interrupts: \"The storm has died down,I am going into town in 1 hour. Get ready\".@You have lost time...but not your life$",
+ "Congestion, the deadly flu... You are stuck here! Your whole case sinks slowly beneath the water$",
+ "The water is rising fast, freezing your last illusions. Before you have time to react... you are dead$",
+ "As soon as you reach the bottom of the well, a hand cuts the rope Farewell sweet life!$",
+ "The storm covers your footprints.A wall of silence falls heavily on your shoulders. Slowly you succumb to frosbite...$",
+ "You're not completely alone! A cold blade plunges into your back. In future, be more careful!$",
+ "You don't know what implication Leo may have had in Murielle's death. Was she dead outright? In any case, the family problems that you have uncovered in the course of your enquiries would explain Leo's behaviour. You're not sure that's the reason Julia had asked for your help, but that's reason enough for you! Out of respect for her, after taking certain precautions you have a revealing talk with Leo.$",
+ "$",
+ "You don't have the keys to the manor. Your cries rest unheard You're going to catch... your death!$",
+ "With a circular movement, the sword slices across you. Guts and intestines spill out all over. A sorry state of affairs!$",
+ "Home, Sweet home !$",
+ "The mystery behind a closed door$",
+ "Bewitching charm of these old rooms$",
+ "An empty stomach$",
+ "Closer to heaven? Not so sure$",
+ "Afraid of the dark?$",
+ "Old rugs and a glint of gold$",
+ "Anguish!$",
+ "Safe? Perhaps not!$",
+ "A little ill at ease, eh!?$",
+ "Always further$",
+ "Your way of the cross!$",
+ "On the trail of...$",
+ "Watch what's hiding$",
+ "The road down to hell$",
+ "Feeling well? You look a little pale$",
+ "What lurks behind...?$",
+ "Close-up on:$",
+ "You notice, amongst other things$",
+ "And...$",
+ "That's all!$",
+ "A bit of reading$",
+ "The adventure awaits, you set off!$",
+ "Don't mess up YOUR next ADVENTURE!$",
+ "I don't understand$",
+ "There is an easier way$",
+ "No, not just now$",
+ "Too late$",
+ "$",
+ "Like a deep stony stare, a solitary eye that points towards the@stars; the artery that links hea-ven and hell. You must fathom@these depths keeping hold of that@which is, and will become. Monday, Tuesday, Wednesday, Sunday, from@the first Monday to the first Sunday,plunging from one day to the next your@\"IS\" or \"WILL BECOME\". Carrying your burden with love and light,@the smallest oversight will seal your fate.$",
+ "10/1/51: We think we've solved the mystery of the manuscript and@located the crypt. Is it the idea@of success in what seems like a dream that disturbs me so? I feel@I have committed myself rather too much, as far as Leo is @concerned... No! I mustgo on. @I should have put Guy in the picture but for a week now, I've had@no news of him$",
+ "Take your prayers as you would to the holy place. From the pillar@of wisdom, bring the sun to his@knees. Thus will it show you the place to offer alms of another@kind and like young Arthur, open the way of darkness.White is your@colour, golden your hearth. So@advance with caution Orpheus and light your way unto the sad@virgin. Offer her the circle of the man with three faces. That he@may regain the world and turn with it to its original@inglory!$",
+ "The mountains are the fangs in a monstrous mouth opening on the@finity of a celestial orgy, grin-ding the stars as we grind our@teeth into dust. You will drop your chord of stone at your feet.@The laugh of silence at the@highest pitch, and in your right hand, the measure of genius. Thus@will you pass between the two crescents beyond the abyss of the@wall of silence. The key to the melody is within your grasp. It@suffices to find the note that clashes.$",
+ " 9/12 INTER. 518 3/13 EXPENS. 23@ 9/12 SALES 1203 7/12 CHEQUE 1598@ TOTAL 1721 TOTAL 1721$",
+ " 5/1/51@@ Luc, my love@ Guy knows about us. After an argument I told him everything! I@think only of you. Max keeps pes-tering me, but it's finished with @him. He should stick to his pots and pans! When can you and I be alone together? For you I would@get a divorce.@I love you.@ Eva$",
+ " Mortville, 10/2/51@@ Pat@ I recall you owe me 50000 frs that I lent you for your business@I need that money, can you repay me quickly?@ Guy$",
+ " Mortville, 15/2/51@ Dear Sir@ I am writing to you on the sub-ject of our business deal. I have@decided to go all the way in the certainty that my partner, Pat@DEFRANCK, has been forging the accounts. @In spite of$",
+ " A pipe$",
+ " A pen$",
+ " A lighter$",
+ " A retort$",
+ " A shaving brush$",
+ " A tin of paint$",
+ " A flute$",
+ " An expensive ring$",
+ " A reel of thread$",
+ " An old book$",
+ " A wallet$",
+ " A dagger$",
+ " A pistol$",
+ " A bible$",
+ " A candle$",
+ " A jewellery box$",
+ " An iron$",
+ " A photo$",
+ " A pocket watch$",
+ " A rope$",
+ " Keys$",
+ " A pearl necklace$",
+ " A bottle of perfume$",
+ " Binoculars$",
+ " Glasses$",
+ " A leather purse$",
+ " A tennis ball$",
+ " Ammunition$",
+ " A cut-throat razor$",
+ " A hairbrush$",
+ " A clothes brush$",
+ " A pack of cards$",
+ " A shoe horn$",
+ " A screwdriver$",
+ " A hammer$",
+ " Keys$",
+ " Keys$",
+ " An ashtray$",
+ " A paintbrush$",
+ " A rope$",
+ " A wooden object$",
+ " Sleeping pills$",
+ " A gold ring$",
+ " A jewellery box$",
+ " An alarm clock$",
+ " A coat of armour$",
+ " A candlestick$",
+ " A pair of gloves$",
+ " A engraved goblet$",
+ " A parchment$",
+ " A dagger$",
+ " A dossier$",
+ " A parchment$",
+ " A parchment$",
+ " A dossier$",
+ " A dossier$",
+ " A letter$",
+ " A novel$",
+ " A wooden rod$",
+ " An envelope$",
+ " A letter$",
+ " An envelope$",
+ "Julia$",
+ "Julia's death$",
+ "Julia's relationships$",
+ "A message from Julia$",
+ "Julia's inheritance$",
+ "Julia's final actions$",
+ "Julia's gifts$",
+ "Julia's bedroom$",
+ "The photo at Julia's home$",
+ "Julia and yourself...$",
+ "L\202o's occupations$",
+ "Pat's occupations$",
+ "Guy's occupations$",
+ "Bob's occupations$",
+ "Eva's occupations$",
+ "Luc's occupations$",
+ "Ida's occupations$",
+ "Max's occupations$",
+ "Your occupations$",
+ "L\202o's relationships$",
+ "Pat's relationships$",
+ "Guy's relationships$",
+ "Bob's relationships$",
+ "Eva's relationships$",
+ "Luc's relationships$",
+ "Ida's relationships$",
+ "Max's relationships$",
+ "Your relationships$",
+ "Murielle$",
+ "Murielle's relationships$",
+ "Murielle and yourself...$",
+ "Murielle's disappearance$",
+ "The wall of silence$",
+ "The manuscripts$",
+ "The coat of arms$",
+ "Engravings in the cellar$",
+ "The well$",
+ "The secret passages$",
+ "The chapel$",
+ "The paintings$",
+ "The photo of the attic$",
+ "The body in the crypt$",
+ "$",
+ "$",
+ "END OF THE CONVERSATION$",
+ "That was the name old people gave to the mountain range that lies at the foot of the manor!$",
+ "These are the mountains one can see in front of the manor$",
+ "I don't know!$",
+ "She died from pulmonary embolism$",
+ "Mother died suddenly. And yet her health had seemed to improve\202$",
+ "Miss DEFRANCK died from a cold$",
+ "She died from pulmonary embolism$",
+ "Excuse me but I prefer to say nothing for now$",
+ "Only the good die young$",
+ "I loved my mother . My only regret is that she died in the DEFRANCK's manor$",
+ "That region has a lot of history and there is plenty to keep me busy. And also I love horses..$",
+ "He is a history enthusiast and a gambler. By the way he won a large sum one year ago$",
+ "He is already very busy with the management and maintenance of the mansion...$",
+ "I am the CEO of a small perfume company. But when I am here, I rest$",
+ "He is a dynamic man who has succeeded in perfurmes$",
+ "Him! He is an upstart rogue! Perfumes must have killed his common sense. Moreover, when he's here he spends his evenings in his room$",
+ "I was very concerned about my mother's health, and now I don't feel like doing anything at all$",
+ "He would have done better to look after me a bit more and a bit less after his mother$",
+ "It is not my business...$",
+ "He does not have much luck at the moment although his business is satisfactory$",
+ "I work with Pat but it's not going too well at the moment$",
+ "Oh really?! He has occupations? He should take them seriously then$",
+ "Him and Pat are patners. I think it's going pretty well$",
+ "I take care of myself and that's already lots. How about you?$",
+ "Oh for that I trust her! She knows how to keep herself busy$",
+ "What! You have not yet discovered her main occupation..?$",
+ "She is working in the decoration business, and tastefully with that. She is always very well dressed$",
+ "If you like jewels, I have some good deals to propose for a short while$",
+ "The jewels...$",
+ "I don't know, but I'd like him to give me a bit more slack!$",
+ "When one is a housewife, one always find something to do...$",
+ "She could stay there doing nothing, but no! She sews, she reads...$",
+ "She has probably not very fulfilling occupations...$",
+ "A woman like there is no more: She is interested in everything!$",
+ "With the cooking and the cleaning I do not have much time for you$",
+ "I do not know how he manages to do everything. That's wonderful!",
+ "He would do more if he showed less interest in gossip and alcohol$",
+ "I am very independant. As long as nobody interferes in my business: No problem$",
+ "He is selfish. I wonder if he likes something other than his horses and grimoires$",
+ "I think he gets along well with everyone, except, perhaps, with Guy$",
+ "He has a temper. You have to learn how to deal with him...$",
+ "Business is business. As for the family, I leave it as it is...$",
+ "Relations? Friendly relations? Financial relations, without a doubt$",
+ "Oh, I have no issue with this person$",
+ "He is a resourceful businessman. He sometimes tries to swim upstream but... he will always find a way to make it work$",
+ "They are all boring .. No! Not even that .. Even if .. some of them ..$",
+ "Contrary to his mother, he is a very shy person ! So when you say relations...$",
+ "He must be trying very hard to remain nice despite all his troubles$",
+ "His romantic relationship: it's over. His relationship with me: hasn't really started. As for the other ones: I don't follow the \"other ones\"$",
+ "I like everyone, as long as they are not trying to screw me over$",
+ "It is not enough to have a bit of money and to know how to talk for everyone to like you$",
+ "Not much to say about him... He is a nice and generous man. And what's more, he can be quite funny$",
+ "Nowadays I get along rather well with everyone. But, here, I am not going to say more about this$",
+ "Nice feathers, but a bird's brain... Ask her husband$",
+ "Is it for an appointment?$",
+ "She is very lively! She does not burden herself with stupids prejudices$",
+ "In my line of work, one mostly encounters beautiful women and gangsters$",
+ "The only sure thing he has going for him, it's his jewelery... And his wife, but he doesn't realize that$",
+ "It's an interesting character. Who is not always very easy to follow, but worth knowing$",
+ "I hate no one, but I like things and people when they stay where they should be$",
+ "This stays between us. But you see: when I speak with her, I soon start to feel a bit uncomfortable!$",
+ "You'd have to try hard to not get along with her$",
+ "You know, in my line of work you hear everything but don't remember anything, and service is well done$",
+ "He's a submissive hypocrite! Personally I don't trust him$",
+ "I don't know what he thinks deep down inside, but he's always polite and impeccable$",
+ "Someone who lived in the manor, a year ago... maybe more$",
+ "She was more than a friend to my mother. In these moments, I would have loved to have her by my side$",
+ "Murielle has been Julia's lady-in-waiting$",
+ "She, too, was doing some research....$",
+ "She was a very educated person. Her abrupt leaving, a year ago, surprised me and caused me great sorrow$",
+ "Her and Leo shared a common passion for history and the local area$",
+ "I think everyone liked her$",
+ "She got along with everyone. She loved her son dearly. As for the relations between mother-in-law and daughter-in-law...$",
+ "Apart from Leo, she got along very well with Max...$",
+ "Even if your relations were unfrequent, Jerome, there was still a place for you in her heart...$",
+ "Apart from her family, not a lot of people$",
+ "Oh right! I think she deeply regretted this friend's leaving... err! Marielle... or Mireille...$",
+ "No, nothing!$",
+ "No... Not that I know of$",
+ "I met Julia when buying the manor. It was the only thing she owned. But all my wealth was hers...$",
+ "Apart from a few personal belongings, I think she didn't own anything anymore$",
+ "I think all her fortune came from Leo. So, pfft!$",
+ "Apart from the letter for you I posted, nothing very important!$",
+ "I was very happy she gave me her bound bible as a present$",
+ "It happened fast and she didn't have time to make any particular will$",
+ "Her last gift suprised me$",
+ "Which gift?$",
+ "A chandelier...$",
+ "Yes, I got a present. My wife even got a bible$",
+ "Well yes! Like everyone, I believe$",
+ "A dagger$",
+ "I have never been looking around in the attic!$",
+ "You can either see through walls or pick a door$",
+ "The portrait of a young girl: it's Murielle...$",
+ "You know, I didn't know her that well$",
+ "She was very charming, but above all she was Julia's lady-in-waiting$",
+ "She was the only truly interesting woman I've met$",
+ "She had a great knowledge in history, and you learned a great deal when you asked her about it$",
+ "I've always wondered why some people fancied her!$",
+ "If the room is closed, ask Leo$",
+ "I closed her door after her death and I'd like it to remain this way for a while$",
+ "You know how it is: family relations$",
+ "All those years, I've never regretted serving her$",
+ "I loved her as much as she loved me, I think$",
+ "What made you think you could enter my wife's room?!!$",
+ "It must be the picture of Murielle with Julia's godson$",
+ "I don't remember$",
+ "This is Murielle. I took that picture, and actually they developed it backwards$",
+ "You sure are curious!... It's not worth anything$",
+ "Grimoires, parchment and manuscripts: it is Leo's realm$",
+ "Too bad the motto doesn't appear here...$",
+ "This is beautiful... And very old...$",
+ "Hey! That's a place I've never visited$",
+ "According to Leo, it seems that the Moons are more recent$",
+ "Even under this weather, you managed to find a sun...$",
+ "Profound and disturbing: Progress is good$",
+ "For me, it remains the biggest of all mysteries$",
+ "The last days she was talking about a trip. And then...$",
+ "A little over a year ago, one night, she decided to leave...$",
+ "In any case, she wasn't meant to live here$",
+ "What?! Whose body? Which crypt?$",
+ "If there are any, I have never found them...$",
+ "Of course! And ghosts too...$",
+ "It's the oldest in the area: it is from the 11th century$",
+ "It was slightly renovated after the French Revolution$",
+ "Julia loved paintings$",
+ "They are different in styles, but not all of them are worth a lot$",
+ "What are you doing h-$",
+ "I'm sure you are looking for something in here$",
+ "I'm listening$",
+ "What do you want?$",
+ "Yes?$",
+ "I'm all yours...$",
+ "What's the matter?$",
+ "Go ahead$",
+ "What is it about?$",
+ "Max: at your service, sir$",
+ "In any case you have no business being in here! Get out!!$",
+ "You are too curious!$",
+ "Jerome! It's been a while... I'm very sad to announce you that Julia died. Her family is here: Guy, her son; Eva, her daughter-in-law; Leo, her husband, of course; her son-in-law Pat; cousins, too: Bob, Ida, Luc. The storm is getting stronger, you must stay here. Meals are served at 12am and 7pm, and there is a mass at the chapel every day at 10am$",
+ "When I saw you I knew you would uncover the truth... I knew why you were here: I had found the draft of Julia's letter. But I love to play, so... She hadn't wanted your task to be too easy, to protect me, probably, but she couldn't die knowing this mystery would remain unsolved. Did you find out that the wall of silence is the name the builders gave, during the construction of the manor, to the wall on which the coat of arms hangs?... And those gifts Julia left before dying were as many false leads, and their true purpose was to highlight how important the parchments were... That's right, more than a year ago I was working with Murielle on the decryption of those manuscripts I had just found. My wife made the connection between our work and Murielle's disappearance, but she never had any proof. Except that ring she found one day while going through my belongings. One night, we went exploring the secret passage we had found. Murielle died by accident in the room of the Virgin. I quickly took the ring from her, found the treasure and ran away. I didn't think she was still alive, and I didn't say a word because I needed the money. I told everyone the money was coming from a winning bet at the horseraces... Leave now, since you're not a policeman. Leave me alone!$",
+ "February 1951... Occupation: private eye. The cold was freezing Paris off, and my cases as well, when...$",
+ "A letter, a call, memories from a childhood not that long ago. Echoes of the many games we played in the disused rooms of Mortville Manor... And Julia, now an old woman.$",
+ " to the office$",
+ " to the kitchen$",
+ " to the cellar$",
+ " to the landing$",
+ " outside$",
+ " to the dining room$",
+ " inside the manor$",
+ " front of the manor$",
+ " to the chapel$",
+ " to the well$",
+ " north$",
+ " behind the manor$",
+ " south$",
+ " east$",
+ " west$",
+ " towards the manor$",
+ " further$",
+ " in the water$",
+ " out of the well$",
+ " in the well$",
+ " choice on screen$",
+ "In the MYSTERY series...$",
+ "MORTVILLE MANOR$",
+ "$",
+ "From an original idea of...$",
+ "Bernard GRELAUD and Bruno GOURIER$",
+ "$",
+ "Directed by: KYILKHOR CREATION and LANGLOIS$",
+ "$",
+ "With the cooperation of...$",
+ "B\202atrice et Jean_Luc LANGLOIS$",
+ "for the music and the voices,$",
+ "Bernard GRELAUD for the graphic conception,$",
+ "MARIA-DOLORES for the graphic direction,$",
+ "Bruno GOURIER for the technical direction,$",
+ "Mick ANDON for the translation. $",
+ "$",
+ "Publisher: KYILKHOR and B&JL LANGLOIS $",
+ "COPYRIGHT 1987: KYILKHOR and B&JL LANGLOIS$",
+ "$",
+ "YOUR MOVE$",
+ " attach$",
+ " close$",
+ " eat$",
+ " enter$",
+ " force$",
+ " knock$",
+ " leave$",
+ " lift$",
+ " listen$",
+ " look$",
+ " open$",
+ " place$",
+ " read$",
+ " scratch$",
+ " search$",
+ " sleep$",
+ " smell$",
+ " sound$",
+ " take$",
+ " turn$",
+ " wait$",
+ " hide yourself$",
+ " look$",
+ " put$",
+ " read$",
+ " search$",
+ " Leo$",
+ " Pat$",
+ " Guy$",
+ " Eva$",
+ " Bob$",
+ " Luc$",
+ " Ida$",
+ " Max$",
+ "JULIA...$",
+ "- Did she commit suicide?$",
+ "- Was she murdered?$",
+ "- Did she die by accident?$",
+ "- Did she die of natural causes?$",
+ "Where did the money used for the@restoration of the manor come from?$",
+ "- Blackmail$",
+ "- Honest work$",
+ "- Inheritance$",
+ "- Races$",
+ "- Rents$",
+ "- Hold-up$",
+ "- Other$",
+ "What is Leo's hobby?$",
+ "- Historical research$",
+ "- Politics$",
+ "- Painting$",
+ "- Drugs$",
+ "- Occult sciences$",
+ "- Leader of a sect$",
+ "Julia left several clues that are@represented in one place. Which one?$",
+ "- Chapel$",
+ "- Outside$",
+ "- Cellar$",
+ "- Attic$",
+ "- Kitchen$",
+ "- Dining room$",
+ "- Julia's room$",
+ "- Leo's room$",
+ "- Pat's room$",
+ "- Bob's room$",
+ "- Max's room$",
+ "- Luc/Ida's room$",
+ "- Guy/Eva's room$",
+ "The main clue that lead you@to the underground door is:$",
+ "- A dagger$",
+ "- A ring$",
+ "- A book$",
+ "- A parchment$",
+ "- A letter$",
+ "- A pendulum$",
+ "How many parchments were there in the manor?$",
+ "- None$",
+ "- Just one$",
+ "- Two$",
+ "- Three$",
+ "- Four$",
+ "- Five$",
+ "How many persons are involved in@this story?@(including Julia, but not yourself)$",
+ "- Nine$",
+ "- Ten$",
+ "- Eleven$",
+ "What was the first name@of the unknown character?$",
+ "- Mireille$",
+ "- Fran\207oise$",
+ "- Maguy$",
+ "- Emilie$",
+ "- Murielle$",
+ "- Sophie$",
+ "Who did Murielle have an affair with?$",
+ "- Bob$",
+ "- Luc$",
+ "- Guy$",
+ "- Leo$",
+ "- Max$",
+ "Murielle shared an occupation@with one other person. Who?$",
+ "[1][You realize that certain elements of|this investigation remain a mystery for you.|Therefore, you decide first to learn|more before undertaking new risks..][ok]$",
+ "[3][ | insert disk 1 | in drive A ][ok]$",
+ "[1][ | Disk error | All stop... ][ok]$",
+ "[1][ | You should have noticed |00% of the clues ][ok]$",
+ "[3][ | insert disk 2 | in drive A ][ok]$",
+ "[1][ |Before going any further, you decide to| look back on the knowledge you gained][ok]$",
+ "TBT - MASTER .$",
+ "TBT - rorL$",
+ NULL
+};
+
+const char *gameDataFr[] = {
+ "Le calme dans la tourmente$",
+ "Des go\227ts et des couleurs!$",
+ "Mauve qui peut!$",
+ "Pri\212re de laisser en sortant...$",
+ "Trou noir troublant$",
+ "Bleu... comme \"peur bleue\"!$",
+ "Chambre de \"Saigneur\"!$",
+ "Histoire d'eaux$",
+ "Vert nid$",
+ "Coup d'oeil sur l'interdit$",
+ "Odeur de feux de bois et de tabac$",
+ "Tabac et vieux bouquins$",
+ "Oignons, cannelle et spiritueux$",
+ "Un endroit bien peu visit\202$",
+ "Humidit\202 et moisissure$",
+ "Avis aux colporteurs...$",
+ "Corps putr\202fi\202 : cryptomanie mortelle!$",
+ "Et en plus... des pi\212ges d\202samorc\202s!$",
+ "C'est d\202j\205 ouvert$",
+ "Danger : avalanches$",
+ "Une odeur de saintet\202!$",
+ "Une b\203tisse imposante$",
+ "L'envers du myst\212re!$",
+ "Dr\223le d'horoscope!$",
+ "Tant va la cruche...$",
+ "Une porte en ch\212ne$",
+ "Une photo$",
+ "Les armoiries$",
+ "$",
+ "Max, le domestique, vous accueille puis vous conduit \205 votre chambre$",
+ "Mortevielle, le 16/2/51@ Mon cher J\202r\223me,@ Suite \205 mon t\202l\202gramme, je vous fais part des raisons de mon inqui\202tude :il y a un an, Murielle, ma dame de compagnie, disparaissait . D\202part ayant rapport avec le renouveau financier du Manoir, ou... Silence difficile \205 comprendre, surtout pour mon fils Guy . N'ayant pu jusqu'\205 pr\202sent, faire le jour sur cette affaire, je compte sur vous pour la mener \205 bien . Si mon \202tat de sant\202 ne s'am\202liorait pas, prenez les d\202cisions qui vous sembleront le plus appropri\202es...@ Amiti\202s. JULIA DEFRANCK$",
+ "Plus tard, Guy vous apprendra le suicide de L\202o... apr\212s un pari insens\202 aux courses!$",
+ "F3: encore@F8: suite$",
+ "Le ma\214tre des lieux$",
+ "Le futur h\202ritier$",
+ "Le fils de JULIA$",
+ "Joli brin!!!$",
+ "Superman!$",
+ "Le mari d'Ida$",
+ "Propos int\202ressants?$",
+ "Service compris...$",
+ "Rien dessous!$",
+ "Un ange passe...$",
+ "Une 1/2 h passe: rien! Attendez-vous encore?$",
+ "Admirez! Contemplez!$",
+ "Non ! Rien !$",
+ "Impossible$",
+ "\207a tache !$",
+ "Un trait\202 sur l'histoire de la r\202gion$",
+ "Quelques pi\212ces$",
+ "Premier commandement...$",
+ "Des p\202tales plein les narines !$",
+ "Pique, Coeur...$",
+ "\207a ne manque pas de cachets !$",
+ "Un roman d'amour$",
+ "Souffler n'est pas jouer$",
+ "Pas une r\202ussite!$",
+ "Gare aux rebondissements !$",
+ "Sombre et profond...$",
+ "Sensations normales$",
+ "Sniff!$",
+ "Pas discret ! Contentez-vous de regarder !$",
+ "Atchoum! De la p... poussi\212re$",
+ "La toile est sign\202e... pas le papier peint !$",
+ "Pas de chance, rien !$",
+ "Soyez plus discret !$",
+ "Les volets sont clos$",
+ "De la neige, encore de la neige !$",
+ "G\202nial : une toile de ma\214tre !$",
+ "Aucun doute : une v\202ritable imitation$",
+ "Hum ! Vous tiquez : de l'antique en toc !$",
+ "Une pi\212ce rare de valeur !$",
+ "Rien de remarquable$",
+ "Linge, objets personnels...$",
+ "Pas n'importe o\227 !$",
+ "Ce n'est pas l'heure !$",
+ "On ne parle pas la bouche pleine ! Donc, une fois le repas termin\202...$",
+ "Quelqu'un entre, s'affaire, ressort...$",
+ "On s'approche de votre cachette !$",
+ "On vous surprend !$",
+ "Non : vous \210tes trop charg\202 !$",
+ "Essayez de nouveau$",
+ "Vous restez perplexe !?$",
+ "Vous quittez le Manoir. A Paris, un message vous attend...$",
+ "A\213e, a\213e, a\213e !$",
+ "Rien de plus$",
+ "Le son para\214t normal$",
+ "Ca ne bouge pas$",
+ "On vous r\202pond$",
+ "Pas le moment !$",
+ "M\210me mati\212re, autre face !$",
+ "Le reflet est piqu\202, mais le cadre est d'or$",
+ "Bibelots, babioles...$",
+ "Vous essuyez un \202chec !$",
+ "Il est des odeurs... qu'il vaut mieux ne pas voir !$",
+ "Des produits m\202nagers$",
+ "\207a vous d\202mange ?$",
+ "C'est coinc\202, gel\202 ! Brrrr...$",
+ "Les huisseries sont bloqu\202es !$",
+ "Des papiers...$",
+ "Non ! Le p\212re No\210l n'est pas coinc\202 !$",
+ "\207a donne sur un couloir$",
+ "Vaisselle, argenterie...$",
+ "Non ! Ce ne sont pas les restes de Julia !$",
+ "Une gravure ancienne$",
+ "Il y a une profonde ouverture en losange$",
+ "Le mur coulisse... Un passage ! L'empruntez-vous ?$",
+ "Le passage se ferme$",
+ "Un tiroir secret... Un livret ! Le lisez-vous ?$",
+ "Le tiroir se referme$",
+ "Rien ! Sang et chairs collent \205 la pierre !$",
+ "Des d\202tails vous font supposer que... la mort ne fut pas imm\202diate !$",
+ "Des projets v\202reux ?$",
+ "Sa vie n'aurait-elle tenu qu'\205 un doigt ?$",
+ "Un tr\202sor se serait-il fait la malle ?$",
+ "Une fente de la taille d'une pi\212ce !$",
+ "Quelques pierres pivotent... Une crypte ! Y p\202n\202trez-vous ?$",
+ "La bague tourne, le mur se referme...$",
+ "Une colonne de pierres derri\212re l'autel$",
+ "Il y a du bruit...$",
+ "Occup\202 !$",
+ "Retentez-vous votre chance ?$",
+ "Trop profond !$",
+ "Le mur de la cave pivote$",
+ "Nothing !$",
+ "L'unique !$",
+ "L'objet glisse au fond...$",
+ "Vous n'avez rien en main$",
+ "Ce n'est pas ouvert$",
+ "Il y a d\202j\205 quelque chose$",
+ "La porte est ferm\202e$",
+ "Pas de r\202ponse$",
+ "Une boule de bois pleine$",
+ "Il n'y a plus de place$",
+ "Une boule de bois perc\202e par le travers$",
+ "? ?$",
+ "A vous de jouer$",
+ "OK !$",
+ "Soudain Max survient avec votre valise : \"Merci de votre visite ! D\202tective \"priv\202\"... de bon sens et de discr\202tion sans doute\" . D\202\207u d\202moralis\202, vous quittez le manoir@Vous \212tes NUL !$",
+ "L\202o vous interrompt : \"la temp\212te est calm\202e. Je pars en ville dans 1 heure. Tenez-vous pr\210t!\"... Bon... Vous avez perdu du temps... mais pas la vie$",
+ "Congestion, grippe fatale : vous y restez ! Votre enqu\212te tombe \205 l'eau$",
+ "L'eau monte tr\212s vite et refroidit vos derni\212res illusions... Avant que vous n'ayez eu le temps de r\202agir, vous \212tes mort!$",
+ "A peine \212tes-vous au fond du puits qu'une main tranche la corde... Adieu la vie!$",
+ "La temp\212te recouvre vos traces . Un mur de silence s'abat sur vos \202paules . Lentement vous succombez \205 la morsure du froid !$",
+ "Pas si seul que \207a ! Une lame glac\202e s'enfonce dans votre dos. A l'avenir, soyez plus prudent!$",
+ "Vous ignorez la responsabilit\202 exacte de L\202o dans la mort de Murielle... Est-elle morte sur le coup ? De toutes fa\207ons les probl\212mes familiaux d\202couverts lors de votre enqu\212te justifient l'attitude de L\202o... Vous n'\212tes pas s\227r que Julia vous ait appel\202 pour \207a mais c'est suffisant pour vous ! Par respect pour elle, et apr\212s certaines pr\202cautions, vous avez une entrevue r\202v\202latrice avec L\202o$",
+ "$",
+ "Vous n'avez pas les clefs du Manoir . Vos appels restent sans r\202ponse . Vous allez attraper... la mort !$",
+ "D'un mouvement circulaire, l'\202p\202e vous fend par le travers : tripes et boyaux \205 l'air, bonjour les vers!$",
+ "Home, Sweet home !$",
+ "Myst\212re d'une porte close$",
+ "Charme envo\227tant de vieilles pi\212ces$",
+ "La faim au ventre$",
+ "Plus pr\212s du ciel? Pas s\227r !$",
+ "Peur du noir?$",
+ "Vieux tapis et reflets d'or$",
+ "Angoisse !$",
+ "Sauv\202 ? Pas certain !$",
+ "Mal \205 l'aise, hein !$",
+ "Toujours plus loin !$",
+ "Votre chemin de croix !$",
+ "A la d\202couverte de...$",
+ "Attention \205 ce que cache...$",
+ "Une descente aux Enfers !$",
+ "Si ce n'est pas dans vos cordes :@ ne soyez pas sot!$",
+ "Avant la mise en pi\212ce !$",
+ "Gros plan sur :$",
+ "Vous remarquez particuli\212rement...$",
+ "Et encore...$",
+ "C'est fini !$",
+ "Un peu de lecture$",
+ "L'aventure vous attend, vous partez...$",
+ "Ne ratez pas VOTRE prochaine AVENTURE...$",
+ "Je ne comprends pas$",
+ "Il y a plus simple$",
+ "Non ! Pas ce coup-ci$",
+ "Trop tard$",
+ "$",
+ "Comme un regard profond tout couvert de peaux-pierres, pointant son oeil obscur aux astres de lumi\212re, il est la gorge reliant le ciel et les enfers . Il faut aller au fond de cette art\212re comme un rat au coeur m\210me de la terre !@Lundi, Mardi, Mercredi, Dimanche du 1e lundi au 1e dimanche, tu installeras \"ce rat\" entre chacun des jours . N'omets rien car ta venue serait ta retenue !@Porte ton fardeau comme un oeuf nouveau et donne lui le jour avec force et amour.$",
+ "10/1/50: Nous avons r\202solu le myst\212re du manuscrit et localis\202 la crypte . Est-ce l'id\202e d'aboutir dans ce qui n'\202tait qu'un \"r\212ve\" qui me rend si anxieuse ?@Je regrette de m'\210tre engag\202e vis \205 vis de L\202o . Non! je dois continuer ! J'aurais d\227 mettre Guy au courant... mais, depuis une semaine, je n'ai aucune nouvelle .$",
+ "Porte ta pri\212re au lieu saint qui se doit, changes-en l'air, tu auras la mati\212re !@Du pilier de la haute sagesse, le soleil aux genoux te montrera l'espace par lequel ton \205me s'ouvrira un chemin et gagnera son \212re . Avance comme un Orph\202e peu soucieux des t\202n\212bres : le blanc est ta couleur, l'or ta demeure . Eclaire ton chemin jusqu'\205 la myst\202rieuse . Offre-lui le cercle de l'homme aux trois facettes . Qu'il regagne le monde et qu'il tourne avec lui dans la richesse premi\212re.$",
+ "Les montagnes sont les crocs d'une gueule dantesque ouverte \205 l'infini de quelqu' orgie c\202leste, mastiquant des \202toiles comme nous broyons du noir .@Tu d\202poseras l'accord de pierre \205 tes pieds, le rire du silence sur la gamme d'en haut et dans ta main droite, une toile d'un m\212tre . Tu passeras ainsi entre les deux croissants, par del\205 les ab\214mes du Mur du Silence . La Cl\202 des champs est \205 ta port\202e, tu n'as qu'\205 retrouver la note qui d\202note.$",
+ " DECEMBRE@ 9 REMISE 518 13 AGIOS 23@ 19 VIREMENT 1203 17 TRESOR 1598@ TOTAL 1721 TOTAL 1721$",
+ " Le 5/01/51@@ Luc, mon amour@ Guy conna\214t notre liaison . A la suite d'une dispute, je lui ai tout dit . Je ne pense qu'\205 toi ! Max me relance mais j'ai d\202finitivement rompu avec lui . Qu'il reste \205 ses gamelles . Quand pourrons-nous nous voir seuls ? Pour toi je divorcerai... Je t'aime .@ ton Eva$",
+ " Mortevielle, le 10/2/51@@ Pat,@ Je te rappelle que tu me dois 50000 F que je t'ai pr\202t\202s pour ton affaire . J'en ai besoin, peux-tu me les rendre assez vite?@ Guy$",
+ " Mortevielle, le 15/2/51@ Ma\214tre,@ Je vous \202cris au sujet de notre affaire. Je suis d\202cid\202 \205 aller jusqu'au bout, certain que mon associ\202, Pat DEFRANCK, a falsifi\202 un livre de comptes . Malgr\202$",
+ " Une pipe$",
+ " Un stylo \205 plume$",
+ " Un briquet \205 essence$",
+ " Une cornue$",
+ " Un blaireau$",
+ " Un pot de peinture$",
+ " Une flute$",
+ " Une bague de valeur$",
+ " Une bobine de fil$",
+ " Un vieux bouquin$",
+ " Un porte-monnaie$",
+ " Un poignard$",
+ " Un r\202volver$",
+ " Une bible$",
+ " Une bougie$",
+ " Un coffret \205 bijoux$",
+ " Un fer \205 repasser$",
+ " Une photo$",
+ " Une montre \205 gousset$",
+ " Une corde$",
+ " Des clefs$",
+ " Un collier de perles$",
+ " Un flacon de parfum$",
+ " Des jumelles$",
+ " Des lunettes$",
+ " Une bourse en cuir$",
+ " Une balle de tennis$",
+ " Des munitions$",
+ " Un rasoir \205 main$",
+ " Une brosse \205 cheveux$",
+ " Une brosse \205 linge$",
+ " Un jeu de cartes$",
+ " Un chausse pied$",
+ " Un tournevis$",
+ " Un marteau$",
+ " Des clefs$",
+ " Des clefs$",
+ " Un cendrier$",
+ " Un pinceau$",
+ " Une corde$",
+ " Un objet en bois$",
+ " Des somnif\212res$",
+ " Une bague en or$",
+ " Un coffret \205 bijoux$",
+ " Un r\202veil matin$",
+ " Une cotte de mailles$",
+ " Un chandellier$",
+ " Une paire de gants$",
+ " Une coupe cisel\202e$",
+ " Un parchemin$",
+ " Un poignard$",
+ " Un dossier$",
+ " Un parchemin$",
+ " Un parchemin$",
+ " Un dossier$",
+ " Un dossier$",
+ " Une lettre$",
+ " Un roman$",
+ " Une baguette en bois$",
+ " Une enveloppe$",
+ " Une lettre$",
+ " Une enveloppe$",
+ "Julia$",
+ "La mort de Julia$",
+ "Les relations de Julia$",
+ "Un message de Julia$",
+ "L'h\202ritage de Julia$",
+ "Derniers actes de Julia$",
+ "Les cadeaux de Julia$",
+ "La chambre de Julia$",
+ "La photo chez Julia$",
+ "Julia et vous...$",
+ "Les occupations de L\202o$",
+ "Les occupations de Pat$",
+ "Les occupations de Guy$",
+ "Les occupations de Bob$",
+ "Les occupations d'Eva$",
+ "Les occupations de Luc$",
+ "Les occupations d'Ida$",
+ "Les occupations de Max$",
+ "Vos occupations$",
+ "Les relations de L\202o$",
+ "Les relations de Pat$",
+ "Les relations de Guy$",
+ "Les relations de Bob$",
+ "Les relations d'Eva$",
+ "Les relations de Luc$",
+ "Les relations d'Ida$",
+ "Les relations de Max$",
+ "Vos relations$",
+ "Murielle$",
+ "Les relations de Murielle$",
+ "Murielle et vous...$",
+ "Disparition de Murielle$",
+ "Le mur du silence$",
+ "Les manuscrits$",
+ "Le blason$",
+ "Les gravures dans la cave$",
+ "Le puits$",
+ "Les passages secrets$",
+ "La chapelle$",
+ "Les tableaux$",
+ "La photo du grenier$",
+ "Le corps dans la crypte$",
+ "$",
+ "$",
+ "FIN DE LA CONVERSATION$",
+ "Les vieux appelaient ainsi la chaine de montagne qui se dresse au pied du manoir !$",
+ "C'est le massif montagneux que l'on aper\207oit devant le manoir$",
+ "Je n'en sais rien !$",
+ "Elle est morte d'une embolie pulmonaire$",
+ "Ma m\202re est morte soudainement . Son \202tat semblait pourtant s'\210tre am\202lior\202$",
+ "Madame DEFRANCK est morte d'un coup de froid$",
+ "Elle est morte d'une embolie pulmonaire$",
+ "Pardonnez moi mais je pr\202f\212re, actuellement garder le silence$",
+ "Ce sont toujours les meilleurs qui partent les premiers$",
+ "J'aimais beaucoup ma m\212re . Je regrette seulement qu'elle soit morte dans le manoir des DEFRANCK$",
+ "C'est une r\202gion qui a un pass\202 charg\202 et j'ai largement de quoi m'occuper . Et puis j'aime beaucoup les chevaux..$",
+ "C'est un passionn\202 d'histoire et un joueur inv\202t\202r\202 . D'ailleurs, voici un an il a gagn\202 une grosse somme$",
+ "Il a d\202j\205 beaucoup a faire avec la gestion et l'entretien du manoir...$",
+ "Je suis PDG d'une petite soci\202t\202 de parfums . Mais quand je suis ici, je me repose$",
+ "C'est un homme dynamique qui a r\202ussi dans le parfum$",
+ "Lui ! C'est un arriviste v\202reux ! Les parfums ont du endormir son bon sens . D'ailleurs ici il passe ses soir\202es dans sa chambre$",
+ "J'ai \202t\202 tr\212s pr\202occup\202 par la sant\202 de ma m\212re, et maintenant je n'ai plus go\226t \205 rien$",
+ "Il aurait mieux fait de s'occuper un peu plus de moi et un peu moins de sa m\212re$",
+ "Ce sont ses affaires...$",
+ "Il n'a pas trop de chance en ce moment bien que ses affaires soient satisfaisantes$",
+ "Je travaille avec Pat mais \207a ne va pas tr\212s fort en ce moment$",
+ "Ah oui ?! Il a des occupations ? Il ferait bien de s'en occuper s\202rieusement alors$",
+ "Lui et Pat sont associ\202s . Je crois que \207a ne va pas trop mal$",
+ "Je m'occupe de moi et c'est d\202j\205 beaucoup . Et vous ?$",
+ "Oh \207a ! Je lui fais confiance . Elle sait s'occuper$",
+ "Mais ! Vous n'avez pas encore d\202couvert son occupation principale..?$",
+ "Elle fait dans la d\202coration avec beaucoup dego\226t d'ailleurs. Elle est toujours tr\212s bien habill\202e$",
+ "Si les bijoux vous interessent, j'ai quelques affaires interessantes \205 saisir rapidement$",
+ "Les bijoux...$",
+ "Je ne sais pas, mais j'aimerais bien qu'il s'occupe un peu moins de mes affaires !$",
+ "Quand on est une femme d'int\202rieur on trouve toujours de quoi s'occuper...$",
+ "Elle pourrait rester sans rien faire, mais non ! Elle coud, elle lit ...$",
+ "Elle n'a s\226rement pas des occupations tr\212s \202panouissantes ...$",
+ "Une femme comme il n'y en a plus : Elle s'interesse a tout !$",
+ "Entre la cuisine et le m\202nage, je n'ai pas beaucoup de temps \205 vous accorder$",
+ "Je ne sais pas comment il s'y prend pour tout faire . C'est merveilleux !$",
+ "Il en ferait plus si il s'occupait moins des rag\223ts et de la bouteille$",
+ "Je suis tr\212s ind\202pendant . Tant qu'on ne s'occupe pas de mes affaires : Pas de probl\212me$",
+ "C'est un \202go\213ste . Je me demande si il aime autre chose que ses chevaux et ses grimoires$",
+ "Je crois qu'il s'entend bien avec tout le monde, mis \205 part, peut \210tre, avec Guy$",
+ "C'est un homme de caract\212re . Il faut savoir le prendre ..$",
+ "Les affaires sont les affaires . Quant \205 la famille, je la laisse pour ce qu'elle est ...$",
+ "Relations ? Relations amicales ? Relations financi\212res sans doute$",
+ "Moi je n'ai rien \205 lui reprocher$",
+ "C'est un homme d'affaire d\202brouillard . Il nage parfois \205 contre-courant mais ... il s'en sortira toujours$",
+ "Ils m'ennuient tous .. Non ! Ce n'est m\210me pas \207a .. Quoique .. certains ..$",
+ "A l'inverse de sa m\212re, c'est une personne tr\212s renferm\202e ! Alors question relations ..$",
+ "Il doit sans doute faire beaucoup d'effort pour rester agr\202able malgr\202 tous ses ennuis$",
+ "Ses relations amoureuses : C'est termin\202 . Ses relations avec moi : Pas vraiment commenc\202es . Quant aux autres : Je ne suis pas les \"autres\"$",
+ "J'aime bien tout le monde, tant qu'on ne m'escroque pas$",
+ "Il ne suffit pas d'avoir un peu d'argent et d'\210tre beau parleur pour plaire \205 tout le monde$",
+ "Sans histoire .. C'est quelqu'un d'agr\202able et g\202n\202reux . De plus, il ne manque pas d'humour$",
+ "Actuellement je m'entends plut\223t bien avec tout le monde . Mais, ici, je ne vais pas m'\202tendre sur le sujet$",
+ "Beau plumage, mais \207a ne vole pas haut ... Parlez en \205 son mari$",
+ "C'est pour un rendez-vous ?$",
+ "Elle est tr\212s vivante ! Elle ne s'embarrasse pas de pr\202jug\202s stupides$",
+ "Dans mon m\202tier, on c\223toit surtout des belles femmes et des truands$",
+ "La seule valeur s\226re chez lui, c'est ses bijoux .. Et sa femme, mais \207a il ne s'en rend pas compte$",
+ "C'est quelqu'un d'interessant . De pas toujours facile \205 comprendre, mais qui m\202rite le d\202tour$",
+ "Je ne d\202teste personne, mais j'aime les choses et les gens quand ils sont \205 leur place$",
+ "C'est entre nous . Mais voyez : quand je parle avec elle, je me sens vite \205 l'\202troit !$",
+ "Pour ne pas s'entendre avec elle, faut y mettre de la mauvaise volont\202$",
+ "Vous savez dans mon m\202tier on entend tout mais on ne retient rien, et le service est bien fait$",
+ "C'est un hypocrite, un larbin ! Personnellement je ne lui fais pas confiance$",
+ "Je ne connait pas le fond de sa pens\202e mais c'est quelqu'un de toujours tr\212s correct et impeccable$",
+ "C'\202tait une personne qui a v\202cu au manoir, il y a un an .. peut \210tre plus$",
+ "C'\202tait plus qu'une amie pour ma m\212re . En ces moments, j'aurais aim\202 qu'elle soit \205 mes cot\202s$",
+ "Murielle a \202t\202 la dame de compagnie de Julia$",
+ "Elle aussi, faisait des recherches ...$",
+ "C'\202tait une femme tr\212s cultiv\202e . Son brusque d\202part, il y a un an, m'a surpris et beaucoup chagrin\202$",
+ "Elle partageait avec L\202o sa passion de l'histoire et de la r\202gion$",
+ "Je crois que tout le monde l'aimait bien$",
+ "Elle s'entendait bien avec tout le monde . Elle aimait beaucoup son fils . Quant aux relations belle-m\212re, belle-fille ..$",
+ "A part L\202o, elle avait de tr\212s bon rapport avec Max ...$",
+ "Bien que vos relations furent peu soutenues, J\202r\223me, elle vous portait toujours dans son coeur ...$",
+ "A part sa famille, pas grand monde$",
+ "Ah oui ! Je crois qu'elle a beaucoup regrett\202 le d\202part de cette amie .. euh ! Marielle .. ou Mireille ...$",
+ "Non rien !$",
+ "Non ... Pas que le sache$",
+ "J'ai connu Julia en achetant le manoir . C'\202tait son seul bien . Mais toute ma fortune \202tait la sienne ...$",
+ "Si ce n'est quelques objets personnels, je crois qu'elle n'avait plus rien \205 elle$",
+ "Je crois que toute sa fortune venait de L\202o . Alors, Pfuuut !$",
+ "A part la lettre pour vous que j'ai post\202, rien de bien important !$",
+ "J'ai \202t\202 tr\212s heureuse qu'elle m'offre sa bible reli\202e$",
+ "Ca a \202t\202 rapide et elle n'a pas eu le temps de prendre des dispositions particuli\212res$",
+ "Son dernier pr\202sent m'a surpris$",
+ "Quel cadeau ?$",
+ "Un chandellier ...$",
+ "Oui, j'ai eu un cadeau . Ma femme a m\210me eu une bible$",
+ "Et bien oui ! Comme tout le monde, je crois$",
+ "Un poignard$",
+ "Je n'ai jamais \202t\202 fouiller dans le grenier !$",
+ "Vous avez un don de double-vue ou un passe-partout$",
+ "Le portrait d'une jeune fille : C'est Murielle ...$",
+ "Vous savez, je la connaissais assez peu$",
+ "Elle \202tait tr\212s charmante, mais c'\202tait surtout la dame de compagnie de Julia$",
+ "C'est la seule femme vraiment interessante que j'ai rencontr\202$",
+ "Elle avait de grandes connaissances historiques, et la consulter \202tait tr\212s enrichissant$",
+ "Je me suis toujours demand\202 ce que certains pouvaient lui trouver !$",
+ "Si la chambre est ferm\202e, demandez \205 L\202o$",
+ "J'ai ferm\202 sa chambre apr\212s sa mort et j'aimerais qu'il en soit ainsi encore un certain temps$",
+ "Vous savez ce que c'est : Des relations familiales$",
+ "Durant toutes ces ann\202es, je ne l'ai jamais servie \205 contre-coeur$",
+ "Je l'aimais autant qu'elle m'aimais, je crois$",
+ "De quel droit avez-vous p\202n\202tr\202 dans la chambre de ma femme ?!!$",
+ "C'est sans doute la photo de Murielle avec le filleul de Julia$",
+ "Je ne me rappelle pas$",
+ "C'est Murielle . C'est moi qui l'ai prise. et d'ailleurs elle est tir\202e \205 l'envers$",
+ "Vous \210tes bien curieux !... C'est sans valeur$",
+ "Grimoires, parchemins et manuscrits : C'est le domaine de L\202o$",
+ "Dommage que la devise soit manquante ...$",
+ "C'est tr\212s beau ... Et tr\212s vieux ...$",
+ "Tiens ! C'est un endroit que je n'ai jamais visit\202$",
+ "D'apr\202s L\202o, il semblerait que les Lunes soient plus r\202centes$",
+ "M\210me par ce temps, vous avez d\202nich\202 un soleil ...$",
+ "Profond et inqui\202tant : Le progr\212s a du bon$",
+ "Ca reste pour moi le plus grand des myst\212res$",
+ "Les derniers temps elle parlait d'un voyage . Et puis ...$",
+ "Il y a un peu plus d'un an, un soir, elle a d\202cid\202 de partir ...$",
+ "De toutes fa\207ons elle n'\202tait pas faite pour vivre ici$",
+ "Quoi ?! Quel corps ? Quel crypte ?$",
+ "Si il y en a, je ne les ai jamais trouv\202 ...$",
+ "Bien s\226r ! ... Et des fant\223mes aussi ...$",
+ "C'est la plus vielle de la r\202gion : Elle date du XI eme si\212cle$",
+ "Elle fut l\202g\212rement restaur\202e apr\212s la r\202volution$",
+ "Julia aimait beaucoup la peinture$",
+ "Ils ont diff\202rents styles, mais n'ont pas tous une tr\212s grande valeur$",
+ "Que faites-vous l\205 ?$",
+ "Je suis s\226r que vous cherchez quelque chose ici$",
+ "Je vous \202coute$",
+ "Que d\202sirez-vous ?$",
+ "Oui ?$",
+ "Je suis \205 vous ...$",
+ "C'est pourquoi ?$",
+ "Allez-y$",
+ "C'est \205 quel sujet ?$",
+ "Max : \205 votre service, monsieur$",
+ "De toutes fa\207ons vous n'avez rien \205 faire ici ! Sortez !!$",
+ "Vous \210tes trop curieux !$",
+ "J\202r\223me ! Il y a longtemps ... Quelle tristesse, Julia est morte . Sa famille est ici : Guy, son fils . Eva, sa brue . L\202o, son mari bien s\226r . Son beau fils, Pat . Des cousins : Bob, Ida, Luc . La temp\212te redouble, il vous faut rester . Les repas sont \205 12h et 19h et il y a un recueillement \205 la chapelle tous les jours \205 10h$",
+ "En vous voyant j'ai compris que vous decouvririez la v\202rit\202 ... Car je savais pourquoi vous veniez : J'avais retrouv\202 le brouillon de la lettre de Julia . Mais je suis tr\212s joueur, alors ... Elle n'avait pas voulu que votre t\203che soit trop facile, pour me prot\202ger, sans doute, mais elle n'a pu mourir avec cette incertitude sur la conscience . Avez vous d\202couvert que le mur du silence est le nom que les ma\207ons ont donn\202 au mur qui porte ce blason, lors de la construction du manoir ? .. Et ces cadeaux que Julia a laiss\202 avant de mourir \202taient autant de faux indices qui ne servaient qu'\205 faire ressortir l'importance des parchemins ... Effectivement, il y a plus d'un an, je travailais avec Murielle au d\202cryptage de ces manuscrits que je venais de trouver . Ma femme a fait la relation entre notre travail et la disparition de Murielle mais elle n'a jamais eu de preuves . Si ce n'est cette bague qu'elle a retrouv\202 un jour dans mes affaires . Une nuit, nous nous sommes aventur\202s dans le passage secret que nous avions d\202couvert . Murielle est morte par accident dans la pi\212ce de la vierge . J'ai r\202cup\202r\202 la bague rapidement, trouv\202 le tr\202sor et me suis enfuis . Je ne pensais pas qu'elle vivait encore, et je n'ai rien dit car j'avais besoin d'argent . J'ai fait passer cette somme sur le compte des courses de chevaux ...Partez maintenant, puisque vous n'\210tes pas de la police . Laissez moi seul !$",
+ "F\202vrier 1951 ... Profession : detective priv\202 . Le froid figeait Paris et mes affaires lorsque ...$",
+ "Une lettre, un appel, des souvenirs d'une enfance encore proche . Que de jeux dans les pi\212ces d\202labr\202es du manoir de Mortevielle . Julia, une vieille femme a pr\202sent .$",
+ " au bureau$",
+ " \205 la cuisine$",
+ " \205 la cave$",
+ " dans le couloir$",
+ " dehors$",
+ " la salle \205 manger$",
+ " dans le manoir$",
+ " devant le manoir$",
+ " \205 la chapelle$",
+ " devant le puits$",
+ " au nord$",
+ " derri\212re le manoir$",
+ " au sud$",
+ " \205 l'est$",
+ " \205 l'ouest$",
+ " vers le manoir$",
+ " plus loin$",
+ " dans l'eau$",
+ " hors du puits$",
+ " dans le puits$",
+ " choix sur \202cran$",
+ " Dans la serie MYSTERE...$",
+ " LE MANOIR DE MORTEVIELLE$",
+ "$",
+ " Sur une idee de...$",
+ " Bernard GRELAUD et Bruno GOURIER$",
+ "$",
+ " Realisation: LANKHOR$",
+ "$",
+ " Avec la participation de...$",
+ " Beatrice et Jean-Luc LANGLOIS$",
+ " pour la musique et les voix,$",
+ " Bernard GRELAUD pour la conception graphique,$",
+ " MARIA-DOLORES pour la realisation graphique,$",
+ " Bruno GOURIER pour la realisation technique,$",
+ " Clement ROQUES pour l'adaptation sur IBM PC et compatibles .$",
+ "$",
+ " Edition: LANKHOR$",
+ " COPYRIGHT 1988: LANKHOR$",
+ "$",
+ " A VOUS DE JOUER$",
+ " attacher$",
+ " attendre$",
+ " d\202foncer$",
+ " dormir$",
+ " \202couter$",
+ " entrer$",
+ " fermer$",
+ " fouiller$",
+ " frapper$",
+ " gratter$",
+ " lire$",
+ " manger$",
+ " mettre$",
+ " ouvrir$",
+ " prendre$",
+ " regarder$",
+ " sentir$",
+ " sonder$",
+ " sortir$",
+ " soulever$",
+ " tourner$",
+ " se cacher$",
+ " fouiller$",
+ " lire$",
+ " poser$",
+ " regarder$",
+ " L\202o$",
+ " Pat$",
+ " Guy$",
+ " Eva$",
+ " Bob$",
+ " Luc$",
+ " Ida$",
+ " Max$",
+ "Comment Julia est-elle morte ?$",
+ "Elle s'est suicid\202e$",
+ "Elle est morte assassin\202e$",
+ "Elle est morte accidentellement$",
+ "Elle est morte naturellement$",
+ "D'o\227 provenait l'argent qui a permis la restauration du manoir ?$",
+ "chantage$",
+ "travail$",
+ "h\202ritage$",
+ "courses$",
+ "rentes$",
+ "hold-up$",
+ "d\202couverte$",
+ "Quel est le hobby de L\202o ?$",
+ "recherches historiques$",
+ "politique$",
+ "peinture$",
+ "drogue$",
+ "sciences occultes$",
+ "direction d'une secte$",
+ "Julia a laiss\202 une s\202rie d'indices . Ceux-ci sont repr\202sent\202s en un seul lieu . Lequel ?$",
+ "Chapelle$",
+ "Ext\202rieur$",
+ "Cave$",
+ "Grenier$",
+ "Cuisine$",
+ "Salle \205 manger$",
+ "Chambre Julia$",
+ "Chambre L\202o$",
+ "Chambre Pat$",
+ "Chambre Bob$",
+ "Chambre Max$",
+ "Chambre Luc/Ida$",
+ "Chambre Guy/Eva$",
+ "L'indice principal qui vous a permis d'arriver \205 la porte du souterrain est :$",
+ "Un poignard$",
+ "Une bague$",
+ "Un livre$",
+ "Un parchemin$",
+ "Une lettre$",
+ "Un pendule$",
+ "Combien y avait-il de parchemin dans le manoir ?$",
+ "Aucun$",
+ "Un seul$",
+ "Deux$",
+ "Trois$",
+ "Quatre$",
+ "Cinq$",
+ "Combien de personnes sont m\202l\202es \205 cette histoire - Julia y comprise, vous except\202 - ?$",
+ "Neuf$",
+ "Dix$",
+ "Onze$",
+ "Quel \202tait le pr\202nom de la personne inconnue ?$",
+ "Mireille$",
+ "Fran\207oise$",
+ "Maguy$",
+ "Emilie$",
+ "Murielle$",
+ "Sophie$",
+ "De qui Murielle \202tait-elle la ma\214tresse ?$",
+ "Bob$",
+ "Luc$",
+ "Guy$",
+ "L\202o$",
+ "Max$",
+ "Murielle partageait une occupation avec une autre personne . Qui ?$",
+ "[1][ |Seul le hazard vous a permis d'arriver ici . Vous pr\202f\202rez|retourner enqu\202ter afin de mieux comprendre ...][ok]$",
+ "[1][ |Ins\202rez la disquette 1 dans le lecteur A][ok]$",
+ "[1][ |! ERREUR DISQUETTE !|On arrete tout][ok]$",
+ "[1][ |Vous devriez avoir remarqu\202|00% des indices][ok]$",
+ "[1][ |Ins\202rez la disquette 2 dans le lecteur A][ok]$",
+ "[1][ |Avant d'aller plus loin, vous faites|un point sur l'\202tat de vos connaissances][ok]$",
+ " MASTER .$",
+ " rorL$",
+};
+
+const char *gameDataDe[] = {
+ "Ruhe vor dem Sturm$",
+ "Geschmacklose Farben$",
+ "Lila, der letzte Versuch$",
+ "Diesen Ort bitte sauberhalten...$",
+ "Beaengstigendes schwarzes Loch$",
+ "Der blaue Salon$",
+ "Das blutrote Zimmer$",
+ "Wassersport$",
+ "Der gruene Star$",
+ "Ein Auge aufs Verbotene werfen$",
+ "Geruch von Kaminfeuer und Tabak$",
+ "Tabak und alte Buecher$",
+ "Zwiebeln, Zimt und Spirituosen$",
+ "Ein wenig besuchter Ort$",
+ "Feuchtigkeit und Moder$",
+ "Hausieren verboten!$",
+ "Ein verwester Koerper: toedliche Kryptomanie!$",
+ "Da wird einem angst$",
+ "Es ist schon offen$",
+ "Achtung: Lawinen$",
+ "Ein Hauch von \"Heiligkeit\"$",
+ "Eine grosses eindrucksvolles Gemaeuer...$",
+ "Die Kehrseite des Geheimnisses!$",
+ "Ein merkwuerdiges Horoskop!$",
+ "Der Krug geht so lange...$",
+ "Eine Eichentuer$",
+ "Ein Foto$",
+ "Die Wappen$",
+ "$",
+ "Max, der Diener, empfaengt Sie und wird Sie dann in Ihr Zimmer begleiten$",
+ " Morteville 16/2/51@ Mein lieber Jer\223me@Im Anschluss an mein Telegramm teile ich Ihnen die Gruende meiner Unruhe mit: vor 1 Jahr verschwand meine Gesellschafterin Murielle. Eventuell hat das Verschwinden etwas mit dem finanziel len Umschwung auf dem Landsitz zu tun, oder... Eine Stille, die schwer zu verstehen ist fuer mei-nen Sohn Guy. Da ich bis heute nichts bezueglich dieser Sache unternehmen konnte, zaehle ich auf Sie, um die Affaere zu regeln. Falls sich mein Gesundheitszustand nicht bessert, treffen Sie bitte die Entscheidungen, die Sie fuer richtig halten. @ In Freundschaft. JULIA DEFRANCK$",
+ "Spaeter erzaehlt Ihnen Guy von Leo's Selbstmord nach einer verrueckten Wette beim Rennen!$",
+ "F3: WIEDERHOLUNG@F8: STOP$",
+ "Der Hausherr$",
+ "Der Zukuenftige Erbe$",
+ "Julias Sohn$",
+ "Ein niedliches Maedchen!$",
+ "Superman!$",
+ "Der Mann von Ida$",
+ "Interessante Aeusserungen?$",
+ "Service inbegriffen!$",
+ "Nichts darunter!$",
+ "Kein Mucks...$",
+ "Eine halbe Stunde spaeter: nichts! Warten Sie immer noch?$",
+ "Bewundern Sie! Denken Sie nach!$",
+ "Nein! Nichts!$",
+ "Unmoeglich$",
+ "Das macht Flecken!$",
+ "Eine Abhandlung ueber die Geschichte der Gegend$",
+ "Einige Muenzen$",
+ "Erstes Gebot...$",
+ "Das riecht gut!$",
+ "Pik, Herz...$",
+ "Es mangelt nicht an Pillen!$",
+ "Ein Liebesroman$",
+ "Pusten heisst noch nicht spielen$",
+ "Kein Erfolg!$",
+ "Vorsicht vor Ueberraschungen!$",
+ "Dunkel und tief...$",
+ "Normale Gefuehle$",
+ "Sniff!$",
+ "Unverschaemt! Begnuegen Sie sich mit anschauen!$",
+ "Gesundheit! St... Staub$",
+ "Das Bild ist unterzeichnet... aber nicht die Tapeten$",
+ "Kein Glueck, Nichts!$",
+ "Seien Sie diskreter!$",
+ "Die Vorhaenge sind geschlossen$",
+ "Schnee! Und noch mehr Schnee!$",
+ "Genial: ein Bild vom Meister!$",
+ "Kein Zweifel, das ist eine Faelschung!$",
+ "Hum! Sie stutzen - Antikes oder Schund?$",
+ "Ein selten wertvolles Stueck!$",
+ "Nichts Bemerkenswertes$",
+ "Waesche, persoenliche Objekte...$",
+ "Nicht irgendwo!$",
+ "Das ist nicht der Zeitpunkt!$",
+ "Man spricht nicht mit vollem Mund! Nenn erst einmal das essen beendet ist$",
+ "Jemand kommt rein, beeilt sich und geht wieder raus$",
+ "Man naehert sich Ihrem Versteck!$",
+ "Man ueberrascht Sie!$",
+ "Unmoeglich! Sie sind ueberlastet!$",
+ "Versuchen Sie es aufs neue$",
+ "Sie sind perplex!?$",
+ "Sie verlassen Morteville. In Paris erwartet Sie eine Nachricht...$",
+ "Sie tun sich weh!$",
+ "Nichts weiteres mehr hier$",
+ "Der Ton erscheint normal$",
+ "Es bewegt sich nicht$",
+ "Man antwortet Ihnen$",
+ "Nicht der Augenblick!$",
+ "Gleiches Material, andere Seite!$",
+ "Der Widerschein ist fleckig, aber der Rahmen ist aus Gold$",
+ "Nippsachen, wertlose Dinge...$",
+ "Sie erleiden einen Misserfolg!$",
+ "Hier stinkt es... Besser nicht anschauen!$",
+ "Haushaltsprodukte$",
+ "Da juckt Ihnen das Fell?$",
+ "Das ist esklemmt, zugefroren! Brrrr...$",
+ "Die Fensterrahmen sind blockiert!$",
+ "Papiere...$",
+ "Nein! Der Weihnachtsmann hat keine Schwierigkeiten!$",
+ "Da geht es auf einen Flur$",
+ "Geschirr, Silber...$",
+ "Nein! Das sind nicht die Reste von Julia!$",
+ "Eine alte Gravur$",
+ "Sie entdecken eine tiefe rhombenfoermige Oeffnung$",
+ "Die Mauer gleitet zur Seite! Eine Passage! Benutzen Sie sie?$",
+ "Der Durchgang schliesst sich$",
+ "Eine Geheimschublade. Ein Buechlein... Lesen Sie es?$",
+ "Die Schublade schliesst sich wieder$",
+ "Nichts! Blut und Haut kleben am Stein!$",
+ "Die Details lassen Sie darauf schliessen, dass der Tod nicht unmitte lbar eingetreten ist!$",
+ "Verdorbene Vorhaben?$",
+ "Hing ihr Leben an einem \"Finger\"?$",
+ "Ein Schatz sei verschwunden?$",
+ "Eine Ritze in Groesse einer Muenze!$",
+ "Einige Steine bewegen sich... Eine Krypta! Gehen Siehinein?$",
+ "Der Ring dreht sich, die Mauer schliesst sich wieder$",
+ "Eine Steinsaeule hinter dem Altar$",
+ "Es war laut...$",
+ "Besetzt!$",
+ "Versuchen Sie noch einmal Ihr Glueck?$",
+ "Zu tief!$",
+ "Die Mauer am Ende des Ganges dreht sich$",
+ "Nothing!$",
+ "Der einzigue!$",
+ "Das Objekt faellt hinunter...$",
+ "Sie haben nichts in den Haenden$",
+ "Es ist nicht offen$",
+ "Das ist schon etwas$",
+ "Die Tuer ist zu$",
+ "Keine Antwort$",
+ "Eine volle Holzkugel$",
+ "Es ist kein Platz mehr$",
+ "Eine, in der Mitte durchbohrte, Holzkugel$",
+ "? ?$",
+ "Sie sind dran!$",
+ "OK!$",
+ "Ploetzlich erscheint Max mit Ihrem Koffer : \"Danke fuer Ihren Besuch\" Privatdetektiv mit gutem Gespuer und zweifellos diskret. Demoralisiert verlassen Sie den Landsitz. Sie sind UNBEDEUTEND!$",
+ "Leo unterbricht Sie:\"Das Unwetterhat sich beruhigt. In 1 Stunde gehe ich in die Stadt. Halten Siesich bereit.\" Sie haben Zeit verloren...aber noch nicht das Leben$",
+ "Hochrotes Gesicht, fatale Grippe.Sie bleiben da. Ihre Nachforschun gen fallen ins Wasser$",
+ "Das Wasser steigt sehr schnell und daempft Ihre letzten Illusionen ... Bevor Sie Zeit haben, zu reagiren, sind Sie tot!$",
+ "Sie sind kaum auf dem Grund des Brunnens, als eine Hand das Seil durchschneidet. Leben, adieu!$",
+ "Der Sturm verwischt Ihre Spuren. Eine Mauer des Schweigens huellt Sie ein. Langsam sterben Sie den Erfrierungstod!$",
+ "Sie sind nicht so allein wie Sie denken. Eine kalte Klinge bohrt sich in Ihren Ruecken. Seien Sie in Zukunft vorsichtiger!$",
+ "Sie ignorieren die Schuld von Leoam Tode Murielles. War sie sofort tot? Auf jeden Fall gerechtfertigen die familiaeren Probleme, die waehrend Ihrer Untersuchung aufgedeckt wurden, die Haltung Leos. Sie sind nicht sicher, ob Julia Sie deswegen angerufen hat, aber es genuegt Ihnen. Aus Respekt fuer sie und nach einigen Vorsichtsmassnahmen, fuehren Sie ein aufschlussreiches Gespraech mit Leo.$",
+ "$",
+ "Sie haben keinen Schluessel fuer den Landsitz. Ihre Rufe bleiben ohne Antwort. Sie werden sterben.$",
+ "Mit einem fuerchterlichen Rundschlag spaltet Sie das Schwert entzwei - das Innere kehrt sich nach aussen.$",
+ "Home, Sweet home!$",
+ "Geheimnis einer geschlossenen Tuer$",
+ "Charme verzaubert die alten Zimmer$",
+ "Leerer Magen$",
+ "Naeher 'gen Himmel? Nicht sicher!$",
+ "Angst vorm Dunkeln?$",
+ "Alte Teppiche und Goldschimmer$",
+ "Angst!$",
+ "Gerettet? Nicht sicher!$",
+ "Man fuehlt sich unwohl, was!$",
+ "Immer noch weiter!$",
+ "Ihr Kreuzweg!$",
+ "Bei der Entdeckung von...$",
+ "Achtung, auf das was sich versteckt...$",
+ "Abstieg in die Hoelle!$",
+ "Na fuehlen Sie sich gut? Sie sehen etwas@ blass aus!$",
+ "Vor dem Eintreten!$",
+ "Zoom:$",
+ "Unter anderem bemerken Sie...$",
+ "Und noch mal...$",
+ "Es ist zu Ende!$",
+ "Ein wenig Lektuere$",
+ "Das Abenteuer wartet auf Sie: also los!$",
+ "Verpassen Sie nicht IHR naechstes ABENTEUER!$",
+ "Ich verstehe nicht$",
+ "Es gibt Einfacheres$",
+ "Nein! Nicht Diesmal$",
+ "Zu spaet$",
+ "$",
+ "Wie ein tiefer verschleierter Blick, sein lebloses Auge auf die Sterne gerichtet, ist er wie der Schlund, der Himmel und Hoelle verbindet. Du musst in diese Tiefe vordringen, so wie eine Ratte in die Erde. Montag, Dienstag, Mittwoch, Sonntag, vom 1. Montag bis zum 1. Sonntag -so wird jeder Tag durch das SEIN oder WERDEN bestimmt. Vebersieh nichts, denn sonst ist Dein Schicksal besiegelt.$",
+ "10/1/50: Wir haben das Mysterium des Manuskriptes geloest und die Krypta lokalisiert. Ist es der Gedanke, in diesem Traum mein Ziel zu erreichen, der mir so angst macht? Ich bedauere, dass ich mich gegenueber Leo so engagiert habe. Nein, ich muss weitermachen Ich haette Guy informieren muessen, aber ich habe seit einer Woche nichts mehr von ihm gehoert$",
+ "Trag deine Bitte an den heiligen Ort - so wirst Du mehr erfahren! Der Pfeiler der Weisheit und die Sonne an den Knien werden Dir die Stelle zeigen , die Deiner Seele den Weg in eine neue Welt oeffnen Vorwaerts Orpheus, ohne Angst vordem Ungewissen: Weiss ist Deine Farbe, Gold ist Dein Zuhause. Be-leuchte Deinen Weg, bis hin zur traurigen Jungfrau. Gib ihr den Kreis des Mannes mit den drei Gesichtern, auf dass er die Welt wieder erreicht und sich dreht in seinem urspruenglichen Reichtum$",
+ "Die Berge sind die Zaehne eines gigantischen unendlichen Schlundes, einer himmlischen Orgie, die Sterne verschlingend, so wie uns die Dunkelheit verschlingt. Du laesst das Seil der Steine zu Dei nen Fuessen fallen. Das Lachen der Stille und in Deiner rechten Hand das Werk eines Meisters. Anschliessend wirst Du zwischen den beiden Monden hindurchgehen; jenseits des Abgrundes der Mauer des Schweigens wirst Du den Schluessel zur Melodie findenes fehlt nur noch die passende Note...$",
+ " DEZEMBER@ 9 ABZUG 518 13 ZINSEN 23@19 VEBERWE. 1203 17 GUTHAB 1598@ TOTAL 1721 TOTAL 1721@$",
+ " 5/01/51@ Luc, mein Liebling@ Guy weiss von unserer Beziehung.Nach einem Streit habe ich ihm alles gesagt. Ich liebe nur Dich. Max sitzt mir dauernd auf dem Hals, aber ich habe definitiv mitihm gebrochen. Soll er doch bei seinen Toepfen bleiben. Wann koennen wir uns allein sehen? Wegen dir wuerde ich mich scheiden lassen@ Deine Eva$",
+ " Morteville, 10/2/51@ Pat@ Ich erinnere Dich daran, dass Du mir noch FF 5000,- schuldest, die ich Dir fuer Dein Geschaeft geliehen habe. Ich brauche sie jetzt. Kannst Du sie mir bitte moeglichst schnell wiedergeben?@ Guy$",
+ " Morteville, 15/2/51@ Lieber Herr@ Ich schreibe Ihnen unser Geschaeft betreffend. Ich bin entschlossen, bis zum Aeusserstenzu gehen, da ich mir sicher bin, dass mein Teilhaber, Pat Defranck ein Rechnungsbuch gefaelscht hat.$",
+ "Eine Pfeife$",
+ "Ein Fuellfederhalter$",
+ "Ein Gasfeuerzeug$",
+ "Eine Retorte$",
+ "Ein Rasierpinsel$",
+ "Ein Farbeimer$",
+ "Eine Floete$",
+ "Ein wertvoller Ring$",
+ "Eine Garnrolle$",
+ "Ein altes Buch$",
+ "Ein Portemonnaie$",
+ "Ein Dolch$",
+ "Ein Revolver$",
+ "Eine Bibel$",
+ "Eine Kerze$",
+ "Ein Schmuckkoffer$",
+ "Ein Buegeleisen$",
+ "Ein Foto$",
+ "Eine Taschenuhr$",
+ "Ein Seil$",
+ "Schluessel$",
+ "Ein Perlenkollier$",
+ "Ein Parfumflakon$",
+ "Ein Fernglas$",
+ "Eine Brille$",
+ "Ein Ledergeldbeutel$",
+ "Ein Tennisball$",
+ "Munition$",
+ "Ein Nassrasierer$",
+ "Eine Haarbuerste$",
+ "Eine Kleiderbuerste$",
+ "Ein Kartenspiel$",
+ "Ein Schuhanzieher$",
+ "Ein Schraubenzieher$",
+ "Ein Hammer$",
+ "Schluessel$",
+ "Schluessel$",
+ "Ein Aschenbecher$",
+ "Ein Pinsel$",
+ "Ein Seil$",
+ "Ein Gegenstand aus Holz$",
+ "Schlafmittel$",
+ "Ein goldener Ring$",
+ "Ein Schmuckkoffer$",
+ "Ein Wecker$",
+ "Ein Panzerhemd$",
+ "Ein Kerzenhalter$",
+ "Ein Paar Handschuhe$",
+ "Ein Ziselierter Becher$",
+ "Ein Pergament$",
+ "Ein Dolch$",
+ "Ein Dossier$",
+ "Ein Pergament$",
+ "Ein Pergament$",
+ "Ein Dossier$",
+ "Ein Dossier$",
+ "Ein Brief$",
+ "Ein Roman$",
+ "Ein Holzstock$",
+ "Ein Umschlag$",
+ "Ein Brief$",
+ "Ein Umschlag$",
+ "Julia$",
+ "Julias Tod$",
+ "Julias Beziehungen$",
+ "eine Nachricht von Julia$",
+ "Julias Erbschaft$",
+ "letzte Handlungen Julias$",
+ "Geschenk von Julia$",
+ "Julias Zimmer$",
+ "die Fotos bei Julia$",
+ "Julia und Sie...$",
+ "die Geschaefte von Leo$",
+ "die Geschaefte von Pat$",
+ "die Geschaefte von Guy$",
+ "die Geschaefte von Bob$",
+ "die Geschaefte von Eva$",
+ "die Geschaefte von Luc$",
+ "die Geschaefte von Ida$",
+ "die Geschaefte von Max$",
+ "Ihre Geschaefte$",
+ "Leos Beziehungen$",
+ "Pats Beziehungen$",
+ "Guys Beziehungen$",
+ "Bobs Beziehungen$",
+ "Evas Beziehungen$",
+ "Lucs Beziehungen$",
+ "Idas Beziehungen$",
+ "Maxs Beziehungen$",
+ "Ihre Beziehungen$",
+ "Murielle$",
+ "Murielles Beziehungen$",
+ "Murielle und Sie...$",
+ "Murielles Vershwinden$",
+ "Die Mauer des Schweigens$",
+ "Die manuskripte$",
+ "Das Wappen$",
+ "Die Inschriften im Keller$",
+ "Der Brunnen$",
+ "Die Geheimgaenge$",
+ "Die Kapelle$",
+ "Die Bilder$",
+ "Die Fotos vom Dachboden$",
+ "Koerper in der Krypta$",
+ "$",
+ "$",
+ "ENDE DER UNTERHALTUNG$",
+ "Die Alten nannten die Bergkette am Fusse des Landsitzes so.$",
+ "Das ist das Bergmassiv, das man vor dem Landsitz sieht.$",
+ "Ich weiss nichts davon.$",
+ "Sie ist an einer Lungenembolie gestorben.$",
+ "Meine Mutter ist ploetzlich gestorben, obwohl es schien, dass sich ihr Zustand verbesserte.$",
+ "Frau Defranck ist gestorben.$",
+ "Sie ist an einer Lungenembolie gestorben.$",
+ "Verzeihen Sie mir, aber ich ziehe es vor, im Moment Schweigen zu bewahren.$",
+ "Es sind immer die Guten, die als erste gehen muessen.$",
+ "Ich habe meine Mutter sehr geliebt; ich bedauere, dass sie auf dem Gut der Defrancks gestorben ist.$",
+ "Dies ist eine Gegend, die eine sehr bewegte Vergangenheit hat und es gibt genug Dinge, um die ich mich kuemmern kann und ausserdem liebe ich Pferde.$",
+ "Er interessiert sich sehr fuer Geschichte und er ist ein erfolgloser Spieler. Uebrigens hat er vor einem Jahr eine bedeutende Summe gewonnen.$",
+ "Er hat schon viel zu tun mit der Buchhaltung und der Verwaltung des Gutes.$",
+ "Ich bin Direktor einer Parfumfirma. Aber hier... Erholung.$",
+ "Ein dymamischer Mann, der in der Parfumbranche viel erreicht hat.$",
+ "Das ist ein uebler Emporkoemmling. Die Parfums muessen seinen gesunden Menschenverstand eingeschlaefert haben. Hier verbringt er seine Abende in seinem Zimmer.$",
+ "Vorher galt meine Hauptsorge der Gesundheit meiner Mutter. Jetzt finde ich an nichts mehr Gefallen.$",
+ "Er haette gut daran getan, sich ein bisschen mehr um mich zu kuemmern und etwas weniger um seine Mutter.$",
+ "Das sind seine Angelegenheiten.$",
+ "Er hat nicht viel Glueck im Moment, obwohl seine Geschaefte zufriedenstellend sind.$",
+ "Ich arbeite mit Pat. Es geht nicht besonders gut im Moment.$",
+ "Ah ja! Hat er Beschaeftigungen? Er taete besser daran, sich ernsthaft zu beschaeftigen.$",
+ "Er und Pat sind Geschaeftspartner. Ich glaube, es laeuft gar nicht mal schlecht.$",
+ "Ich kuemmere mich um mich und das ist schon genug. Und Sie?$",
+ "Oh, ich vetraue ihr. Sie versteht, sich zu beschaeftigen.$",
+ "Aber haben Sie noch nicht ihre Hauptbeschaeftigung entdeckt?$",
+ "Sie arbeitet in der Dekoration mit sehr viel Geschmack. Ausserdem ist sie immer sehr gut angezogen.$",
+ "Interessiert sie der Schmuck. Ich habe ein Geschaeft vorzuschlagen.$",
+ "Der Schmuck...$",
+ "Ich weiss nicht, aber ich glaube, ich wuerde es vorziehen, wenn er sich ein bisschen weniger um meine Angelegenheiten kuemmern wuerde.$",
+ "Eine Hausfrau hat immer zu tun.$",
+ "Sie koennte auch ohne Arbeit auskommen. Aber nein, sie naeht, sie liest...$",
+ "Sie hat sicherlich keine sehr erheiternden Taetigkeiten.$",
+ "Eine aussergewoehnliche Frau. Sie interessiert sich fuer alles.$",
+ "Zwischen Kueche und Haushalt habe ich nicht viel Zeit fuer sie.$",
+ "Wie schafft er es nur, alles zu machen? Oh Wunder!$",
+ "Er taete gut daran, wenn er sich weniger mit Klatsch und der Flasche beschaeftigen wuerde.$",
+ "Ich bin sehr selbstaendig. Solange man sich nicht um meine Angelegenheiten kuemmert, gibt es keine Probleme.$",
+ "Er ist ein Egoist. Ich frage mich, ob es fuer ihn noch etwas anderes gibt, als seine Pferde und seine Maerchenbuecher.$",
+ "Er versteht sich gut mit allen, ausser vielleicht mit Guy.$",
+ "Er ist ein Mann mit Charakter. Man muss ihn zu nehmen wissen.$",
+ "Geschaeft ist Geschaeft. Was die Familie anbetrifft...$",
+ "Beziehungen? Freundschaften? Finanzen zweifellos.$",
+ "Ich habe ihm nichts vorzuwerfen.$",
+ "Er ist ein pfiffiger Geschaeftsmann. Manchmal schwimmt er gegen den Strom, aber er weiss sich immer zu helfen.$",
+ "Sie langweilen mich alle. Nein, obwohl... einige...$",
+ "Im Gegensatz zur Mutter ist es eine sehr verschlossene Person. Also Frage: Beziehung.$",
+ "Er muss sich zweifellos sehr anstrengen, um trotz seiner Sorgen freundlich zu bleiben.$",
+ "Seine Liebesaffairen? Aus und vorbei. Mit mir? Es hat nie richtig angefangen. Was die anderen betrifft... ich bin nicht \"die anderen\".$",
+ "Ich mag jeden, solange man mich nicht betruegt.$",
+ "Es reicht nicht, ein bisschen Geld zu haben und ein guter Redner zu sein, um bei allen beliebt zu sein.$",
+ "Jemand, der nett ist und ausserdem noch Humor hat.$",
+ "Ueber diese Sache kann ich mich nicht auslassen.$",
+ "Das ist nicht besonders intelligent. Sprechen Sie mit dem Ehemann darueber.$",
+ "Ist es wegen eines Rendez-vous?$",
+ "Sie ist sehr lebhaft. sie laesst sich nicht durch Vorurteile in Verwirrung brignen.$",
+ "In meinem Beruf ist man vor allem schoenen Frauen und Gaunern sehr nahe.$",
+ "Sein einziges Vermoegen sind sein Schmuck und seine Frau, aber er ist sich dessen nicht bewusst.$",
+ "Jemand interessantes, aber nicht immer leicht zu verstehen, der aber die Muehe wert ist.$",
+ "Ich verachte niemanden, aber ich mag es sehr, wenn alles und alle dort sind, wo sie hingehoeren.$",
+ "Unter uns.. sehen Sie, wenn ich mit ihr spreche, fuehle ich mich schnell beengt.$",
+ "Um sich nicht mit ihr zu verstehen, braucht man wirklich viel schlechten Willen.$",
+ "In meinem Beruf hoert man alles, aber behaelt nichts. Nur der Service zaehlt.$",
+ "Das ist ein Heuchler, ein Kriecher. Ich persoenlich habe kein Vertrauen zu Ihm.$",
+ "Ich kenne seine wahren Gedanken nicht, aber er war stets korrekt.$",
+ "Sie hat vor einem Jahr, vielleicht laenger, auf dem Landsitz gewohnt.$",
+ "Mehr als eine Freundin fuer meine Mutter. In solchen Augenblicken haette ich gewuenscht, dass sie da ist.$",
+ "Sie war die Hausdame von Julia.$",
+ "Sie hat ebenfalls Recherchen angestellt. Aber Guy, der sie besser kennt als jeder andere, kann Ihnen mehr sagen.$",
+ "Ihre Beziehungen?... Sie war sehr kultiviert. Ihr ploetzliches Verschwinden vor einem Jahr hat mich erstaunt.$",
+ "Sie teilte mit Leo ihre Leidenschaft fuer Geschichte und fuer die Gegend.$",
+ "Ich glaube, jeder hatte sie gern.$",
+ "Sie verstand sich mit allen gut, aber ganz besonders liebte sie ihren Sohn. Was die Beziehungen Schwiegermutter Scwiegertochter anbetrifft...$",
+ "Ausser zu Leo hatte sie auch gute Beziehungen zu Max.$",
+ "Obwohl ihre Beziehungen nicht von Dauer waren, lag ihr immer viel an ihnen.$",
+ "Ausser ihrer Familie, nicht viele.$",
+ "Aber ja. Sie hat das Weggehen dieser Freundin sehr bedauert. Eh, Mireille, oder Marielle.$",
+ "Nein, nichts.$",
+ "Nein, nicht das ich wuesste.$",
+ "Ich habe Julia kennengelernt, als ich das Landgut kaufte. Es war das einzige, was ihr gehoerte, aber mein Besitz war auch der ihre.$",
+ "Wenn nicht einige persoenliche Dinge gewesen waeren, ich glaube, dann haette sie nichts eigenes mehr gehabt.$",
+ "Ich glaube, all ihr Reichtum kam von Leo. Also!$",
+ "Ausser des Briefes, den ich fuer sie aufgegeben habe, nichts wichtiges.$",
+ "Ich war gluecklich, als sie mir ihre eingebundene Bibel schenkte.$",
+ "Es ging schnell und sie hatte nicht die Zeit, um spezielle Entscheidungen zu treffen.$",
+ "Ihr letztes Geschenk hat mich ueberrascht.$",
+ "Was fuer ein Geschenk?$",
+ "Ein Kerzenleuchter.$",
+ "Ja, ich habe ein Geschenk bekommen. Meine Frau hat sogar eine Bibel bekommen.$",
+ "Aber ja. wie jeder, glaube ich.$",
+ "Ein Dolch$",
+ "Ich habe nie den Dachboden durchwuehlt.$",
+ "Haben Sie die Gabe eines Hellsehers, oder haben Sie einen Dietrich?$",
+ "Das Portrait einer jungen Frau? Das ist Murielle.$",
+ "Ich kannte sie zu wenig.$",
+ "Sehr charmant. Sie war vor allem die Hausdame von Julia.$",
+ "Das war die einzige wirklich interessante Frau, die ich getroffen habe.$",
+ "Sie hatte ein grosses Wissen vorzuweisen. Sie zu besuchen, war stets sehr bereichernd.$",
+ "Ich habe mich immer gefragt, was manche an ihr fanden.$",
+ "Das Zimmer ist verschlossen? Fragen Sie Leo.$",
+ "Ich habe ihr Zimmer nach ihrem Tod abgeschlossen und ich moechte, dass das auch noch eine zeitlang so bleibt.$",
+ "Wissen Sie, was das sind? Familienbeziehungen.$",
+ "In all den Jahren habe ich sie niemals gegen meinen Willen bedient.$",
+ "Ich habe sie so sehr geliebt, wie sie mich, glaube ich.$",
+ "Mit welchem Recht sind Sie in das Zimmer meiner Frau eingedrungen?$",
+ "Zweifellos das Foto von Murielle mit dem Patenkind von Julia.$",
+ "Ich erinnere mich nicht.$",
+ "Das ist Murielle. Ich war es, der sie fotografiert hat. Uebrigens ist das Foto seitenverkehrt abgezogen.$",
+ "Sie sind wirklich neugierig. Das ist wertlos.$",
+ "Maerchen, Pergamente und Manuskripte das ist Leos Spezialitaet.$",
+ "Schade, dass die Losung fehlt.$",
+ "Das ist sehr schoen und sehr alt.$",
+ "Das ist ein Ort, den ich nie gesehen habe.$",
+ "Leos Meinung nach schien es, als seien die Monde spaeter gemacht worden.$",
+ "M\210me par ce temps, vous avez d\202nich\202 un soleil ...$",
+ "Tief und beunruhigend. Der Fortschritt hat gutes an sich.$",
+ "Der Rest bleibt fuer mich eines der groessten Raetsel.$",
+ "In letzter Zeit sprach sie oft von einer Reise und dann...$",
+ "An einem Abend vor mehr als einem Jahr hat sie sich entschieden wegzugehen.$",
+ "Auf jeden Fall war sie fuer das Leben hier nicht geschaffen.$",
+ "Welcher Koerper? Welche Krypta?$",
+ "Wenn es sie ueberhaupt gibt, ich habe sie nie gefunden.$",
+ "Aber sicher! Und die Fantome auch.$",
+ "Es ist die aelteste der Stadt. Sie stammt aus dem 11. Jahrhundert.$",
+ "Nach der Revolution wurde sie leicht restauriert.$",
+ "Julia liebte die Malerei sehr.$",
+ "Sie haben verschiedene Stilrichtungen, aber sie haben nicht alle Wert.$",
+ "Was machen Sie da ?$",
+ "Ich bin sicher, Sie suchen etwas!$",
+ "Ich hoere.$",
+ "Was wuenschen Sie?$",
+ "Ja ?$",
+ "Ich stehe zu Ihrer Verfuegung.$",
+ "Weswegen?$",
+ "Na los doch!$",
+ "Wegen was?$",
+ "Max: Zu Ihren Diensten, Monsieur.$",
+ "Auf jeden Fall haben Sie hier nichts zu suchen! Gehen Sie raus!$",
+ "Sie sind zu neugierig!$",
+ "Jerome, es ist lange her. Wie traurig, Julia ist tot. Ihre Familie ist hier. Guy, ihr Sohn, und Eva, ihre Schwiegertochter. Leo, ihr Mann, sowie ihr Schwiegersohn Pat und die Cousins Bob, Ida und Luc. Das Unwetter verstaerkt sich. Sie muessen noch bleiben. Die Mahlzeiten sind um 12 Uhr und um 19 Uhr und es findet jeden Tag um 10 Uhr eine Andacht in der Kapelle statt.$",
+ "Als ich Sie sah, habe ich sofort begriffen, dass Sie die Wahrheit aufdecken wuerden, da ich wusste, warum Sie gekommen sind. Ich hatte den Entwurf von Julias Brief gefunden. Aber ich bin ein begeisterter Spieler, also.... Sie haette nicht gewollte, dass ihre Aufgabe zu leicht ausfaellt, zweifellos, um mich zu schuetzen, aber sie konnten nicht sterben mit dieser Ungewissheit.Haben Sie herausgefunden, dass die \"Mauer des Schweigens\" der Name ist, den die Maurer waehrend des Baus des Landsitzes der Mauer gegeben haben, die das Wappen traegt...? Und die Geschenke, die Julia vor ihrem Tod hinterlassen hat waren sowohl falsche Hinweise wie auch ein Mittel, um die Wichtigkeit der Pergamente herauszustellen. Tatsaechlich arbeitete ich vor mehr als einem Jahr mit Murielle an der Entzifferung dieser Pergamente, die ich gefunden hatte. Meine Frau sah einen Zusammenhang zwischen unserer Arbeit und dem Verschwinden Murielles,aber sie hat nie Beweise dafuer gehabt; wenn da nicht dieser Ring gewesen waere, den sie eines Tages unter meinen Sachen wiedergefunden hat. Eines nachts sind wir in dem Geheimgang, den wir entdeckt hatten,auf Erkundung gegangen. Murielle ist durch einen Unfall im \"Jungfrauenzimmer\" ums Leben gekommen. Ich habe ihren Ring schnell an mich genommen, habe den Schatz entdeckt und mich dann aus dem Staub gemacht. Ich dachte nicht daran, dass sie unter Umstaenden noch leben koennte, und ich habe nichts gesagt, da ich Geld brauchte. Ich habe das Geld beim Pferderennen verspielt. Gehen Sie jetzt, da sie ja nicht von der Polizei sind. Lassen Sie mich allein.$",
+ "Februar '51, Beruf: Privatdetektiv. Die Kaelte laesst Paris und meine Unternehmungen erstarren, als...$",
+ "Julia, heute eine alte Frau. Nichts als Erinnerungen und Spiele in den alten Zimmern des Landsitzes von Morteville.$",
+ "im Buero$",
+ "in der Kueche$",
+ "im Keller$",
+ "auf dem Flur$",
+ "draussen$",
+ "im Esszimmer$",
+ "im Landsitz$",
+ "vor dem Landsitz$",
+ "in der Kapelle$",
+ "vor dem Brunnen$",
+ "im Norden$",
+ "hinter dem Landsitz$",
+ "im Sueden$",
+ "im Osten$",
+ "im Westen$",
+ "in Richtung Landsitz$",
+ "noch weiter$",
+ "im Wasser$",
+ "ausser des Brunnens$",
+ "im Brunnen$",
+ "Wahl auf dem Bild$",
+ " In der Reihe RAETSEL...$",
+ " DER LANDSITZ VON MORTEVILLE$",
+ "$",
+ " Nach einer Idee von...$",
+ " Bernard GRELAUD und Bruno GOURIER$",
+ "$",
+ " Realisation: LANKHOR$",
+ "$",
+ " in Zusammenarbeit mit...$",
+ " Beatrice und Jean-Luc LANGLOIS Musik und Stimmen,$",
+ " Bernard GRELAUD graphische Gestaltung,$",
+ " Dominique SABLONS graphische Realisation ,$",
+ " Bruno GOURIER technische Realisation,$",
+ " Gabi NURGE Uebersetzung,$",
+ " Clement ROQUES IBM PC Realisation.$",
+ "$",
+ " Ausgabe: LANKHOR$",
+ " COPYRIGHT 1989: LANKHOR$",
+ "$",
+ " SIE SIND AM ZUG$",
+ "abkratzen$",
+ "anschauen$",
+ "ausgehen$",
+ "befestig.$",
+ "drehen$",
+ "durchsuch$",
+ "eindrueck$",
+ "eintreten$",
+ "essen$",
+ "fuehlen$",
+ "hochheben$",
+ "klopfen$",
+ "lesen$",
+ "nehmen$",
+ "oeffnen$",
+ "schlafen$",
+ "schliess.$",
+ "setzen$",
+ "sondieren$",
+ "warten$",
+ "zuhoeren$",
+ "anschauen$",
+ "durchsuch.$",
+ "hinlegen$",
+ "lesen$",
+ "s. verstec$",
+ "Leo$",
+ "Pat$",
+ "Guy$",
+ "Eva$",
+ "Bob$",
+ "Luc$",
+ "Ida$",
+ "Max$",
+ " JULIA$",
+ "hat sie Selbstmord begangen ?$",
+ "ist sie ermordet worden ?$",
+ "ist sie durch Unfall gestorben ?$",
+ "ist sie eines natuerlichen Todes gestorben ?$",
+ " Woher kam das Geld, das die restaurierung des landsitzes erlaubte ?$",
+ "Erpressung$",
+ "Arbeit$",
+ "Erbschaft$",
+ "Rennen$",
+ "Renten$",
+ "Raub$",
+ "Verschiedenes$",
+ " Was ist Leos Hobby ?$",
+ "Historische Recherchen$",
+ "Politik$",
+ "Malerei$",
+ "Drogen$",
+ "Okkultismus$",
+ "Fuehrung einer Sekte$",
+ " Julia Hat verschiedene Indizien hinterlassen. Diese befinden sich an einem einzigen Ort. Welchem ?$",
+ "Kapelle$",
+ "Draussen$",
+ "Keller$",
+ "Dachboden$",
+ "Kueche$",
+ "Esszimmer$",
+ "Julias Zimmer$",
+ "Leos Zimmer$",
+ "Pats Zimmer$",
+ "Bobs Zimmer$",
+ "Maxs Zimmer$",
+ "Luc/Idas Zimmer$",
+ "Guy/Evas Zimmer$",
+ " Der entscheidende Hinweis, der es Ihnen ermoeglichte, bis an die Tuer des Souterrains zu gelangen, war :$",
+ "ein Dolch$",
+ "ein Ring$",
+ "ein Buch$",
+ "ein Pergament$",
+ "ein Brief$",
+ "ein Pendel$",
+ " Wievele Pergamente befinden sich auf dem Landsitz ?$",
+ "kein$",
+ "eins$",
+ "zwei$",
+ "drei$",
+ "vier$",
+ "f\201nf$",
+ " Wieviele Personen sind in die Geschichte verwickelt ? (Julia eingeschlossen, ausgenommen Sie)$",
+ "neun$",
+ "zehn$",
+ "elf$",
+ " Wie war der Name der unbekannten Person ?$",
+ "Mireille$",
+ "Fran\207oise$",
+ "Maguy$",
+ "Emilie$",
+ "Murielle$",
+ "Sophie$",
+ " Wessen Geliebte war Murielle ?$",
+ "Bob$",
+ "Luc$",
+ "Guy$",
+ "Leo$",
+ "Max$",
+ " Murielle teilte eine Beschaeftigung mit einer anderen Person. Mit wem ?$",
+ "[1][Allein der Zufall hat es Ihnen ermoeglicht bis hierher zu komen.| Gehen Sie zurueck und forschen Sie noch einmal nach,|damit Sie das Gaze besser verstehen...][ok]$",
+ "[1][Legen Sie die Diskette 1 ein][ok]$",
+ "[1][Problem mit der Diskette | Alles abstellen...][OK]$",
+ "[1][Sie haetten 00% der Hinweise| bemerken muessen][ OK ]$",
+ "[1][Legen Sie die Diskette 2 ein][ok]$",
+ "[1][Bevor Sie weitermachen, fassen Sie Ihre Kenntnisse Zusammen][ok]$",
+ " MASTER .$",
+ " sgaf",
+ NULL
+};
+#endif
diff --git a/devtools/create_mortdat/menudata.h b/devtools/create_mortdat/menudata.h
new file mode 100644
index 0000000000..ec8724135c
--- /dev/null
+++ b/devtools/create_mortdat/menudata.h
@@ -0,0 +1,143 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a utility for extracting needed resource data from different language
+ * version of the Mortevielle executable files into a new file mort.dat - this
+ * is required for the ScummVM Mortevielle module to work properly
+ */
+
+#ifndef MENUDATA_H
+#define MENUDATA_H
+
+const char *menuDataEn =
+ " @@@ "
+ " @ "
+ " @ @ @@ @@@ @@@ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ "@@@ @@@ @@ @@ "
+ " "
+ " @@ @@ "
+ " @@ @ @ "
+ " @ @ @ @ @@@ @@@ @@@"
+ " @ @ @ @ @ @ @ "
+ " @ @ @ @ @ @ "
+ " @ @ @ @ @ @ "
+ "@@@ @@@ @@@@ @@ "
+ " "
+ " @ @ "
+ " @@ @ "
+ " @ @ @@@@ @@@@ "
+ " @ @ @ @ @ "
+ " @@@@@ @ @ "
+ " @ @ @ @ @ "
+ "@@@ @@@ @@@ @@ "
+ " "
+ " @@@@@ @@@ @@@"
+ " @ @ @ @ @"
+ " @ @@@ @ @ "
+ " @@@@ @ @ @ @@@ "
+ " @ @@@@@ @ @ "
+ " @ @ @ @ @ "
+ "@@@@@@ @@@ @@@ @@@ "
+ " "
+ "@@@@@@@ @@@ @@@ "
+ "@ @ @ @ @ "
+ " @ @@@@ @ @ @@"
+ " @ @ @ @ @@ @ "
+ " @ @ @ @ @ @@ "
+ " @ @ @ @ @ @ "
+ "@@@ @@@@ @@@ @@@ @@@"
+ " "
+ " @@@@@@@ @ @@@ "
+ " @ @ @ "
+ " @ @ @@ @ @@@ "
+ " @@@@ @ @ @ @"
+ " @ @ @ @ @@@@@ "
+ " @ @ @ @ "
+ "@@@ @@@ @@@ @@@ "
+ " ";
+
+const char *menuDataDe =
+ " @@@ @@ "
+ " @ @ "
+ " @ @ @@ @ @@@@"
+ " @ @ @ @@@ @ @"
+ " @ @ @ @ @ @ @ "
+ " @ @ @ @ @ @ @ "
+ "@@@ @@@ @@ @@ @@ @@@@ "
+ " "
+ " @@@@@@ @ @@ "
+ " @ @ @ "
+ " @ @ @@ @@@@ @ "
+ " @@@@ @ @ @ @@@ "
+ " @ @ @ @ @ @ "
+ " @ @ @ @ @ @ @ "
+ "@@ @@ @@@ @@@ @@ @@"
+ " "
+ " @ @@ @ "
+ " @@@ @ @ "
+ " @ @ @ @@ @@@@ "
+ " @ @ @ @ @ "
+ " @@@@@ @@@ @ "
+ " @ @ @ @ @ "
+ "@@@ @@@ @@@ @@ @@ "
+ " "
+ " @@@ @@ "
+ " @ @ "
+ " @ @@@@ @ "
+ " @ @ @ @@@ "
+ " @ @ @ @ "
+ " @ @ @ @ @ "
+ " @@@ @@@ @@ @@ "
+ " "
+ " @@@@@@ "
+ " @ @ @@ "
+ " @ @ @@@ @ @@@ "
+ " @@@@ @ @ @@@@ @ @"
+ " @ @ @@@@@ @ @ @@@@ "
+ " @ @ @ @ @ @ "
+ "@@ @@ @@@ @@@ @@@ "
+ " "
+ " @@@@@ @ "
+ " @ @ @ "
+ " @ @ @@@@ @@@@ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ "@@@@@ @@@@ @@ "
+ " ";
+
+const int verbsFr[26] = { 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307, 0x308,
+ 0x309, 0x30a, 0x30b, 0x30c, 0x30d, 0x30e, 0x30f, 0x310,
+ 0x311, 0x312, 0x313, 0x314, 0x315, 0x401, 0x402, 0x403,
+ 0x404, 0x405 };
+
+const int verbsEn[26] = { 0x301, 0x315, 0x305, 0x310, 0x309, 0x304, 0x302, 0x30f,
+ 0x306, 0x30d, 0x30e, 0x303, 0x30c, 0x30b, 0x313, 0x30a,
+ 0x311, 0x312, 0x307, 0x308, 0x314, 0x401, 0x405, 0x404,
+ 0x403, 0x402 };
+
+const int verbsDe[26] = { 0x304, 0x314, 0x307, 0x310, 0x315, 0x308, 0x311, 0x306,
+ 0x30c, 0x301, 0x30d, 0x309, 0x312, 0x30f, 0x30e, 0x302,
+ 0x30a, 0x313, 0x303, 0x30b, 0x305, 0x405, 0x402, 0x404,
+ 0x403, 0x401 };
+#endif
diff --git a/devtools/create_mortdat/module.mk b/devtools/create_mortdat/module.mk
new file mode 100644
index 0000000000..86b14d8284
--- /dev/null
+++ b/devtools/create_mortdat/module.mk
@@ -0,0 +1,11 @@
+
+MODULE := devtools/create_mortdat
+
+MODULE_OBJS := \
+ create_mortdat.o \
+
+# Set the name of the executable
+TOOL_EXECUTABLE := create_mortdat
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp
index f34f20882c..446ee5ec3b 100644
--- a/devtools/create_neverhood/create_neverhood.cpp
+++ b/devtools/create_neverhood/create_neverhood.cpp
@@ -69,13 +69,13 @@ bool loadExe(const char *filename) {
bool validateMd5() {
uint8 digest[16];
-
+
md5_buffer(data, dataSize, digest);
-
+
printf("MD5 of nhc.exe is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
- digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
+ digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]);
-
+
if (memcmp(kNhcExeMd5, digest, 16)) {
printf("MD5 hash of nhc.exe doesn't match the expected value! Quitting...\n");
return false;
@@ -112,7 +112,7 @@ uint32 calcHash(const char *value) {
struct HitRect {
int16 x1, y1, x2, y2;
uint16 messageNum;
-
+
void load(uint32 offset) {
byte *item = getData(offset);
x1 = READ_LE_UINT16(item + 0);
@@ -120,7 +120,7 @@ struct HitRect {
x2 = READ_LE_UINT16(item + 4);
y2 = READ_LE_UINT16(item + 6);
messageNum = READ_LE_UINT16(item + 8);
- }
+ }
void save(FILE *fd) {
writeUint16LE(fd, x1);
@@ -129,11 +129,11 @@ struct HitRect {
writeUint16LE(fd, y2);
writeUint16LE(fd, messageNum);
}
-
+
int getItemSize() const {
return 10;
}
-
+
};
struct MessageItem {
@@ -141,22 +141,22 @@ struct MessageItem {
uint32 messageParam;
MessageItem() {}
MessageItem(uint16 msgNum, uint32 msgParam) : messageNum(msgNum), messageParam(msgParam) {}
-
+
void load(uint32 offset) {
byte *item = getData(offset);
messageNum = READ_LE_UINT16(item + 0);
messageParam = READ_LE_UINT32(item + 4);
- }
+ }
void save(FILE *fd) {
writeUint16LE(fd, messageNum);
writeUint32LE(fd, messageParam);
}
-
+
int getItemSize() const {
return 8;
}
-
+
};
struct SubRectItem {
@@ -175,7 +175,7 @@ struct SubRectItem {
// Add the message to the message list
addMessageList(messageListCount, messageListOffset);
}
-
+
void save(FILE *fd) {
writeUint16LE(fd, x1);
writeUint16LE(fd, y1);
@@ -183,11 +183,11 @@ struct SubRectItem {
writeUint16LE(fd, y2);
writeUint32LE(fd, messageListOffset);
}
-
+
int getItemSize() const {
return 16;
}
-
+
};
struct RectItem {
@@ -212,7 +212,7 @@ struct RectItem {
subItemOffset += 16;
subRectItems.push_back(subRectItem);
}
- }
+ }
void save(FILE *fd) {
writeUint16LE(fd, x1);
@@ -223,11 +223,11 @@ struct RectItem {
for (uint32 j = 0; j < subRectItems.size(); j++)
subRectItems[j].save(fd);
}
-
+
int getItemSize() const {
return 16;
}
-
+
};
struct NavigationItem {
@@ -238,10 +238,10 @@ struct NavigationItem {
byte interactive;
byte middleFlag;
uint32 mouseCursorFileHash;
-
+
void load(uint32 offset) {
byte *item = getData(offset);
- fileHash = READ_LE_UINT32(item + 0);
+ fileHash = READ_LE_UINT32(item + 0);
leftSmackerFileHash = READ_LE_UINT32(item + 4);
rightSmackerFileHash = READ_LE_UINT32(item + 8);
middleSmackerFileHash = READ_LE_UINT32(item + 12);
@@ -263,7 +263,7 @@ struct NavigationItem {
int getItemSize() const {
return 24;
}
-
+
};
struct SceneInfo140Item {
@@ -347,24 +347,24 @@ struct SceneInfo2700Item {
template<class ITEMCLASS>
class StaticDataList {
public:
- uint32 id;
+ uint32 id;
std::vector<ITEMCLASS> items;
-
+
virtual ~StaticDataList() {
}
-
+
void add(ITEMCLASS item) {
items.push_back(item);
}
-
+
int getCount() const {
return items.size();
}
-
+
ITEMCLASS *getListItem(int index) {
return &items[index];
}
-
+
virtual bool specialLoadList(uint32 count, uint32 offset) {
return false;
}
@@ -398,7 +398,7 @@ class RectList : public StaticDataList<RectItem> {
};
class MessageList : public StaticDataList<MessageItem> {
-public:
+public:
virtual bool specialLoadList(uint32 count, uint32 offset) {
// Special code for message lists which are set at runtime (but otherwise constant)
@@ -455,7 +455,7 @@ public:
}
return false;
}
-
+
};
class NavigationList : public StaticDataList<NavigationItem> {
@@ -465,11 +465,11 @@ template<class LISTCLASS>
class StaticDataListVector {
public:
std::vector<LISTCLASS*> lists;
-
+
void add(LISTCLASS *list) {
lists.push_back(list);
}
-
+
void loadListVector(const uint32 *offsets) {
for (int i = 0; offsets[i] != 0; i += 2) {
LISTCLASS *list = new LISTCLASS();
@@ -486,7 +486,7 @@ public:
lists.push_back(list);
}
}
-
+
void saveListVector(FILE *fd) {
writeUint32LE(fd, lists.size());
for (typename std::vector<LISTCLASS*>::iterator it = lists.begin(); it != lists.end(); it++) {
@@ -500,7 +500,7 @@ template<class ITEMCLASS>
class StaticDataVector {
public:
std::vector<ITEMCLASS> items;
-
+
void loadVector(const uint32 *offsets) {
for (int i = 0; offsets[i] != 0; i++) {
ITEMCLASS item;
@@ -508,7 +508,7 @@ public:
items.push_back(item);
}
}
-
+
void saveVector(FILE *fd) {
writeUint32LE(fd, items.size());
for (typename std::vector<ITEMCLASS>::iterator it = items.begin(); it != items.end(); it++) {
@@ -522,8 +522,8 @@ StaticDataListVector<HitRectList> hitRectLists;
StaticDataListVector<RectList> rectLists;
StaticDataListVector<MessageList> messageLists;
StaticDataListVector<NavigationList> navigationLists;
-StaticDataVector<SceneInfo140Item> sceneInfo140Items;
-StaticDataVector<SceneInfo2700Item> sceneInfo2700Items;
+StaticDataVector<SceneInfo140Item> sceneInfo140Items;
+StaticDataVector<SceneInfo2700Item> sceneInfo2700Items;
void addMessageList(uint32 messageListCount, uint32 messageListOffset) {
MessageList *messageList = new MessageList();
@@ -550,7 +550,7 @@ int main(int argc, char *argv[]) {
writeUint32LE(datFile, 0x11223344); // Some magic
writeUint32LE(datFile, DAT_VERSION);
-
+
messageLists.saveListVector(datFile);
rectLists.saveListVector(datFile);
hitRectLists.saveListVector(datFile);
diff --git a/devtools/create_neverhood/tables.h b/devtools/create_neverhood/tables.h
index ea39aa807d..eb136491db 100644
--- a/devtools/create_neverhood/tables.h
+++ b/devtools/create_neverhood/tables.h
@@ -122,7 +122,7 @@ static const uint32 rectListOffsets[] = {
// Scene2406
1, 0x004B78C8,
1, 0x004B78D8,
- // Scene2501
+ // Scene2501
1, 0x004B2608,
// Scene2732
1, 0x004AE360,
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index 480f6a926a..3ee5fc4f97 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -109,7 +109,7 @@ enum ProjectType {
int main(int argc, char *argv[]) {
#ifndef USE_WIN32_API
// Initialize random number generator for UUID creation
- std::srand((uint)std::time(0));
+ std::srand((unsigned int)std::time(0));
#endif
if (argc < 2) {
@@ -264,7 +264,7 @@ int main(int argc, char *argv[]) {
setup.filePrefix.erase(setup.filePrefix.size() - 1);
} else if (!std::strcmp(argv[i], "--output-dir")) {
if (i + 1 >= argc) {
- std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dirx\"!\n";
+ std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dir\"!\n";
return -1;
}
@@ -279,12 +279,23 @@ int main(int argc, char *argv[]) {
setup.createInstaller = true;
} else if (!std::strcmp(argv[i], "--tools")) {
setup.devTools = true;
+ } else if (!std::strcmp(argv[i], "--tests")) {
+ setup.tests = true;
} else {
std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n";
return -1;
}
}
+ // When building tests, disable some features
+ if (setup.tests) {
+ setFeatureBuildState("mt32emu", setup.features, false);
+ setFeatureBuildState("eventrecorder", setup.features, false);
+
+ for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j)
+ j->enable = false;
+ }
+
// Print status
cout << "Enabled engines:\n\n";
for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) {
@@ -321,6 +332,12 @@ int main(int argc, char *argv[]) {
}
}
+ // Check if tools and tests are enabled simultaneously
+ if (setup.devTools && setup.tests) {
+ std::cerr << "ERROR: The tools and tests projects cannot be created simultaneously\n";
+ return -1;
+ }
+
// Setup defines and libraries
setup.defines = getEngineDefines(setup.engines);
setup.libraries = getFeatureLibraries(setup.features);
@@ -358,8 +375,8 @@ int main(int argc, char *argv[]) {
return -1;
case kProjectCodeBlocks:
- if (setup.devTools) {
- std::cerr << "ERROR: Building tools is not supported for the CodeBlocks project type!\n";
+ if (setup.devTools || setup.tests) {
+ std::cerr << "ERROR: Building tools or tests is not supported for the CodeBlocks project type!\n";
return -1;
}
@@ -531,8 +548,8 @@ int main(int argc, char *argv[]) {
break;
case kProjectXcode:
- if (setup.devTools) {
- std::cerr << "ERROR: Building tools is not supported for the XCode project type!\n";
+ if (setup.devTools || setup.tests) {
+ std::cerr << "ERROR: Building tools or tests is not supported for the XCode project type!\n";
return -1;
}
@@ -573,6 +590,11 @@ int main(int argc, char *argv[]) {
setup.projectDescription += "Tools";
}
+ if (setup.tests) {
+ setup.projectName += "-tests";
+ setup.projectDescription += "Tests";
+ }
+
provider->createProject(setup);
delete provider;
@@ -623,6 +645,9 @@ void displayHelp(const char *exe) {
" --tools Create project files for the devtools\n"
" (ignores --build-events and --installer, as well as engine settings)\n"
" (default: false)\n"
+ " --tests Create project files for the tests\n"
+ " (ignores --build-events and --installer, as well as engine settings)\n"
+ " (default: false)\n"
"\n"
"Engines settings:\n"
" --list-engines list all available engines and their default state\n"
@@ -816,6 +841,8 @@ const Feature s_features[] = {
{ "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", true, "Ogg Vorbis support" },
{ "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" },
{ "png", "USE_PNG", "libpng", true, "libpng support" },
+ { "faad", "USE_FAAD", "libfaad", false, "AAC support" },
+ { "mpeg2", "USE_MPEG2", "libmpeg2", false, "MPEG-2 support" },
{ "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" },
{"freetype", "USE_FREETYPE2", "freetype", true, "FreeType support" },
@@ -841,7 +868,9 @@ const Tool s_tools[] = {
{ "create_hugo", true},
{ "create_kyradat", true},
{ "create_lure", true},
+ { "create_neverhood", true},
{ "create_teenagent", true},
+ { "create_tony", true},
{ "create_toon", true},
{ "create_translations", true},
{ "qtable", true}
@@ -1126,69 +1155,66 @@ ProjectProvider::ProjectProvider(StringList &global_warnings, std::map<std::stri
: _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) {
}
-void ProjectProvider::createProject(const BuildSetup &setup) {
+void ProjectProvider::createProject(BuildSetup &setup) {
+ std::string targetFolder;
+
if (setup.devTools) {
_uuidMap = createToolsUUIDMap();
+ targetFolder = "/devtools/";
+ } else if (!setup.tests) {
+ _uuidMap = createUUIDMap(setup);
+ targetFolder = "/engines/";
+ }
- // We also need to add the UUID of the main project file.
- const std::string svmUUID = _uuidMap[setup.projectName] = createUUID();
-
- createWorkspace(setup);
-
- StringList in, ex;
-
- // Create tools project files
- for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) {
- if (i->first == setup.projectName)
- continue;
-
- in.clear(); ex.clear();
- const std::string moduleDir = setup.srcDir + "/devtools/" + i->first;
-
- createModuleList(moduleDir, setup.defines, in, ex);
- createProjectFile(i->first, i->second, setup, moduleDir, in, ex);
- }
-
- // Create other misc. build files
- createOtherBuildFiles(setup);
+ // We also need to add the UUID of the main project file.
+ const std::string svmUUID = _uuidMap[setup.projectName] = createUUID();
- } else {
- _uuidMap = createUUIDMap(setup);
+ createWorkspace(setup);
- // We also need to add the UUID of the main project file.
- const std::string svmUUID = _uuidMap[setup.projectName] = createUUID();
+ StringList in, ex;
- // Create Solution/Workspace file
- createWorkspace(setup);
+ // Create project files
+ for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) {
+ if (i->first == setup.projectName)
+ continue;
- StringList in, ex;
+ in.clear(); ex.clear();
+ const std::string moduleDir = setup.srcDir + targetFolder + i->first;
- // Create engine project files
- for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) {
- if (i->first == setup.projectName)
- continue;
+ createModuleList(moduleDir, setup.defines, setup.testDirs, in, ex);
+ createProjectFile(i->first, i->second, setup, moduleDir, in, ex);
+ }
- in.clear(); ex.clear();
- const std::string moduleDir = setup.srcDir + "/engines/" + i->first;
+ if (setup.tests) {
+ // Create the main project file.
+ in.clear(); ex.clear();
- createModuleList(moduleDir, setup.defines, in, ex);
- createProjectFile(i->first, i->second, setup, moduleDir, in, ex);
- }
+ createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/test", setup.defines, setup.testDirs, in, ex);
+ createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex);
+ } else if (!setup.devTools) {
// Last but not least create the main project file.
in.clear(); ex.clear();
// File list for the Project file
- createModuleList(setup.srcDir + "/backends", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/base", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/common", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/engines", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/graphics", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/gui", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/audio", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex);
- createModuleList(setup.srcDir + "/video", setup.defines, in, ex);
+ createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, setup.testDirs, in, ex);
+ createModuleList(setup.srcDir + "/video", setup.defines, setup.testDirs, in, ex);
// Resource files
in.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico");
@@ -1207,10 +1233,10 @@ void ProjectProvider::createProject(const BuildSetup &setup) {
// Create the main project file.
createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex);
-
- // Create other misc. build files
- createOtherBuildFiles(setup);
}
+
+ // Create other misc. build files
+ createOtherBuildFiles(setup);
}
ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const {
@@ -1318,7 +1344,7 @@ void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &p
delete files;
}
-void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const {
+void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const {
const std::string moduleMkFile = moduleDir + "/module.mk";
std::ifstream moduleMk(moduleMkFile.c_str());
if (!moduleMk)
@@ -1449,6 +1475,59 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
++i;
}
}
+ } else if (*i == "TESTS") {
+ if (tokens.size() < 3)
+ error("Malformed TESTS definition in " + moduleMkFile);
+ ++i;
+
+ if (*i != ":=" && *i != "+=" && *i != "=")
+ error("Malformed TESTS definition in " + moduleMkFile);
+ ++i;
+
+ while (i != tokens.end()) {
+ // Read input
+ std::string folder = unifyPath(*i);
+
+ // Get include folder
+ const std::string source_dir = "$(srcdir)/";
+ const std::string selector = getLastPathComponent(folder);
+ const std::string module = getLastPathComponent(moduleDir);
+
+ folder.replace(folder.find(source_dir), source_dir.length(), "");
+ folder.replace(folder.find(selector), selector.length(), "");
+ folder.replace(folder.find(module), module.length(), moduleDir);
+
+ // Scan all files in the include folder
+ FileList files = listDirectory(folder);
+
+ if (files.empty())
+ continue;
+
+ // Add to list of test folders
+ testDirs.push_back(folder);
+
+ for (FileList::const_iterator f = files.begin(); f != files.end(); ++f) {
+ if (f->isDirectory)
+ continue;
+
+ std::string filename = folder + f->name;
+
+ if (shouldInclude.top()) {
+ // In case we should include a file, we need to make
+ // sure it is not in the exclude list already. If it
+ // is we just drop it from the exclude list.
+ excludeList.remove(filename);
+
+ includeList.push_back(filename);
+ } else if (std::find(includeList.begin(), includeList.end(), filename) == includeList.end()) {
+ // We only add the file to the exclude list in case it
+ // has not yet been added to the include list.
+ excludeList.push_back(filename);
+ }
+ }
+
+ ++i;
+ }
} else if (*i == "ifdef") {
if (tokens.size() < 2)
error("Malformed ifdef in " + moduleMkFile);
diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h
index de77793ee7..d0f2db364c 100644
--- a/devtools/create_project/create_project.h
+++ b/devtools/create_project/create_project.h
@@ -221,13 +221,16 @@ struct BuildSetup {
StringList defines; ///< List of all defines for the build.
StringList libraries; ///< List of all external libraries required for the build.
+ StringList testDirs; ///< List of all folders containing tests
bool devTools; ///< Generate project files for the tools
+ bool tests; ///< Generate project files for the tests
bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder
bool createInstaller; ///< Create NSIS installer after the build
BuildSetup() {
devTools = false;
+ tests = false;
runBuildEvents = false;
createInstaller = false;
}
@@ -339,7 +342,7 @@ public:
*
* @param setup Description of the desired build setup.
*/
- void createProject(const BuildSetup &setup);
+ void createProject(BuildSetup &setup);
/**
* Returns the last path component.
@@ -430,10 +433,11 @@ protected:
*
* @param moduleDir Path to the module.
* @param defines List of set defines.
+ * @param testDirs List of folders containing tests.
* @param includeList Reference to a list, where included files should be added.
* @param excludeList Reference to a list, where excluded files should be added.
*/
- void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const;
+ void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const;
/**
* Creates an UUID for every enabled engine of the
@@ -448,7 +452,7 @@ protected:
* Creates an UUID for every enabled tool of the
* passed build description.
*
- * @return A map, which includes UUIDs for all enabled engines.
+ * @return A map, which includes UUIDs for all enabled tools.
*/
UUIDMap createToolsUUIDMap() const;
diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp
index 6af9323fcd..7bab5c1078 100644
--- a/devtools/create_project/msbuild.cpp
+++ b/devtools/create_project/msbuild.cpp
@@ -67,10 +67,10 @@ inline void outputConfiguration(std::ostream &project, const std::string &config
"\t\t</ProjectConfiguration>\n";
}
-inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, int version) {
+inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, std::string toolset) {
project << "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"Configuration\">\n"
- "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n"
- "\t\t<PlatformToolset>v" << version << "0</PlatformToolset>\n"
+ "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n"
+ "\t\t<PlatformToolset>" << toolset << "</PlatformToolset>\n"
"\t</PropertyGroup>\n";
}
@@ -98,6 +98,8 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
outputConfiguration(project, "Debug", "x64");
outputConfiguration(project, "Analysis", "Win32");
outputConfiguration(project, "Analysis", "x64");
+ outputConfiguration(project, "LLVM", "Win32");
+ outputConfiguration(project, "LLVM", "x64");
outputConfiguration(project, "Release", "Win32");
outputConfiguration(project, "Release", "x64");
@@ -108,18 +110,23 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
"\t\t<ProjectGuid>{" << uuid << "}</ProjectGuid>\n"
"\t\t<RootNamespace>" << name << "</RootNamespace>\n"
"\t\t<Keyword>Win32Proj</Keyword>\n"
- "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath" << _version << ")' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath" << _version << ")</VCTargetsPath>\n"
+ "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath" << _version << ")' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath" << _version << ")</VCTargetsPath>\n"
"\t</PropertyGroup>\n";
// Shared configuration
project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n";
- outputConfigurationType(setup, project, name, "Release|Win32", _version);
- outputConfigurationType(setup, project, name, "Analysis|Win32", _version);
- outputConfigurationType(setup, project, name, "Debug|Win32", _version);
- outputConfigurationType(setup, project, name, "Release|x64", _version);
- outputConfigurationType(setup, project, name, "Analysis|x64", _version);
- outputConfigurationType(setup, project, name, "Debug|x64", _version);
+ std::string version = "v" + std::to_string(_version) + "0";
+ std::string llvm = "LLVM-vs" + std::to_string(getVisualStudioVersion());
+
+ outputConfigurationType(setup, project, name, "Release|Win32", version);
+ outputConfigurationType(setup, project, name, "Analysis|Win32", version);
+ outputConfigurationType(setup, project, name, "LLVM|Win32", llvm);
+ outputConfigurationType(setup, project, name, "Debug|Win32", version);
+ outputConfigurationType(setup, project, name, "Release|x64", version);
+ outputConfigurationType(setup, project, name, "LLVM|x64", llvm);
+ outputConfigurationType(setup, project, name, "Analysis|x64", version);
+ outputConfigurationType(setup, project, name, "Debug|x64", version);
project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n"
"\t<ImportGroup Label=\"ExtensionSettings\">\n"
@@ -127,20 +134,24 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
outputProperties(project, "Release|Win32", setup.projectDescription + "_Release.props");
outputProperties(project, "Analysis|Win32", setup.projectDescription + "_Analysis.props");
+ outputProperties(project, "LLVM|Win32", setup.projectDescription + "_LLVM.props");
outputProperties(project, "Debug|Win32", setup.projectDescription + "_Debug.props");
outputProperties(project, "Release|x64", setup.projectDescription + "_Release64.props");
outputProperties(project, "Analysis|x64", setup.projectDescription + "_Analysis64.props");
+ outputProperties(project, "LLVM|x64", setup.projectDescription + "_LLVM64.props");
outputProperties(project, "Debug|x64", setup.projectDescription + "_Debug64.props");
project << "\t<PropertyGroup Label=\"UserMacros\" />\n";
// Project-specific settings (analysis uses debug properties)
- outputProjectSettings(project, name, setup, false, true, false);
- outputProjectSettings(project, name, setup, false, true, true);
- outputProjectSettings(project, name, setup, true, true, false);
- outputProjectSettings(project, name, setup, false, false, false);
- outputProjectSettings(project, name, setup, false, false, true);
- outputProjectSettings(project, name, setup, true, false, false);
+ outputProjectSettings(project, name, setup, false, true, "Debug");
+ outputProjectSettings(project, name, setup, false, true, "Analysis");
+ outputProjectSettings(project, name, setup, false, true, "LLVM");
+ outputProjectSettings(project, name, setup, true, true, "Release");
+ outputProjectSettings(project, name, setup, false, false, "Debug");
+ outputProjectSettings(project, name, setup, false, false, "Analysis");
+ outputProjectSettings(project, name, setup, false, false, "LLVM");
+ outputProjectSettings(project, name, setup, true, false, "Release");
// Files
std::string modulePath;
@@ -159,10 +170,26 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
if (name == setup.projectName)
writeReferences(setup, project);
+ // Output auto-generated test runner
+ if (setup.tests) {
+ project << "\t<ItemGroup>\n";
+ project << "\t\t<ClCompile Include=\"test_runner.cpp\" />\n";
+ project << "\t</ItemGroup>\n";
+ }
+
project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n"
"\t<ImportGroup Label=\"ExtensionTargets\">\n"
- "\t</ImportGroup>\n"
- "</Project>\n";
+ "\t</ImportGroup>\n";
+
+ if (setup.tests) {
+ // We override the normal target to ignore the exit code (this allows us to have a clean output and not message about the command exit code)
+ project << "\t\t<Target Name=\"PostBuildEvent\">\n"
+ << "\t\t\t<Message Text=\"Description: Run tests\" />\n"
+ << "\t\t\t<Exec Command=\"$(TargetPath)\" IgnoreExitCode=\"true\" />\n"
+ << "\t\t</Target>\n";
+ }
+
+ project << "</Project>\n";
// Output filter file if necessary
createFiltersFile(setup, name);
@@ -239,16 +266,14 @@ void MSBuildProvider::writeReferences(const BuildSetup &setup, std::ofstream &ou
output << "\t</ItemGroup>\n";
}
-void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) {
- const std::string configuration = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug"));
-
+void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) {
// Check for project-specific warnings:
std::map<std::string, StringList>::iterator warningsIterator = _projectWarnings.find(name);
bool enableLanguageExtensions = find(_enableLanguageExtensions.begin(), _enableLanguageExtensions.end(), name) != _enableLanguageExtensions.end();
bool disableEditAndContinue = find(_disableEditAndContinue.begin(), _disableEditAndContinue.end(), name) != _disableEditAndContinue.end();
// Nothing to add here, move along!
- if (!setup.devTools && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end())
+ if ((!setup.devTools || !setup.tests) && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end())
return;
std::string warnings = "";
@@ -260,7 +285,7 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s
"\t\t<ClCompile>\n";
// Language Extensions
- if (setup.devTools || name == setup.projectName || enableLanguageExtensions)
+ if (setup.devTools || setup.tests || name == setup.projectName || enableLanguageExtensions)
project << "\t\t\t<DisableLanguageExtensions>false</DisableLanguageExtensions>\n";
// Edit and Continue
@@ -274,18 +299,18 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s
project << "\t\t</ClCompile>\n";
// Link configuration for main project
- if (name == setup.projectName || setup.devTools) {
+ if (name == setup.projectName || setup.devTools || setup.tests) {
std::string libraries;
for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i)
libraries += *i + ".lib;";
project << "\t\t<Link>\n"
- "\t\t\t<OutputFile>$(OutDir)" << (setup.devTools ? name : setup.projectName) << ".exe</OutputFile>\n"
+ "\t\t\t<OutputFile>$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe</OutputFile>\n"
"\t\t\t<AdditionalDependencies>" << libraries << "%(AdditionalDependencies)</AdditionalDependencies>\n"
"\t\t</Link>\n";
- if (!setup.devTools && setup.runBuildEvents) {
+ if (!setup.devTools && !setup.tests && setup.runBuildEvents) {
project << "\t\t<PreBuildEvent>\n"
"\t\t\t<Message>Generate revision</Message>\n"
"\t\t\t<Command>" << getPreBuildEvent() << "</Command>\n"
@@ -296,6 +321,11 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s
"\t\t\t<Message>Copy data files to the build folder</Message>\n"
"\t\t\t<Command>" << getPostBuildEvent(isWin32, setup.createInstaller) << "</Command>\n"
"\t\t</PostBuildEvent>\n";
+ } else if (setup.tests) {
+ project << "\t\t<PreBuildEvent>\n"
+ "\t\t\t<Message>Generate runner.cpp</Message>\n"
+ "\t\t\t<Command>" << getTestPreBuildEvent(setup) << "</Command>\n"
+ "\t\t</PreBuildEvent>\n";
}
}
@@ -330,9 +360,9 @@ 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;$(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 ? "Sync" : "") << "</ExceptionHandling>\n";
+ "\t\t\t<ExceptionHandling>" << ((setup.devTools || setup.tests) ? "Sync" : "") << "</ExceptionHandling>\n";
#if NEEDS_RTTI
properties << "\t\t\t<RuntimeTypeInfo>true</RuntimeTypeInfo>\n";
@@ -348,7 +378,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
"\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n"
"\t\t\t<SubSystem>Console</SubSystem>\n";
- if (!setup.devTools)
+ if (!setup.devTools && !setup.tests)
properties << "\t\t\t<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n";
properties << "\t\t</Link>\n"
@@ -361,13 +391,12 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
properties.flush();
}
-void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) {
- const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug"));
+void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) {
const std::string outputBitness = (isWin32 ? "32" : "64");
- std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str());
+ std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str());
if (!properties)
- error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
+ error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
@@ -375,7 +404,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
"\t\t<Import Project=\"" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".props\" />\n"
"\t</ImportGroup>\n"
"\t<PropertyGroup>\n"
- "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << outputType << outputBitness << "</_PropertySheetDisplayName>\n"
+ "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << configuration << outputBitness << "</_PropertySheetDisplayName>\n"
"\t\t<LinkIncremental>" << (isRelease ? "false" : "true") << "</LinkIncremental>\n"
"\t</PropertyGroup>\n"
"\t<ItemDefinitionGroup>\n"
@@ -384,27 +413,31 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
if (isRelease) {
properties << "\t\t\t<IntrinsicFunctions>true</IntrinsicFunctions>\n"
"\t\t\t<WholeProgramOptimization>true</WholeProgramOptimization>\n"
- "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
+ "\t\t\t<PreprocessorDefinitions>WIN32;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<StringPooling>true</StringPooling>\n"
"\t\t\t<BufferSecurityCheck>false</BufferSecurityCheck>\n"
"\t\t\t<DebugInformationFormat></DebugInformationFormat>\n"
"\t\t\t<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n"
- "\t\t\t<EnablePREfast>" << (enableAnalysis ? "true" : "false") << "</EnablePREfast>\n"
+ "\t\t\t<EnablePREfast>" << (configuration == "Analysis" ? "true" : "false") << "</EnablePREfast>\n"
"\t\t</ClCompile>\n"
"\t\t<Link>\n"
"\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n"
"\t\t\t<SetChecksum>true</SetChecksum>\n";
} else {
properties << "\t\t\t<Optimization>Disabled</Optimization>\n"
- "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
+ "\t\t\t<PreprocessorDefinitions>WIN32;" << (configuration == "LLVM" ? "_CRT_SECURE_NO_WARNINGS;" : "") << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<MinimalRebuild>true</MinimalRebuild>\n"
"\t\t\t<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n"
"\t\t\t<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n"
"\t\t\t<FunctionLevelLinking>true</FunctionLevelLinking>\n"
"\t\t\t<TreatWarningAsError>false</TreatWarningAsError>\n"
"\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>" << (enableAnalysis ? "true" : "false") << "</EnablePREfast>\n"
- "\t\t</ClCompile>\n"
+ "\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";
+
+ properties << "\t\t</ClCompile>\n"
"\t\t<Link>\n"
"\t\t\t<GenerateDebugInformation>true</GenerateDebugInformation>\n"
"\t\t\t<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\n"
@@ -460,7 +493,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream
// Deal with duplicated file names
if (isDuplicate) {
projectFile << "\t\t<ClCompile Include=\"" << (*entry).path << "\">\n"
- "\t\t\t<ObjectFileName>$(IntDir)" << (*entry).prefix << "%(Filename).obj</ObjectFileName>\n";
+ "\t\t\t<ObjectFileName>$(IntDir)" << (*entry).prefix << "%(Filename).obj</ObjectFileName>\n";
projectFile << "\t\t</ClCompile>\n";
} else {
diff --git a/devtools/create_project/msbuild.h b/devtools/create_project/msbuild.h
index fa6667741a..829657beff 100644
--- a/devtools/create_project/msbuild.h
+++ b/devtools/create_project/msbuild.h
@@ -35,7 +35,7 @@ protected:
void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir,
const StringList &includeList, const StringList &excludeList);
- void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis);
+ void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration);
void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix);
@@ -44,7 +44,7 @@ protected:
void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents);
- void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis);
+ void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration);
const char *getProjectExtension();
const char *getPropertiesExtension();
diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp
index b8d2401af9..cdd2d8a7c1 100644
--- a/devtools/create_project/msvc.cpp
+++ b/devtools/create_project/msvc.cpp
@@ -79,9 +79,11 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) {
"\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n"
"\t\tDebug|Win32 = Debug|Win32\n"
"\t\tAnalysis|Win32 = Analysis|Win32\n"
+ "\t\tLLVM|Win32 = LLVM|Win32\n"
"\t\tRelease|Win32 = Release|Win32\n"
"\t\tDebug|x64 = Debug|x64\n"
"\t\tAnalysis|x64 = Analysis|x64\n"
+ "\t\tLLVM|x64 = LLVM|x64\n"
"\t\tRelease|x64 = Release|x64\n"
"\tEndGlobalSection\n"
"\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n";
@@ -91,12 +93,16 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) {
"\t\t{" << i->second << "}.Debug|Win32.Build.0 = Debug|Win32\n"
"\t\t{" << i->second << "}.Analysis|Win32.ActiveCfg = Analysis|Win32\n"
"\t\t{" << i->second << "}.Analysis|Win32.Build.0 = Analysis|Win32\n"
+ "\t\t{" << i->second << "}.LLVM|Win32.ActiveCfg = LLVM|Win32\n"
+ "\t\t{" << i->second << "}.LLVM|Win32.Build.0 = LLVM|Win32\n"
"\t\t{" << i->second << "}.Release|Win32.ActiveCfg = Release|Win32\n"
"\t\t{" << i->second << "}.Release|Win32.Build.0 = Release|Win32\n"
"\t\t{" << i->second << "}.Debug|x64.ActiveCfg = Debug|x64\n"
"\t\t{" << i->second << "}.Debug|x64.Build.0 = Debug|x64\n"
"\t\t{" << i->second << "}.Analysis|x64.ActiveCfg = Analysis|x64\n"
"\t\t{" << i->second << "}.Analysis|x64.Build.0 = Analysis|x64\n"
+ "\t\t{" << i->second << "}.LLVM|x64.ActiveCfg = LLVM|x64\n"
+ "\t\t{" << i->second << "}.LLVM|x64.Build.0 = LLVM|x64\n"
"\t\t{" << i->second << "}.Release|x64.ActiveCfg = Release|x64\n"
"\t\t{" << i->second << "}.Release|x64.Build.0 = Release|x64\n";
}
@@ -114,12 +120,14 @@ void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) {
// Create the configuration property files (for Debug and Release with 32 and 64bits versions)
// Note: we use the debug properties for the analysis configuration
- createBuildProp(setup, true, false, false);
- createBuildProp(setup, true, true, false);
- createBuildProp(setup, false, false, false);
- createBuildProp(setup, false, false, true);
- createBuildProp(setup, false, true, false);
- createBuildProp(setup, false, true, true);
+ createBuildProp(setup, true, false, "Release");
+ createBuildProp(setup, true, true, "Release");
+ createBuildProp(setup, false, false, "Debug");
+ createBuildProp(setup, false, true, "Debug");
+ createBuildProp(setup, false, false, "Analysis");
+ createBuildProp(setup, false, true, "Analysis");
+ createBuildProp(setup, false, false, "LLVM");
+ createBuildProp(setup, false, true, "LLVM");
}
void MSVCProvider::createGlobalProp(const BuildSetup &setup) {
@@ -161,6 +169,16 @@ std::string MSVCProvider::getPreBuildEvent() const {
return cmdLine;
}
+std::string MSVCProvider::getTestPreBuildEvent(const BuildSetup &setup) const {
+ // Build list of folders containing tests
+ std::string target = "";
+
+ for (StringList::const_iterator it = setup.testDirs.begin(); it != setup.testDirs.end(); ++it)
+ target += " $(SolutionDir)" + *it + "*.h";
+
+ return "&quot;$(SolutionDir)../../test/cxxtest/cxxtestgen.py&quot; --runner=ParenPrinter --no-std --no-eh -o $(SolutionDir)test_runner.cpp" + target;
+}
+
std::string MSVCProvider::getPostBuildEvent(bool isWin32, bool createInstaller) const {
std::string cmdLine = "";
diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h
index 5a854b596a..3a3eb98034 100644
--- a/devtools/create_project/msvc.h
+++ b/devtools/create_project/msvc.h
@@ -70,7 +70,7 @@ protected:
* @param isWin32 Bitness of property file
* @param enableAnalysis PREfast support
*/
- virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) = 0;
+ virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) = 0;
/**
* Get the file extension for property files
@@ -88,6 +88,13 @@ protected:
std::string getPreBuildEvent() const;
/**
+ * Get the command line for the test generator
+ *
+ * @param setup Description of the desired build setup.
+ */
+ std::string getTestPreBuildEvent(const BuildSetup &setup) const;
+
+ /**
* Get the command line for copying data files to the build directory.
*
* @param isWin32 Bitness of property file.
diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp
index de2df96d78..438e0772f9 100644
--- a/devtools/create_project/visualstudio.cpp
+++ b/devtools/create_project/visualstudio.cpp
@@ -83,7 +83,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
// Check for project-specific warnings:
std::map< std::string, std::list<std::string> >::iterator warningsIterator = _projectWarnings.find(name);
- if (setup.devTools || name == setup.projectName) {
+ if (setup.devTools || setup.tests || name == setup.projectName) {
std::string libraries;
for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i)
@@ -92,6 +92,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
// Win32
outputConfiguration(project, setup, libraries, "Debug", "Win32", "", true);
outputConfiguration(project, setup, libraries, "Analysis", "Win32", "", true);
+ outputConfiguration(project, setup, libraries, "LLVM", "Win32", "", true);
outputConfiguration(project, setup, libraries, "Release", "Win32", "", true);
// x64
@@ -100,6 +101,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
// libraries list created for IA-32. If that changes in the future, we need to adjust this part!
outputConfiguration(project, setup, libraries, "Debug", "x64", "64", false);
outputConfiguration(project, setup, libraries, "Analysis", "x64", "64", false);
+ outputConfiguration(project, setup, libraries, "LLVM", "Win32", "64", false);
outputConfiguration(project, setup, libraries, "Release", "x64", "64", false);
} else {
@@ -119,9 +121,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
// Win32
outputConfiguration(setup, project, toolConfig, "Debug", "Win32", "");
outputConfiguration(setup, project, toolConfig, "Analysis", "Win32", "");
+ outputConfiguration(setup, project, toolConfig, "LLVM", "Win32", "");
outputConfiguration(setup, project, toolConfig, "Release", "Win32", "");
outputConfiguration(setup, project, toolConfig, "Debug", "x64", "64");
outputConfiguration(setup, project, toolConfig, "Analysis", "x64", "64");
+ outputConfiguration(setup, project, toolConfig, "LLVM", "x64", "64");
outputConfiguration(setup, project, toolConfig, "Release", "x64", "64");
}
@@ -140,6 +144,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
else
addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix);
+ // Output auto-generated test runner
+ if (setup.tests) {
+ project << "\t\t<File RelativePath=\"test_runner.cpp\" />\n";
+ }
+
project << "\t</Files>\n"
"</VisualStudioProject>\n";
}
@@ -161,7 +170,7 @@ void VisualStudioProvider::outputConfiguration(const BuildSetup &setup, std::ost
}
void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildSetup &setup, const bool isWin32) {
- if (!setup.devTools && setup.runBuildEvents) {
+ if (!setup.devTools && !setup.tests && setup.runBuildEvents) {
project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n"
"\t\t\t\tCommandLine=\"" << getPreBuildEvent() << "\"\n"
"\t\t\t/>\n"
@@ -169,6 +178,17 @@ void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildS
"\t\t\t\tCommandLine=\"" << getPostBuildEvent(isWin32, setup.createInstaller) << "\"\n"
"\t\t\t/>\n";
}
+
+ // Generate runner file before build for tests
+ if (setup.tests) {
+ project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n"
+ "\t\t\t\tCommandLine=\"" << getTestPreBuildEvent(setup) << "\"\n"
+ "\t\t\t/>\n";
+
+ project << "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n"
+ "\t\t\t\tCommandLine=\"$(TargetPath)\" IgnoreExitCode=\"true\"\n"
+ "\t\t\t/>\n";
+ }
}
void VisualStudioProvider::writeReferences(const BuildSetup &setup, std::ofstream &output) {
@@ -212,9 +232,9 @@ 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;$(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 ? "1" : "0") << "\"\n";
+ "\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n";
#if NEEDS_RTTI
properties << "\t\tRuntimeTypeInfo=\"true\"\n";
@@ -235,7 +255,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of
"\t\tIgnoreDefaultLibraryNames=\"\"\n"
"\t\tSubSystem=\"1\"\n";
- if (!setup.devTools)
+ if (!setup.devTools && !setup.tests)
properties << "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n";
properties << "\t\tAdditionalLibraryDirectories=\"$(" << LIBS_DEFINE << ")\\lib\\" << ((bits == 32) ? "x86" : "x64") << "\"\n"
@@ -249,19 +269,18 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of
properties.flush();
}
-void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) {
- const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug"));
+void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) {
const std::string outputBitness = (isWin32 ? "32" : "64");
- std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str());
+ std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str());
if (!properties)
- error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
+ error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
properties << "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n"
"<VisualStudioPropertySheet\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"8.00\"\n"
- "\tName=\"" << setup.projectDescription << "_" << outputType << outputBitness << "\"\n"
+ "\tName=\"" << setup.projectDescription << "_" << configuration << outputBitness << "\"\n"
"\tInheritedPropertySheets=\".\\" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".vsprops\"\n"
"\t>\n"
"\t<Tool\n"
@@ -275,7 +294,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea
"\t\tBufferSecurityCheck=\"false\"\n"
"\t\tDebugInformationFormat=\"0\"\n"
"\t\tRuntimeLibrary=\"0\"\n"
- "\t\tAdditionalOption=\"" << (enableAnalysis ? "/analyze" : "") << "\"\n"
+ "\t\tAdditionalOption=\"" << (configuration == "Analysis" ? "/analyze" : "") << "\"\n"
"\t/>\n"
"\t<Tool\n"
"\t\tName=\"VCLinkerTool\"\n"
@@ -291,7 +310,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea
"\t\tEnableFunctionLevelLinking=\"true\"\n"
"\t\tWarnAsError=\"false\"\n"
"\t\tDebugInformationFormat=\"" << (isWin32 ? "4" : "3") << "\"\n" // For x64 format "4" (Edit and continue) is not supported, thus we default to "3"
- "\t\tAdditionalOption=\"" << (enableAnalysis ? "/analyze" : "") << "\"\n"
+ "\t\tAdditionalOption=\"" << (configuration == "Analysis" ? "/analyze" : "") << "\"\n"
"\t/>\n"
"\t<Tool\n"
"\t\tName=\"VCLinkerTool\"\n"
@@ -338,9 +357,9 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst
<< indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n"
<< toolLine
<< indentString << "\t</FileConfiguration>\n"
- << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n"
- << toolLine
- << indentString << "\t</FileConfiguration>\n"
+ << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n"
+ << toolLine
+ << indentString << "\t</FileConfiguration>\n"
<< indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n"
<< toolLine
<< indentString << "\t</FileConfiguration>\n"
@@ -353,18 +372,18 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst
<< indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n"
<< toolLine
<< indentString << "\t</FileConfiguration>\n"
- << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n"
- << toolLine
- << indentString << "\t</FileConfiguration>\n"
+ << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n"
+ << toolLine
+ << indentString << "\t</FileConfiguration>\n"
<< indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n"
<< toolLine
<< indentString << "\t</FileConfiguration>\n"
- << indentString << "\t<FileConfiguration Name=\"Debug|x64\">\n"
- << toolLine
- << indentString << "\t</FileConfiguration>\n"
- << indentString << "\t<FileConfiguration Name=\"Analysis|x64\">\n"
- << toolLine
- << indentString << "\t</FileConfiguration>\n"
+ << indentString << "\t<FileConfiguration Name=\"Debug|x64\">\n"
+ << toolLine
+ << indentString << "\t</FileConfiguration>\n"
+ << indentString << "\t<FileConfiguration Name=\"Analysis|x64\">\n"
+ << toolLine
+ << indentString << "\t</FileConfiguration>\n"
<< indentString << "\t<FileConfiguration Name=\"Release|x64\">\n"
<< toolLine
<< indentString << "\t</FileConfiguration>\n"
diff --git a/devtools/create_project/visualstudio.h b/devtools/create_project/visualstudio.h
index 845550139c..7eb66c4f2d 100644
--- a/devtools/create_project/visualstudio.h
+++ b/devtools/create_project/visualstudio.h
@@ -42,7 +42,7 @@ protected:
void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents);
- void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis);
+ void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration);
const char *getProjectExtension();
const char *getPropertiesExtension();
diff --git a/devtools/create_teenagent/static_tables.h b/devtools/create_teenagent/static_tables.h
index 6e7fdfe91c..5c9b5b3d21 100644
--- a/devtools/create_teenagent/static_tables.h
+++ b/devtools/create_teenagent/static_tables.h
@@ -15148,7 +15148,7 @@ const static char* dialog_162[] = {
};
// Note:
-// The usage of this in the engine overlaps the previous dialog i.e. the
+// The usage of this in the engine overlaps the previous dialog i.e. the
// starting offset used is two bytes early, thus implicitly changing the
// first command of this dialog from NEW_LINE to CHANGE_CHARACTER.
const static char* dialog_163[] = {
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 7d39730c63..45018a5633 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -638,6 +638,16 @@ begin_credits("Credits");
add_person("David Turner", "digitall", "");
end_section();
+ begin_section("Mortevielle");
+ add_person("Arnaud Boutonn&eacute;", "Strangerke", "");
+ add_person("Paul Gilbert", "dreammaster", "");
+ end_section();
+
+ begin_section("Neverhood");
+ add_person("Benjamin Haisch", "john_doe", "");
+ add_person("Filippos Karapetis", "[md5]", "");
+ end_section();
+
begin_section("Parallaction");
add_person("", "peres", "");
end_section();
diff --git a/devtools/extract_mort/extract_mort.cpp b/devtools/extract_mort/extract_mort.cpp
new file mode 100644
index 0000000000..159309c0fa
--- /dev/null
+++ b/devtools/extract_mort/extract_mort.cpp
@@ -0,0 +1,428 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 is a utility for extracting needed resource data from different language
+ * version of the Lure of the Temptress lure.exe executable files into a new file
+ * lure.dat - this file is required for the ScummVM Lure of the Temptress module
+ * to work properly
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/endian.h"
+
+enum AccessMode {
+ kFileReadMode = 1,
+ kFileWriteMode = 2
+};
+
+class File {
+private:
+ FILE *f;
+public:
+ bool open(const char *filename, AccessMode mode = kFileReadMode) {
+ f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb");
+ return (f != NULL);
+ }
+ void close() {
+ fclose(f);
+ f = NULL;
+ }
+ int seek(int32 offset, int whence = SEEK_SET) {
+ return fseek(f, offset, whence);
+ }
+ long read(void *buffer, int len) {
+ return fread(buffer, 1, len, f);
+ }
+ void write(const void *buffer, int len) {
+ fwrite(buffer, 1, len, f);
+ }
+ byte readByte() {
+ byte v;
+ read(&v, sizeof(byte));
+ return v;
+ }
+ uint16 readWord() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_LE_16(v);
+ }
+ uint32 readLong() {
+ uint32 v;
+ read(&v, sizeof(uint32));
+ return FROM_LE_32(v);
+ }
+ void readString(char *sLine) {
+ while ((*sLine = readByte()) != '\n')
+ ++sLine;
+
+ *sLine = '\0';
+ }
+ void writeByte(byte v) {
+ write(&v, sizeof(byte));
+ }
+ void writeWord(uint16 v) {
+ uint16 vTemp = TO_LE_16(v);
+ write(&vTemp, sizeof(uint16));
+ }
+ void writeLong(uint32 v) {
+ uint32 vTemp = TO_LE_32(v);
+ write(&vTemp, sizeof(uint32));
+ }
+ void writeString(const char *s) {
+ fprintf(f, "%s", s);
+ }
+ uint32 pos() {
+ return ftell(f);
+ }
+ uint32 size() {
+ int pos = ftell(f);
+ fseek (f, 0, SEEK_END);
+ int end = ftell (f);
+ fseek (f, pos, SEEK_SET);
+
+ return end;
+ }
+};
+
+File textFile, txxInp, txxNtp;
+int _version;
+
+/*-------------------------------------------------------------------------*/
+
+#define BUFFER_SIZE 32768
+
+const byte tabdrFr[32] = {
+ 32, 101, 115, 97, 114, 105, 110,
+ 117, 116, 111, 108, 13, 100, 99,
+ 112, 109, 46, 118, 130, 39, 102,
+ 98, 44, 113, 104, 103, 33, 76,
+ 85, 106, 30, 31
+};
+
+const byte tab30Fr[32] = {
+ 69, 67, 74, 138, 133, 120, 77, 122,
+ 121, 68, 65, 63, 73, 80, 83, 82,
+ 156, 45, 58, 79, 49, 86, 78, 84,
+ 71, 81, 64, 66, 135, 34, 136, 91
+};
+
+const byte tab31Fr[32]= {
+ 93, 47, 48, 53, 50, 70, 124, 75,
+ 72, 147, 140, 150, 151, 57, 56, 51,
+ 107, 139, 55, 89, 131, 37, 54, 88,
+ 119, 0, 0, 0, 0, 0, 0, 0
+};
+
+const byte tabdrDe[32] = {
+ 0x20, 0x65, 0x6E, 0x69, 0x73, 0x72, 0x74,
+ 0x68, 0x61, 0x75, 0x0D, 0x63, 0x6C, 0x64,
+ 0x6D, 0x6F, 0x67, 0x2E, 0x62, 0x66, 0x53,
+ 0x2C, 0x77, 0x45, 0x7A, 0x6B, 0x44, 0x76,
+ 0x9C, 0x47, 0x1E, 0x1F
+};
+
+const byte tab30De[32] = {
+ 0x49, 0x4D, 0x21, 0x42, 0x4C, 0x70, 0x41, 0x52,
+ 0x57, 0x4E, 0x48, 0x3F, 0x46, 0x50, 0x55, 0x4B,
+ 0x5A, 0x4A, 0x54, 0x31, 0x4F, 0x56, 0x79, 0x3A,
+ 0x6A, 0x5B, 0x5D, 0x40, 0x22, 0x2F, 0x30, 0x35
+};
+
+const byte tab31De[32]= {
+ 0x78, 0x2D, 0x32, 0x82, 0x43, 0x39, 0x33, 0x38,
+ 0x7C, 0x27, 0x37, 0x3B, 0x25, 0x28, 0x29, 0x36,
+ 0x51, 0x59, 0x71, 0x81, 0x87, 0x88, 0x93, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const byte *tabdr, *tab30, *tab31;
+uint16 ctrlChar;
+
+/**
+ * Extracts a single character from the game data
+ */
+static void extractCharacter(unsigned char &c, uint &idx, uint &pt, bool &the_end, const uint16 *strData) {
+ uint16 oct, ocd;
+
+ /* 5-8 */
+ oct = FROM_LE_16(strData[idx]);
+
+ oct = ((uint16)(oct << (16 - pt))) >> (16 - pt);
+ if (pt < 6) {
+ idx = idx + 1;
+ oct = oct << (5 - pt);
+ pt = pt + 11;
+ oct = oct | (FROM_LE_16(strData[idx]) >> pt);
+ } else {
+ pt = pt - 5;
+ oct = (uint)oct >> pt;
+ }
+
+ if (oct == ctrlChar) {
+ c = '$';
+ the_end = true;
+ } else if (oct == 30 || oct == 31) {
+ ocd = FROM_LE_16(strData[idx]);
+ ocd = (uint16)(ocd << (16 - pt)) >> (16 - pt);
+ if (pt < 6) {
+ idx = idx + 1;
+ ocd = ocd << (5 - pt);
+ pt = pt + 11;
+ ocd = ocd | (FROM_LE_16(strData[idx]) >> pt);
+ } else {
+ pt = pt - 5;
+ ocd = (uint)ocd >> pt;
+ }
+ if (oct == 30)
+ c = (char)tab30[ocd];
+ else
+ c = (char)tab31[ocd];
+
+ if (c == '\0')
+ the_end = true;
+ } else {
+ c = (char)tabdr[oct];
+ }
+}
+
+/**
+ * Puts a compressed 5-bit value into the string data buffer
+ */
+static void addCompressedValue(int oct, int &indis, int &point, uint16 *strData) {
+ // Write out the part of the value that fits into the current word
+ if (point < 5)
+ strData[indis] |= oct >> (5 - point);
+ else
+ strData[indis] |= oct << (point - 5);
+
+ // Handling of there's any overlap into the next word
+ if (point < 5) {
+ // Overlapping into next word
+ ++indis;
+
+ // Get the bits that fall into the next word and set it
+ int remainder = oct & ((1 << (5 - point)) - 1);
+ strData[indis] |= remainder << (16 - (5 - point));
+
+ point += -5 + 16;
+ } else {
+ point -= 5;
+ if (point == 0) {
+ point = 16;
+ ++indis;
+ }
+ }
+}
+
+/**
+ * Compresses a single passed character and stores it in the compressed strings buffer
+ */
+static void compressCharacter(unsigned char ch, int &indis, int &point, uint16 *strData) {
+ if (ch == '$') {
+ // End of string
+ addCompressedValue(11, indis, point, strData);
+ return;
+ }
+
+ // Scan through the tabdr array for a match
+ for (int idx = 0; idx < 30; ++idx) {
+ if ((idx != 11) && (tabdr[idx] == ch)) {
+ addCompressedValue(idx, indis, point, strData);
+ return;
+ }
+ }
+
+ // Scan through the tab30 array
+ for (int idx = 0; idx < 32; ++idx) {
+ if (tab30[idx] == ch) {
+ addCompressedValue(30, indis, point, strData);
+ addCompressedValue(idx, indis, point, strData);
+ return;
+ }
+ }
+
+ // Scan through the tab31 array
+ for (int idx = 0; idx < 32; ++idx) {
+ if (tab31[idx] == ch) {
+ addCompressedValue(31, indis, point, strData);
+ addCompressedValue(idx, indis, point, strData);
+ return;
+ }
+ }
+
+ printf("Encountered invalid character '%c' when compressing strings\n", ch);
+ exit(1);
+}
+
+/**
+ * string extractor
+ */
+static void export_strings(const char *textFilename) {
+ char buffer[BUFFER_SIZE];
+ uint16 *strData;
+
+ // Open input and output files
+ if (!txxInp.open("TXX.INP", kFileReadMode)) {
+ if (!txxInp.open("TXX.MOR", kFileReadMode)) {
+ printf("Missing TXX.INP/MOR");
+ exit(-1);
+ }
+ }
+ if (!txxNtp.open("TXX.NTP", kFileReadMode)) {
+ if (!txxNtp.open("TXX.IND", kFileReadMode)) {
+ printf("Missing TXX.NTP/IND");
+ exit(-1);
+ }
+ }
+ textFile.open(textFilename, kFileWriteMode);
+
+ // Read all the compressed string data into a buffer
+ printf("%d %d", txxInp.size(), txxNtp.size());
+ strData = (uint16 *)malloc(txxInp.size());
+ txxInp.read(strData, txxInp.size());
+
+ // Loop through getting each string
+ for (unsigned int strIndex = 0; strIndex < (txxNtp.size() / 3); ++strIndex) {
+ uint indis = txxNtp.readWord();
+ uint point = txxNtp.readByte();
+
+ // Extract the string
+ int charIndex = 0;
+ unsigned char ch;
+ bool endFlag = false;
+ do {
+ extractCharacter(ch, indis, point, endFlag, strData);
+ buffer[charIndex++] = ch;
+ if (charIndex == BUFFER_SIZE) {
+ printf("Extracted string exceeded allowed buffer size.\n");
+ exit(1);
+ }
+
+ if (indis >= (txxInp.size() / 2))
+ endFlag = true;
+ } while (!endFlag);
+
+ // Write out the string
+ buffer[charIndex++] = '\n';
+ buffer[charIndex] = '\0';
+ textFile.writeString(buffer);
+ }
+
+ // Close the files and free the buffer
+ free(strData);
+ txxInp.close();
+ txxNtp.close();
+ textFile.close();
+}
+
+/**
+ * string importer
+ */
+static void import_strings(const char *textFilename) {
+ // Open input and output files
+ if (!txxInp.open("TXX.INP", kFileWriteMode)) {
+ printf("Missing TXX data file");
+ exit(-1);
+ }
+ if (!txxNtp.open("TXX.NTP", kFileWriteMode)) {
+ printf("Missing TXX index file");
+ exit(-1);
+ }
+ textFile.open(textFilename, kFileReadMode);
+
+ // Set up a buffer for the output compressed strings
+ uint16 strData[BUFFER_SIZE];
+ memset(strData, 0, BUFFER_SIZE);
+ char sLine[BUFFER_SIZE];
+
+ int indis = 0;
+ int point = 16;
+
+ while (textFile.pos() < textFile.size()) {
+ // Read in the next source line
+ textFile.readString(sLine);
+
+ // Write out the index entry for the string
+ txxNtp.writeWord(indis);
+ txxNtp.writeByte(point);
+
+ // Loop through writing out the characters to the compressed data buffer
+ char *s = sLine;
+ while (*s) {
+ compressCharacter(*s, indis, point, strData);
+ ++s;
+ }
+ }
+
+ // Write out the compressed data
+ if (point != 16)
+ ++indis;
+ txxInp.write(strData, indis * 2);
+
+ // Close the files
+ txxInp.close();
+ txxNtp.close();
+ textFile.close();
+}
+
+
+int main(int argc, char *argv[]) {
+ if (argc != 4) {
+ printf("Format: %s export|import v1|v2 output_file\n", argv[0]);
+ printf("where:\nv1: French DOS version\nv2: German DOS version\n");
+ printf("The program must be run from the directory with the Mortville Manor game files.\n");
+ exit(0);
+ }
+
+ if (!strcmp(argv[2], "v1")) {
+ tab30 = tab30Fr;
+ tab31 = tab31Fr;
+ tabdr = tabdrFr;
+ ctrlChar = 11;
+ } else if (!strcmp(argv[2], "v2")) {
+ tab30 = tab30De;
+ tab31 = tab31De;
+ tabdr = tabdrDe;
+ ctrlChar = 10;
+ } else {
+ printf("Unknown version");
+ exit(-1);
+ }
+
+ // Do the processing
+ if (!strcmp(argv[1], "export"))
+ export_strings(argv[3]);
+ else if (!strcmp(argv[1], "import"))
+ import_strings(argv[3]);
+ else
+ printf("Unknown operation specified\n");
+}
diff --git a/devtools/extract_mort/module.mk b/devtools/extract_mort/module.mk
new file mode 100644
index 0000000000..cbdcd251d9
--- /dev/null
+++ b/devtools/extract_mort/module.mk
@@ -0,0 +1,11 @@
+
+MODULE := devtools/extract_mort
+
+MODULE_OBJS := \
+ extract_mort.o \
+
+# Set the name of the executable
+TOOL_EXECUTABLE := extract_mort
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 6e3bae1d7e..0dbcbf4792 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -626,7 +626,8 @@ jungle Let's Explore the Jungle with Buzzy
8801fb4a1200b347f7a38523339526dd -1 en Windows - - - Kirben
moonbase Moonbase Commander
- cf400d20769fb70eb21766582f4924f7 -1 en Windows - - - Kirben
+ cf400d20769fb70eb21766582f4924f7 -1 en Windows 1.0 1.0 - Kirben
+ e1c9998826ce7fa8bde5cc3a5023edec -1 en Windows 1.1 1.1 - fuzzie
ef71a322b6530ac45b1a070f7c0795f7 -1 en Windows Demo Demo - Kirben
pajama Pajama Sam 1: No Need to Hide When It's Dark Outside
@@ -654,6 +655,7 @@ pajama2 Pajama Sam 2: Thunder and Lightning Aren't so Frightening
e5563c8358443c4352fcddf7402a5e0a -1 fr Windows HE 98.5 - - gist974
c6907d44f1166941d982864cd42cdc89 -1 de All HE 99 - - nachbarnebenan
f8be685007a8b425ba2a455da732f59f -1 fr Mac HE 99 - - alamaz
+ 7477bc23d0383516c5e310cd8771dcc9 -1 fr Windows HE 99 - - Strangerke
32709cbeeb3044b34129950860a83f14 -1 ru Windows HE 99 - - sev
1af4eb581a33d808707d66d50e084dca -1 he Windows HE 99 - - Matan Bareket
@@ -773,6 +775,7 @@ puttzoo Putt-Putt Saves the Zoo
3a3e592b074f595489f7f11e150c398d -1 us Windows HE 99 Updated - Adrian
c5cc7cba02a2fbd539c4439e775b0536 43470 de Windows HE 99 Updated - Lightkey
5c9cecbd2952ccec14c9ecebf5822a34 -1 en iOS HE 100 - - clone2727
+ 7b4ee071eecadc2d8cd0c3509110825c -1 en Windows HE 100 Remastered - Kirben
3486ede0f904789267d4bcc5537a46d4 14337 en Mac - Demo - khalek
d220d154aafbfa12bd6f3ab1b2dae420 -1 de Mac - Demo - Joachim Eberhard
diff --git a/devtools/skycpt/cptcompiler.cpp b/devtools/skycpt/cptcompiler.cpp
index 2c7d33c73b..657f51b8a0 100644
--- a/devtools/skycpt/cptcompiler.cpp
+++ b/devtools/skycpt/cptcompiler.cpp
@@ -376,6 +376,7 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
uint32 asciiSize = (uint32)(asciiPos - asciiBuf);
fwrite(&asciiSize, 1, 4, debOutf);
fwrite(asciiBuf, 1, asciiSize, debOutf);
+ free(asciiBuf);
// the direct links...
fwrite(&dlinkCount, 2, 1, debOutf);
@@ -438,6 +439,8 @@ void doCompile(FILE *inf, FILE *debOutf, FILE *resOutf, TextFile *cptDef, FILE *
diffNo++;
}
}
+ fclose(dif);
+ free(resCpts);
assert(diffDest <= 8192);
fwrite(&diffNo, 1, 2, debOutf);
fwrite(&diffDest, 1, 2, debOutf);
diff --git a/dists/engine-data/README b/dists/engine-data/README
index c9c4bd4817..9bbb006d17 100644
--- a/dists/engine-data/README
+++ b/dists/engine-data/README
@@ -16,6 +16,11 @@ scripts, from.
lure.dat
TODO
+mort.dat:
+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.
+
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
diff --git a/dists/engine-data/mort.dat b/dists/engine-data/mort.dat
new file mode 100644
index 0000000000..0d6a44206d
--- /dev/null
+++ b/dists/engine-data/mort.dat
Binary files differ
diff --git a/dists/msvc10/create_msvc10.bat b/dists/msvc10/create_msvc10.bat
index 5616c2cc8b..be0434fc50 100644
--- a/dists/msvc10/create_msvc10.bat
+++ b/dists/msvc10/create_msvc10.bat
@@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/tests" goto tests
+if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 10
goto done
+:tests
+echo.
+echo Creating tests project files
+echo.
+create_project ..\.. --tests --msvc --msvc-version 10
+goto done
+
:clean_check
echo.
set cleananswer=N
@@ -88,6 +97,7 @@ del /Q *.props > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q scummvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
+del /Q test_runner.cpp > NUL 2>&1
goto done
:done
diff --git a/dists/msvc11/create_msvc11.bat b/dists/msvc11/create_msvc11.bat
index b6a5413e3b..fc5471f46f 100644
--- a/dists/msvc11/create_msvc11.bat
+++ b/dists/msvc11/create_msvc11.bat
@@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/tests" goto tests
+if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 11
goto done
+:tests
+echo.
+echo Creating tests project files
+echo.
+create_project ..\.. --tests --msvc --msvc-version 11
+goto done
+
:clean_check
echo.
set cleananswer=N
@@ -88,6 +97,7 @@ del /Q *.props > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q scummvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
+del /Q test_runner.cpp > NUL 2>&1
goto done
:done
diff --git a/dists/msvc12/create_msvc12.bat b/dists/msvc12/create_msvc12.bat
index fe12a9b288..d99001edb1 100644
--- a/dists/msvc12/create_msvc12.bat
+++ b/dists/msvc12/create_msvc12.bat
@@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/tests" goto tests
+if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 12
goto done
+:tests
+echo.
+echo Creating tests project files
+echo.
+create_project ..\.. --tests --msvc --msvc-version 12
+goto done
+
:clean_check
echo.
set cleananswer=N
@@ -88,6 +97,7 @@ del /Q *.props > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q scummvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
+del /Q test_runner.cpp > NUL 2>&1
goto done
:done
diff --git a/dists/msvc8/create_msvc8.bat b/dists/msvc8/create_msvc8.bat
index 2261c9bcec..1e0d339001 100644
--- a/dists/msvc8/create_msvc8.bat
+++ b/dists/msvc8/create_msvc8.bat
@@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/tests" goto tests
+if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 8
goto done
+:tests
+echo.
+echo Creating tests project files
+echo.
+create_project ..\.. --tests --msvc --msvc-version 8
+goto done
+
:clean_check
echo.
set cleananswer=N
@@ -88,6 +97,7 @@ del /Q *.vsprops > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q scummvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
+del /Q test_runner.cpp
goto done
:done
diff --git a/dists/msvc9/create_msvc9.bat b/dists/msvc9/create_msvc9.bat
index 1622cd9037..34bcccdd7b 100644
--- a/dists/msvc9/create_msvc9.bat
+++ b/dists/msvc9/create_msvc9.bat
@@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
+if "%~1"=="/tests" goto tests
+if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 9
goto done
+:tests
+echo.
+echo Creating tests project files
+echo.
+create_project ..\.. --tests --msvc --msvc-version 9
+goto done
+
:clean_check
echo.
set cleananswer=N
@@ -88,6 +97,7 @@ del /Q *.vsprops > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q scummvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
+del /Q test_runner.cpp
goto done
:done
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index f3fa14c95a..037db3ef62 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -32,6 +32,9 @@ kyra.dat FILE "dists/engine-data/kyra.dat"
#if ENABLE_LURE == STATIC_PLUGIN
lure.dat FILE "dists/engine-data/lure.dat"
#endif
+#if ENABLE_MORTEVIELLE == STATIC_PLUGIN
+mort.dat FILE "dists/engine-data/mort.dat"
+#endif
#if ENABLE_NEVERHOOD == STATIC_PLUGIN
neverhood.dat FILE "dists/engine-data/neverhood.dat"
#endif
diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in
index b7a87f4e3d..c18c18ef63 100644
--- a/dists/scummvm.rc.in
+++ b/dists/scummvm.rc.in
@@ -32,6 +32,9 @@ kyra.dat FILE "dists/engine-data/kyra.dat"
#if ENABLE_LURE == STATIC_PLUGIN
lure.dat FILE "dists/engine-data/lure.dat"
#endif
+#if ENABLE_MORTEVIELLE == STATIC_PLUGIN
+mort.dat FILE "dists/engine-data/mort.dat"
+#endif
#if ENABLE_NEVERHOOD == STATIC_PLUGIN
neverhood.dat FILE "dists/engine-data/neverhood.dat"
#endif
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index 9023548c83..fd0c8dc2da 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -609,7 +609,9 @@ AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, con
}
void AdvancedMetaEngine::initSubSystems(const ADGameDescription *gameDesc) const {
+#ifdef ENABLE_EVENTRECORDER
if (gameDesc) {
g_eventRec.processGameDescription(gameDesc);
}
+#endif
}
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 1c342183cd..57561c00ee 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -598,8 +598,8 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_console = NULL;
_egoHoldKey = false;
-
-
+
+
}
void AgiEngine::initialize() {
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 0c2c3ed3be..f1bb079ffc 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -642,6 +642,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("AGI Piano (v1.0)", "8778b3d89eb93c1d50a70ef06ef10310"),
FANMADE("AGI Quest (v1.46-TJ0)", "1cf1a5307c1a0a405f5039354f679814"),
GAME("tetris", "", "7a874e2db2162e7a4ce31c9130248d8a", 0x2917, GID_FANMADE),
+ FANMADE("AGI Tetris (1998)", "1afcbc25bfafded2d5fb82de9da0bd9a"),
FANMADE_V("AGI Trek (Demo)", "c02882b8a8245b629c91caf7eb78eafe", 0x2440),
FANMADE_F("AGI256 Demo", "79261ac143b2e2773b2753674733b0d5", GF_AGI256),
FANMADE_F("AGI256-2 Demo", "3cad9b3aff1467cebf0c5c5b110985c5", GF_AGI256_2),
diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp
index b7d2801076..17d980dfd8 100644
--- a/engines/agi/preagi_troll.cpp
+++ b/engines/agi/preagi_troll.cpp
@@ -190,6 +190,7 @@ void TrollEngine::inventory() {
break;
case IDI_TRO_MAX_TREASURE:
drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2);
+ break;
default:
sprintf(tmp, IDS_TRO_TREASURE_4, _treasuresLeft);
drawStr(20, 10, kColorDefault, tmp);
@@ -219,6 +220,7 @@ void TrollEngine::waitAnyKeyIntro() {
switch (iMsg) {
case 200:
iMsg = 0;
+ // fall through
case 0:
drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2);
_gfx->doUpdate();
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index bbe9ddd0c6..1be385be37 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -985,6 +985,7 @@ void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
}
break;
}
+ break;
default:
if (!event.kbd.flags) { // if the control/alt/shift keys are not pressed
keyHelp();
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 65f8dd1420..87a1228c6a 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1272,7 +1272,7 @@ protected:
Item *getNextItemPtrStrange();
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
void openTextWindow();
@@ -1311,7 +1311,7 @@ protected:
int countSaveGames();
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_PN : public AGOSEngine {
@@ -1517,8 +1517,8 @@ protected:
virtual void windowPutChar(WindowBlock *window, byte c, byte b = 0);
bool badload(int8 errorNum);
- int loadFile(char *name);
- int saveFile(char *name);
+ int loadFile(const Common::String &name);
+ int saveFile(const Common::String &name);
void getFilename();
void sysftodb();
void dbtosysf();
@@ -1640,7 +1640,7 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Elvira2 : public AGOSEngine_Elvira1 {
@@ -1709,7 +1709,7 @@ protected:
virtual void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
virtual void addArrows(WindowBlock *window, uint8 num);
@@ -1735,7 +1735,7 @@ protected:
virtual void userGame(bool load);
virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 {
@@ -1802,7 +1802,7 @@ protected:
virtual bool confirmOverWrite(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon1 : public AGOSEngine_Waxworks {
@@ -1873,7 +1873,7 @@ protected:
virtual void vcStopAnimation(uint16 zone, uint16 sprite);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon2 : public AGOSEngine_Simon1 {
@@ -1919,7 +1919,7 @@ protected:
virtual void playSpeech(uint16 speechId, uint16 vgaSpriteId);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
#ifdef ENABLE_AGOS2
@@ -2059,7 +2059,7 @@ protected:
void saveUserGame(int slot);
void windowBackSpace(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
virtual void quickLoadOrSave();
};
@@ -2139,7 +2139,7 @@ protected:
void printInfoText(const char *itemText);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 9176412e0e..40c9d1d049 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -272,7 +272,7 @@ void MoviePlayerDXA::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
if (!surface)
return;
- byte *src = (byte *)surface->pixels;
+ const byte *src = (const byte *)surface->getPixels();
dst += y * pitch + x;
do {
@@ -344,7 +344,7 @@ void MoviePlayerDXA::handleNextFrame() {
bool MoviePlayerDXA::processFrame() {
Graphics::Surface *screen = _vm->_system->lockScreen();
- copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch);
+ copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch);
_vm->_system->unlockScreen();
uint32 soundTime = _mixer->getSoundElapsedTime(_bgSound);
@@ -443,7 +443,7 @@ void MoviePlayerSMK::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
if (!surface)
return;
- byte *src = (byte *)surface->pixels;
+ const byte *src = (const byte *)surface->getPixels();
dst += y * pitch + x;
do {
@@ -495,7 +495,7 @@ void MoviePlayerSMK::nextFrame() {
bool MoviePlayerSMK::processFrame() {
Graphics::Surface *screen = _vm->_system->lockScreen();
- copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch);
+ copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch);
_vm->_system->unlockScreen();
uint32 waitTime = getTimeToNextFrame();
diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp
index 262ae44f01..b6b90eefcc 100644
--- a/engines/agos/charset-fontdata.cpp
+++ b/engines/agos/charset-fontdata.cpp
@@ -2924,7 +2924,7 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
Graphics::Surface *screen = _system->lockScreen();
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dstPitch = screen->pitch;
h = 8;
w = 6;
@@ -2961,7 +2961,7 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
error("windowDrawChar: Unknown language %d", _language);
}
} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dstPitch = screen->pitch;
h = 8;
w = 6;
@@ -2986,14 +2986,14 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
error("windowDrawChar: Unknown language %d", _language);
}
} else if (getGameType() == GType_ELVIRA1) {
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dstPitch = screen->pitch;
h = 8;
w = 6;
src = english_elvira1Font + (chr - 32) * 8;
} else {
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dstPitch = screen->pitch;
h = 8;
w = 8;
diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp
index f58f4397b5..eca9728643 100644
--- a/engines/agos/charset.cpp
+++ b/engines/agos/charset.cpp
@@ -362,7 +362,7 @@ void AGOSEngine::windowScroll(WindowBlock *window) {
w = window->width * 8;
h = (window->height -1) * 8;
- dst = (byte *)screen->pixels + window->y * screen->pitch + window->x * 8;
+ dst = (byte *)screen->getBasePtr(window->x * 8, window->y);
src = dst + 8 * screen->pitch;
do {
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index cf3a12ceb8..d27aed29db 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -32,15 +32,15 @@
namespace AGOS {
byte *AGOSEngine::getBackBuf() {
- return (byte *)_backBuf->pixels;
+ return (byte *)_backBuf->getPixels();
}
byte *AGOSEngine::getBackGround() {
- return (byte *)_backGroundBuf->pixels;
+ return (byte *)_backGroundBuf->getPixels();
}
byte *AGOSEngine::getScaleBuf() {
- return (byte *)_scaleBuf->pixels;
+ return (byte *)_scaleBuf->getPixels();
}
#ifdef ENABLE_AGOS2
@@ -226,7 +226,7 @@ void AGOSEngine::animateSprites() {
debug(0, "Using special wall");
uint8 color, h, len;
- byte *dst = (byte *)_window4BackScn->pixels;
+ byte *dst = (byte *)_window4BackScn->getPixels();
color = (_variableArray[293] & 1) ? 13 : 15;
_wallOn = 2;
@@ -256,7 +256,7 @@ void AGOSEngine::animateSprites() {
} else if (getGameType() == GType_ELVIRA2 && _variableArray[71] & 2) {
// Used by the Unholy Barrier spell
uint8 color, h, len;
- byte *dst = (byte *)_window4BackScn->pixels;
+ byte *dst = (byte *)_window4BackScn->getPixels();
color = 1;
_wallOn = 2;
@@ -491,7 +491,7 @@ void AGOSEngine::saveBackGround(VgaSprite *vsp) {
int16 y = vsp->y - _scrollY;
if (_window3Flag == 1) {
- animTable->srcPtr = (const byte *)_window4BackScn->pixels;
+ animTable->srcPtr = (const byte *)_window4BackScn->getPixels();
} else {
int xoffs = (_videoWindows[vsp->windowNum * 4 + 0] * 2 + x) * 8;
int yoffs = (_videoWindows[vsp->windowNum * 4 + 1] + y);
@@ -565,7 +565,7 @@ void AGOSEngine::displayBoxStars() {
if (x_ >= 311)
continue;
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += (((screen->pitch / 4) * y_) * 4) + x_;
@@ -673,7 +673,7 @@ void AGOSEngine::scrollScreen() {
if (getGameType() == GType_SIMON2) {
src = getBackGround();
- dst = (byte *)_window4BackScn->pixels;
+ dst = (byte *)_window4BackScn->getPixels();
for (int i = 0; i < _scrollHeight; i++) {
memcpy(dst, src, _screenWidth);
src += _backGroundBuf->pitch;
@@ -725,7 +725,7 @@ void AGOSEngine::fillBackFromBackGround(uint16 height, uint16 width) {
void AGOSEngine::fillBackFromFront() {
Graphics::Surface *screen = _system->lockScreen();
- byte *src = (byte *)screen->pixels;
+ byte *src = (byte *)screen->getPixels();
byte *dst = getBackBuf();
for (int i = 0; i < _screenHeight; i++) {
@@ -748,7 +748,7 @@ void AGOSEngine::fillBackGroundFromBack() {
void AGOSEngine::fillBackGroundFromFront() {
Graphics::Surface *screen = _system->lockScreen();
- byte *src = (byte *)screen->pixels;
+ byte *src = (byte *)screen->getPixels();
byte *dst = getBackGround();
for (int i = 0; i < _screenHeight; i++) {
@@ -785,7 +785,7 @@ void AGOSEngine::displayScreen() {
Graphics::Surface *screen = _system->lockScreen();
if (getGameType() == GType_PP || getGameType() == GType_FF) {
byte *src = getBackBuf();
- byte *dst = (byte *)screen->pixels;
+ byte *dst = (byte *)screen->getPixels();
for (int i = 0; i < _screenHeight; i++) {
memcpy(dst, src, _screenWidth);
src += _backBuf->pitch;
@@ -798,9 +798,9 @@ void AGOSEngine::displayScreen() {
_window4Flag = 0;
uint16 srcWidth, width, height;
- byte *dst = (byte *)screen->pixels;
+ byte *dst = (byte *)screen->getPixels();
- const byte *src = (const byte *)_window4BackScn->pixels;
+ const byte *src = (const byte *)_window4BackScn->getPixels();
if (_window3Flag == 1) {
src = getBackGround();
}
@@ -831,8 +831,8 @@ void AGOSEngine::displayScreen() {
if (_window6Flag == 2) {
_window6Flag = 0;
- byte *src = (byte *)_window6BackScn->pixels;
- byte *dst = (byte *)screen->pixels + 51 * screen->pitch;
+ byte *src = (byte *)_window6BackScn->getPixels();
+ byte *dst = (byte *)screen->getBasePtr(0, 51);
for (int i = 0; i < 80; i++) {
memcpy(dst, src, _window6BackScn->w);
dst += screen->pitch;
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index cc1c40c207..65c7f7fd77 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -365,7 +365,7 @@ void AGOSEngine::drawStuff(const byte *src, uint xoffs) {
const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 132 : 135;
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels + y * screen->pitch + xoffs;
+ byte *dst = (byte *)screen->getBasePtr(xoffs, y);
for (uint h = 0; h < 6; h++) {
memcpy(dst, src, 4);
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index db0817250b..266fcc9796 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -649,7 +649,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
state->surf2_addr = getBackGround();
state->surf2_pitch = _backGroundBuf->pitch;
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _window4BackScn->pitch;
xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
@@ -666,7 +666,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
state->surf2_addr = getBackGround();
state->surf2_pitch = _backGroundBuf->pitch;
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _videoWindows[18] * 16;
xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
@@ -678,7 +678,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -696,7 +696,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
state->surf2_addr = getBackGround();
state->surf2_pitch = _backGroundBuf->pitch;
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _window4BackScn->pitch;
}
@@ -712,7 +712,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
state->surf2_addr = getBackGround();
state->surf2_pitch = _backGroundBuf->pitch;
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -861,7 +861,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
uint16 xoffs = 0, yoffs = 0;
if (getGameType() == GType_WW) {
if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) {
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _videoWindows[18] * 16;
xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
@@ -873,7 +873,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -881,7 +881,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
}
} else if (getGameType() == GType_ELVIRA2) {
if (_windowNum == 4 || _windowNum >= 10) {
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _videoWindows[18] * 16;
xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
@@ -893,7 +893,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -901,19 +901,19 @@ void AGOSEngine::drawImage(VC10_state *state) {
}
} else if (getGameType() == GType_ELVIRA1) {
if (_windowNum == 6) {
- state->surf_addr = (byte *)_window6BackScn->pixels;
+ state->surf_addr = (byte *)_window6BackScn->getPixels();
state->surf_pitch = _window6BackScn->pitch;
xoffs = state->x * 8;
yoffs = state->y;
} else if (_windowNum == 2 || _windowNum == 3) {
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
yoffs = vlut[1] + state->y;
} else {
- state->surf_addr = (byte *)_window4BackScn->pixels;
+ state->surf_addr = (byte *)_window4BackScn->getPixels();
state->surf_pitch = _videoWindows[18] * 16;
xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
@@ -926,7 +926,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
_window4Flag = 1;
}
} else {
- state->surf_addr = (byte *)screen->pixels;
+ state->surf_addr = (byte *)screen->getPixels();
state->surf_pitch = screen->pitch;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -973,7 +973,7 @@ void AGOSEngine::horizontalScroll(VC10_state *state) {
vcWriteVar(251, _scrollX);
if (getGameType() == GType_SIMON2) {
- dst = (byte *)_window4BackScn->pixels;
+ dst = (byte *)_window4BackScn->getPixels();
dstPitch = _window4BackScn->pitch;
} else {
dst = getBackBuf();
@@ -1375,10 +1375,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
} else if (getGameType() == GType_SIMON1 && (getFeatures() & GF_DEMO)) {
// The DOS Floppy demo was based off Waxworks engine
if (updateWindow == 4 || updateWindow >= 10) {
- src = (byte *)_window4BackScn->pixels;
+ src = (byte *)_window4BackScn->getPixels();
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3 || updateWindow == 9) {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
} else {
_system->unlockScreen();
@@ -1387,13 +1387,13 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
}
} else if (getGameType() == GType_SIMON1) {
if (updateWindow == 4) {
- src = (byte *)_window4BackScn->pixels;
+ src = (byte *)_window4BackScn->getPixels();
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow >= 10) {
- src = (byte *)_window4BackScn->pixels + xoffs + yoffs * 320;
+ src = (byte *)_window4BackScn->getBasePtr(xoffs, yoffs);
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 0) {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
} else {
_system->unlockScreen();
@@ -1402,10 +1402,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
}
} else if (getGameType() == GType_WW) {
if (updateWindow == 4 || updateWindow >= 10) {
- src = (byte *)_window4BackScn->pixels;
+ src = (byte *)_window4BackScn->getPixels();
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3 || updateWindow == 9) {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
} else {
_system->unlockScreen();
@@ -1414,10 +1414,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
}
} else if (getGameType() == GType_ELVIRA2) {
if (updateWindow == 4 || updateWindow >= 10) {
- src = (byte *)_window4BackScn->pixels;
+ src = (byte *)_window4BackScn->getPixels();
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3) {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
} else {
_system->unlockScreen();
@@ -1427,17 +1427,17 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
} else if (getGameType() == GType_ELVIRA1) {
if (updateWindow == 6) {
_window6Flag = 1;
- src = (byte *)_window6BackScn->pixels;
+ src = (byte *)_window6BackScn->getPixels();
srcWidth = 48;
} else if (updateWindow == 2 || updateWindow == 3) {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
} else {
- src = (byte *)_window4BackScn->pixels;
+ src = (byte *)_window4BackScn->getPixels();
srcWidth = _videoWindows[18] * 16;
}
} else {
- src = (byte *)screen->pixels + yoffs * screen->pitch + xoffs;
+ src = (byte *)screen->getBasePtr(xoffs, yoffs);
srcWidth = screen->pitch;
}
@@ -1451,13 +1451,13 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vgaSpriteId, bool specialCas
if (getGameType() == GType_PN && !_wiped && !specialCase) {
uint8 color = (getPlatform() == Common::kPlatformDOS) ? 7 : 15;
- dst = (byte *)screen->pixels + 48;
+ dst = (byte *)screen->getBasePtr(48, 0);
memset(dst, color, 224);
- dst = (byte *)screen->pixels + 132 * screen->pitch + 48;
+ dst = (byte *)screen->getBasePtr(48, 132);
memset(dst, color, 224);
} else if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette) {
- dst = (byte *)screen->pixels + 133 * screen->pitch;
+ dst = (byte *)screen->getBasePtr(0, 133);
for (int h = 0; h < 67; h++) {
for (int w = 0; w < _screenWidth; w++)
@@ -1479,7 +1479,7 @@ void AGOSEngine::drawEdging() {
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels + 136 * screen->pitch;
+ dst = (byte *)screen->getBasePtr(0, 136);
uint8 len = 52;
while (len--) {
@@ -1488,7 +1488,7 @@ void AGOSEngine::drawEdging() {
dst += screen->pitch;
}
- dst = (byte *)screen->pixels + 187 * screen->pitch;
+ dst = (byte *)screen->getBasePtr(0, 187);
memset(dst, color, _screenWidth);
_system->unlockScreen();
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 0ee1d62fde..6d4192da2a 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -202,7 +202,7 @@ void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y)
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += 110;
dst += x;
@@ -228,7 +228,7 @@ void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y)
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += (x + window->x) * 8;
dst += (y * 25 + window->y) * screen->pitch;
@@ -256,7 +256,7 @@ void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += (x + window->x) * 8;
dst += (y * 20 + window->y) * screen->pitch;
@@ -284,7 +284,7 @@ void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += (x + window->x) * 8;
dst += (y * 8 + window->y) * screen->pitch;
@@ -312,7 +312,7 @@ void AGOSEngine_Elvira1::drawIcon(WindowBlock *window, uint icon, uint x, uint y
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
dst += (x + window->x) * 8;
dst += (y * 8 + window->y) * screen->pitch;
@@ -339,7 +339,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) {
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels + y * screen->pitch + x * 8;
+ dst = (byte *)screen->getBasePtr(x * 8, y);
src = _iconFilePtr + icon * 146;
if (icon == 0xFF) {
@@ -951,7 +951,7 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) {
}
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels + y * screen->pitch + x * 8;
+ byte *dst = (byte *)screen->getBasePtr(x * 8, y);
for (h = 0; h < 19; h++) {
for (w = 0; w < 16; w++) {
@@ -1042,7 +1042,7 @@ static const byte hitBarData[12 * 7] = {
// Personal Nightmare specific
void AGOSEngine_PN::drawIconHitBar() {
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels + 3 * screen->pitch + 6 * 8;
+ byte *dst = (byte *)screen->getBasePtr(6 * 8, 3);
const byte *src = hitBarData;
uint8 color = (getPlatform() == Common::kPlatformDOS) ? 7 : 15;
diff --git a/engines/agos/menus.cpp b/engines/agos/menus.cpp
index a0d2bdcaa0..85c50e421b 100644
--- a/engines/agos/menus.cpp
+++ b/engines/agos/menus.cpp
@@ -164,7 +164,7 @@ void AGOSEngine::unlightMenuStrip() {
mouseOff();
Graphics::Surface *screen = _system->lockScreen();
- src = (byte *)screen->pixels + 8 * screen->pitch + 272;
+ src = (byte *)screen->getBasePtr(272, 8);
w = 48;
h = 82;
@@ -192,7 +192,7 @@ void AGOSEngine::lightMenuBox(uint hitarea) {
mouseOff();
Graphics::Surface *screen = _system->lockScreen();
- src = (byte *)screen->pixels + ha->y * screen->pitch + ha->x;
+ src = (byte *)screen->getBasePtr(ha->x, ha->y);
w = ha->width;
h = ha->height;
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 48671390f0..8eb7f066b3 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -33,32 +33,35 @@
namespace AGOS {
+
+// FIXME: This code counts savegames, but callers in many cases assume
+// that the return value + 1 indicates an empty slot.
int AGOSEngine::countSaveGames() {
Common::InSaveFile *f = NULL;
Common::StringArray filenames;
uint i = 1;
- char slot[4];
int slotNum;
bool marks[256];
- char *prefix = genSaveName(998);
- prefix[strlen(prefix)-3] = '*';
- prefix[strlen(prefix)-2] = '\0';
+ // Get the name of (possibly non-existent) savegame slot 998, and replace
+ // the extension by * to get a pattern.
+ Common::String tmp = genSaveName(998);
+ assert(tmp.size() >= 4 && tmp[tmp.size()-4] == '.');
+ Common::String prefix = Common::String(tmp.c_str(), tmp.size()-3) + "*";
+
memset(marks, false, 256 * sizeof(bool)); //assume no savegames for this title
filenames = _saveFileMan->listSavefiles(prefix);
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
- slot[0] = file->c_str()[file->size()-3];
- slot[1] = file->c_str()[file->size()-2];
- slot[2] = file->c_str()[file->size()-1];
- slot[3] = '\0';
-
- slotNum = atoi(slot);
+ assert(file->size() >= 4);
+ slotNum = atoi(file->c_str() + file->size() - 3);
if (slotNum >= 0 && slotNum < 256)
marks[slotNum] = true; //mark this slot as valid
}
+ // FIXME: Why does this already try to actually open the savegames?
+ // Historical accident?
while (i < 256) {
if (marks[i] &&
(f = _saveFileMan->openForLoading(genSaveName(i)))) {
@@ -72,68 +75,46 @@ int AGOSEngine::countSaveGames() {
}
#ifdef ENABLE_AGOS2
-char *AGOSEngine_PuzzlePack::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_PuzzlePack::genSaveName(int slot) const {
if (getGameId() == GID_DIMP)
- sprintf(buf, "dimp.sav");
+ return "dimp.sav";
else
- sprintf(buf, "swampy.sav");
-
- return buf;
+ return "swampy.sav";
}
-char *AGOSEngine_Feeble::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "feeble.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Feeble::genSaveName(int slot) const {
+ return Common::String::format("feeble.%.3d", slot);
}
#endif
-char *AGOSEngine_Simon2::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon2.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon2::genSaveName(int slot) const {
+ return Common::String::format("simon2.%.3d", slot);
}
-char *AGOSEngine_Simon1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon1::genSaveName(int slot) const {
+ return Common::String::format("simon1.%.3d", slot);
}
-char *AGOSEngine_Waxworks::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Waxworks::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "waxworks-pc.%.3d", slot);
+ return Common::String::format("waxworks-pc.%.3d", slot);
else
- sprintf(buf, "waxworks.%.3d", slot);
-
- return buf;
+ return Common::String::format("waxworks.%.3d", slot);
}
-char *AGOSEngine_Elvira2::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Elvira2::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "elvira2-pc.%.3d", slot);
+ return Common::String::format("elvira2-pc.%.3d", slot);
else
- sprintf(buf, "elvira2.%.3d", slot);
-
- return buf;
+ return Common::String::format("elvira2.%.3d", slot);
}
-char *AGOSEngine_Elvira1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "elvira1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Elvira1::genSaveName(int slot) const {
+ return Common::String::format("elvira1.%.3d", slot);
}
-char *AGOSEngine::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "pn.%.3d", slot);
- return buf;
+Common::String AGOSEngine::genSaveName(int slot) const {
+ return Common::String::format("pn.%.3d", slot);
}
#ifdef ENABLE_AGOS2
@@ -177,12 +158,12 @@ void AGOSEngine::quickLoadOrSave() {
waitForSync(1122);
}
- char *filename = genSaveName(_saveLoadSlot);
+ Common::String filename = genSaveName(_saveLoadSlot);
if (_saveLoadType == 2) {
Subroutine *sub;
success = loadGame(genSaveName(_saveLoadSlot));
if (!success) {
- buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename.c_str());
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
drawIconArray(2, me(), 0, 0);
setBitFlag(97, true);
@@ -217,7 +198,7 @@ void AGOSEngine::quickLoadOrSave() {
} else {
success = saveGame(_saveLoadSlot, _saveLoadName);
if (!success)
- buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename.c_str());
}
if (!success) {
@@ -225,7 +206,7 @@ void AGOSEngine::quickLoadOrSave() {
dialog.runModal();
} else if (_saveLoadType == 1) {
- buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename);
+ buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename.c_str());
GUI::TimedMessageDialog dialog(buf, 1500);
dialog.runModal();
@@ -1041,7 +1022,7 @@ void writeItemID(Common::WriteStream *f, uint16 val) {
f->writeUint32BE(val - 1);
}
-bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i;
@@ -1215,7 +1196,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
return result;
}
-bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
@@ -1633,7 +1614,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadFile(char *name) {
+int AGOSEngine_PN::loadFile(const Common::String &name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1666,7 +1647,7 @@ int AGOSEngine_PN::loadFile(char *name) {
return 0;
}
-int AGOSEngine_PN::saveFile(char *name) {
+int AGOSEngine_PN::saveFile(const Common::String &name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 60a1376f25..e98cd2795a 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -370,7 +370,7 @@ void AGOSEngine_PN::opn_opcode30() {
void AGOSEngine_PN::opn_opcode31() {
int a, slot = 0;
- char bf[60];
+ Common::String bf;
if ((a = varval()) > 2) {
setScriptReturn(false);
@@ -381,10 +381,10 @@ void AGOSEngine_PN::opn_opcode31() {
case 0:
getFilename();
slot = matchSaveGame(_saveFile, countSaveGames());
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
@@ -404,7 +404,7 @@ void AGOSEngine_PN::opn_opcode31() {
}
void AGOSEngine_PN::opn_opcode32() {
- char bf[60];
+ Common::String bf;
int a, slot;
a = varval();
@@ -419,12 +419,12 @@ void AGOSEngine_PN::opn_opcode32() {
getFilename();
slot = matchSaveGame(_saveFile, curSlot);
if (slot != -1)
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
else
- strcpy(bf, genSaveName(curSlot));
+ bf = genSaveName(curSlot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp
index 93077ed83e..f5b57a01c8 100644
--- a/engines/agos/verb.cpp
+++ b/engines/agos/verb.cpp
@@ -973,7 +973,7 @@ void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) {
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- src = (byte *)screen->pixels + ha->y * screen->pitch + ha->x;
+ src = (byte *)screen->getBasePtr(ha->x, ha->y);
// WORKAROUND: Hitareas for saved game names aren't adjusted for scrolling locations
if (getGameType() == GType_SIMON2 && ha->id >= 208 && ha->id <= 213) {
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index 8541f579d6..cc5ede5f2c 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -1179,7 +1179,7 @@ void AGOSEngine::vc32_saveScreen() {
if (getGameType() == GType_PN) {
Graphics::Surface *screen = _system->lockScreen();
byte *dst = getBackGround();
- byte *src = (byte *)screen->pixels;
+ byte *src = (byte *)screen->getPixels();
for (int i = 0; i < _screenHeight; i++) {
memcpy(dst, src, _screenWidth);
dst += _backGroundBuf->pitch;
@@ -1193,7 +1193,7 @@ void AGOSEngine::vc32_saveScreen() {
uint16 height = _videoWindows[4 * 4 + 3];
byte *dst = (byte *)_backGroundBuf->getBasePtr(xoffs, yoffs);
- byte *src = (byte *)_window4BackScn->pixels;
+ byte *src = (byte *)_window4BackScn->getPixels();
uint16 srcWidth = _videoWindows[4 * 4 + 2] * 16;
for (; height > 0; height--) {
memcpy(dst, src, width);
@@ -1247,7 +1247,7 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) {
if (getGameType() == GType_ELVIRA1 && num == 3) {
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels;
+ byte *dst = (byte *)screen->getPixels();
for (int i = 0; i < _screenHeight; i++) {
memset(dst, color, _screenWidth);
dst += screen->pitch;
@@ -1258,7 +1258,10 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) {
uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16;
uint16 yoffs = (vlut[1] - _videoWindows[17]);
uint16 dstWidth = _videoWindows[18] * 16;
- byte *dst = (byte *)_window4BackScn->pixels + xoffs + yoffs * dstWidth;
+ // TODO: Is there any known connection between dstWidth and the pitch
+ // of the _window4BackScn Surface? If so, we might be able to pass
+ // yoffs as proper y parameter to getBasePtr.
+ byte *dst = (byte *)_window4BackScn->getBasePtr(xoffs, 0) + yoffs * dstWidth;
setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index d4aafd3d7b..4eb337c687 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -76,7 +76,7 @@ void AGOSEngine::vc45_setWindowPalette() {
uint8 height = vlut[3];
if (num == 4) {
- byte *dst = (byte *)_window4BackScn->pixels;
+ byte *dst = (byte *)_window4BackScn->getPixels();
for (uint8 h = 0; h < height; h++) {
for (uint8 w = 0; w < width; w++) {
@@ -223,11 +223,11 @@ void AGOSEngine::vc53_dissolveIn() {
uint16 count = dissolveCheck * 2;
while (count--) {
Graphics::Surface *screen = _system->lockScreen();
- byte *dstPtr = (byte *)screen->pixels + x + y * screen->pitch;
+ byte *dstPtr = (byte *)screen->getBasePtr(x, y);
yoffs = _rnd.getRandomNumber(dissolveY);
dst = dstPtr + yoffs * screen->pitch;
- src = (byte *)_window4BackScn->pixels + yoffs * _window4BackScn->pitch;
+ src = (byte *)_window4BackScn->getBasePtr(0, yoffs);
xoffs = _rnd.getRandomNumber(dissolveX);
dst += xoffs;
@@ -296,7 +296,7 @@ void AGOSEngine::vc54_dissolveOut() {
uint16 count = dissolveCheck * 2;
while (count--) {
Graphics::Surface *screen = _system->lockScreen();
- byte *dstPtr = (byte *)screen->pixels + x + y * screen->pitch;
+ byte *dstPtr = (byte *)screen->getBasePtr(x, y);
color |= dstPtr[0] & 0xF0;
yoffs = _rnd.getRandomNumber(dissolveY);
@@ -378,7 +378,7 @@ void AGOSEngine::fullFade() {
void AGOSEngine::vc56_fullScreen() {
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels;
+ byte *dst = (byte *)screen->getPixels();
byte *src = _curVgaFile2 + 800;
for (int i = 0; i < _screenHeight; i++) {
diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp
index 1e7b2ba060..b7f80ebf91 100644
--- a/engines/agos/vga_pn.cpp
+++ b/engines/agos/vga_pn.cpp
@@ -155,7 +155,7 @@ void AGOSEngine::vc48_specialEffect() {
if (getPlatform() == Common::kPlatformDOS) {
if (num == 1) {
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels;
+ byte *dst = (byte *)screen->getPixels();
for (uint h = 0; h < _screenHeight; h++) {
for (uint w = 0; w < _screenWidth; w++) {
@@ -205,7 +205,7 @@ void AGOSEngine_PN::clearVideoWindow(uint16 num, uint16 color) {
uint16 yoffs = vlut[1];
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels + xoffs + yoffs * screen->pitch;
+ byte *dst = (byte *)screen->getBasePtr(xoffs, yoffs);
for (uint h = 0; h < vlut[3]; h++) {
memset(dst, color, vlut[2] * 16);
dst += screen->pitch;
diff --git a/engines/agos/vga_s2.cpp b/engines/agos/vga_s2.cpp
index 9b9ed4e297..e0780b491a 100644
--- a/engines/agos/vga_s2.cpp
+++ b/engines/agos/vga_s2.cpp
@@ -213,7 +213,10 @@ void AGOSEngine_Simon2::clearVideoWindow(uint16 num, uint16 color) {
uint16 xoffs = vlut[0] * 16;
uint16 yoffs = vlut[1];
uint16 dstWidth = _videoWindows[18] * 16;
- byte *dst = (byte *)_window4BackScn->pixels + xoffs + yoffs * dstWidth;
+ // TODO: Is there any known connection between dstWidth and the pitch
+ // of the _window4BackScn Surface? If so, we might be able to pass
+ // yoffs as proper y parameter to getBasePtr.
+ byte *dst = (byte *)_window4BackScn->getBasePtr(xoffs, 0) + yoffs * dstWidth;
setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp
index c74f0cf52b..ca93fa9fec 100644
--- a/engines/agos/vga_ww.cpp
+++ b/engines/agos/vga_ww.cpp
@@ -143,7 +143,7 @@ void AGOSEngine::vc61() {
uint h, tmp;
Graphics::Surface *screen = _system->lockScreen();
- dstPtr = (byte *)screen->pixels;
+ dstPtr = (byte *)screen->getPixels();
if (a == 6) {
src = _curVgaFile2 + 800;
diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp
index 0365c736d8..892df92554 100644
--- a/engines/agos/window.cpp
+++ b/engines/agos/window.cpp
@@ -170,7 +170,7 @@ void AGOSEngine::colorBlock(WindowBlock *window, uint16 x, uint16 y, uint16 w, u
_videoLockOut |= 0x8000;
Graphics::Surface *screen = _system->lockScreen();
- byte *dst = (byte *)screen->pixels + y * screen->pitch + x;
+ byte *dst = (byte *)screen->getBasePtr(x, y);
uint8 color = window->fillColor;
if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
@@ -232,7 +232,7 @@ void AGOSEngine::restoreBlock(uint16 x, uint16 y, uint16 w, uint16 h) {
uint i;
Graphics::Surface *screen = _system->lockScreen();
- dst = (byte *)screen->pixels;
+ dst = (byte *)screen->getPixels();
src = getBackGround();
dst += y * screen->pitch;
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index f4f1cd3e0b..ae4dee6090 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -358,7 +358,7 @@ void CGEEngine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &he
// Create a thumbnail and save it
Graphics::Surface *thumb = new Graphics::Surface();
Graphics::Surface *s = _vga->_page[0];
- ::createThumbnail(thumb, (const byte *)s->pixels, kScrWidth, kScrHeight, thumbPalette);
+ ::createThumbnail(thumb, (const byte *)s->getPixels(), kScrWidth, kScrHeight, thumbPalette);
Graphics::saveThumbnail(*out, *thumb);
thumb->free();
delete thumb;
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index d29c1224fd..3b01421903 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -121,7 +121,7 @@ static const CgeGameDescription gameDescriptions[] = {
"sfinx", "Sfinx Freeware",
{
{"vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024},
- {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844},
+ {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844},
AD_LISTEND
},
Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
diff --git a/engines/cge/snail.cpp b/engines/cge/snail.cpp
index edb8972040..b9030efb4d 100644
--- a/engines/cge/snail.cpp
+++ b/engines/cge/snail.cpp
@@ -494,7 +494,7 @@ void CGEEngine::snGame(Sprite *spr, int num) {
_sprK3->step(newRandom(6));
// check the ALT key as it's the solution of the puzzle
- // the test has been restricted to some specific OSes
+ // the test has been restricted to some specific OSes
// in order to avoid some obvious issues (like Android, iOS, NDS, N64...)
// Not perfect, but at least better than nothing.
#if defined(WIN32) || defined(UNIX) || defined(MACOSX) || defined(MOTOEZX) || defined(LINUPY) || defined(LINUXMOTO_SDL)
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index 56a0754527..c0407cab42 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -826,7 +826,7 @@ void Vga::update() {
}
}
- g_system->copyRectToScreen(Vga::_page[0]->getBasePtr(0, 0), kScrWidth, 0, 0, kScrWidth, kScrHeight);
+ g_system->copyRectToScreen(Vga::_page[0]->getPixels(), kScrWidth, 0, 0, kScrWidth, kScrHeight);
g_system->updateScreen();
}
@@ -845,7 +845,7 @@ void Bitmap::xShow(int16 x, int16 y) {
debugC(4, kCGEDebugBitmap, "Bitmap::xShow(%d, %d)", x, y);
const byte *srcP = (const byte *)_v;
- byte *destEndP = (byte *)_vm->_vga->_page[1]->pixels + (kScrWidth * kScrHeight);
+ byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
byte *lookupTable = _m;
// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
@@ -898,7 +898,7 @@ void Bitmap::show(int16 x, int16 y) {
debugC(5, kCGEDebugBitmap, "Bitmap::show(%d, %d)", x, y);
const byte *srcP = (const byte *)_v;
- byte *destEndP = (byte *)_vm->_vga->_page[1]->pixels + (kScrWidth * kScrHeight);
+ byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 33a5356b3a..7d8022455a 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -23,7 +23,7 @@
#ifndef COMPOSER_H
#define COMPOSER_H
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/random.h"
#include "common/system.h"
#include "common/debug.h"
@@ -174,7 +174,7 @@ private:
Common::List<Sprite> _sprites;
uint _directoriesToStrip;
- Common::ConfigFile _bookIni;
+ Common::INIFile _bookIni;
Common::String _bookGroup;
Common::List<Library> _libraries;
Common::Array<PendingPageChange> _pendingPageChanges;
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index 2b68fac233..caf3ba3a40 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -39,7 +39,7 @@ bool Sprite::contains(const Common::Point &pos) const {
return false;
if (adjustedPos.y < 0 || adjustedPos.y >= _surface.h)
return false;
- byte *pixels = (byte *)_surface.pixels;
+ const byte *pixels = (const byte *)_surface.getPixels();
return (pixels[(_surface.h - adjustedPos.y - 1) * _surface.w + adjustedPos.x] != 0);
}
@@ -541,7 +541,7 @@ void ComposerEngine::redraw() {
for (uint i = 0; i < _dirtyRects.size(); i++) {
const Common::Rect &rect = _dirtyRects[i];
- byte *pixels = (byte *)_screen.pixels + (rect.top * _screen.pitch) + rect.left;
+ byte *pixels = (byte *)_screen.getBasePtr(rect.left, rect.top);
_system->copyRectToScreen(pixels, _screen.pitch, rect.left, rect.top, rect.width(), rect.height());
}
_system->updateScreen();
@@ -794,7 +794,7 @@ bool ComposerEngine::initSprite(Sprite &sprite) {
if (width > 0 && height > 0) {
sprite._surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- decompressBitmap(type, stream, (byte *)sprite._surface.pixels, size, width, height);
+ decompressBitmap(type, stream, (byte *)sprite._surface.getPixels(), size, width, height);
} else {
// there are some sprites (e.g. a -998x-998 one in Gregory's title screen)
// which have an invalid size, but the original engine doesn't notice for
@@ -814,13 +814,13 @@ void ComposerEngine::drawSprite(const Sprite &sprite) {
int y = sprite._pos.y;
// incoming data is BMP-style (bottom-up), so flip it
- byte *pixels = (byte *)_screen.pixels;
+ byte *pixels = (byte *)_screen.getPixels();
for (int j = 0; j < sprite._surface.h; j++) {
if (j + y < 0)
continue;
if (j + y >= _screen.h)
break;
- byte *in = (byte *)sprite._surface.pixels + (sprite._surface.h - j - 1) * sprite._surface.w;
+ const byte *in = (const byte *)sprite._surface.getBasePtr(0, sprite._surface.h - j - 1);
byte *out = pixels + ((j + y) * _screen.w) + x;
for (int i = 0; i < sprite._surface.w; i++)
if ((x + i >= 0) && (x + i < _screen.w) && in[i])
diff --git a/engines/configure.engines b/engines/configure.engines
index d9360febc4..195cdda6c7 100644
--- a/engines/configure.engines
+++ b/engines/configure.engines
@@ -26,6 +26,7 @@ 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"
diff --git a/engines/draci/screen.cpp b/engines/draci/screen.cpp
index 8c1a0c40f7..e43e367300 100644
--- a/engines/draci/screen.cpp
+++ b/engines/draci/screen.cpp
@@ -110,7 +110,7 @@ void Screen::copyToScreen() {
// If a full update is needed, update the whole screen
if (_surface->needsFullUpdate()) {
- byte *ptr = (byte *)_surface->getBasePtr(0, 0);
+ byte *ptr = (byte *)_surface->getPixels();
_vm->_system->copyRectToScreen(ptr, kScreenWidth,
0, 0, kScreenWidth, kScreenHeight);
@@ -138,7 +138,7 @@ void Screen::copyToScreen() {
* Clears the screen and marks the whole screen dirty.
*/
void Screen::clearScreen() {
- byte *ptr = (byte *)_surface->getBasePtr(0, 0);
+ byte *ptr = (byte *)_surface->getPixels();
_surface->markDirty();
diff --git a/engines/draci/surface.cpp b/engines/draci/surface.cpp
index 8380f8777b..3676c6edac 100644
--- a/engines/draci/surface.cpp
+++ b/engines/draci/surface.cpp
@@ -80,7 +80,7 @@ void Surface::markClean() {
* @brief Fills the surface with the specified color
*/
void Surface::fill(uint color) {
- byte *ptr = (byte *)getBasePtr(0, 0);
+ byte *ptr = (byte *)getPixels();
memset(ptr, color, w * h);
}
diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp
index 9d5d6550fa..e0983809fa 100644
--- a/engines/drascula/actors.cpp
+++ b/engines/drascula/actors.cpp
@@ -135,7 +135,7 @@ void DrasculaEngine::startWalking() {
else
characterMoved = 0;
}
- startTime = getTime();
+ _startTime = getTime();
}
void DrasculaEngine::moveCharacters() {
@@ -239,7 +239,7 @@ void DrasculaEngine::moveCharacters() {
factor_red[curY + curHeight], frontSurface, screenSurface);
}
} else if (characterMoved == 1) {
- curPos[0] = _frameX[num_frame];
+ curPos[0] = _frameX[_characterFrame];
curPos[1] = frame_y + DIF_MASK_HARE;
curPos[2] = curX;
curPos[3] = curY;
@@ -369,13 +369,11 @@ void DrasculaEngine::quadrant_4() {
}
void DrasculaEngine::increaseFrameNum() {
- timeDiff = getTime() - startTime;
-
- if (timeDiff >= 6) {
- startTime = getTime();
- num_frame++;
- if (num_frame == 6)
- num_frame = 0;
+ if (getTime() - _startTime >= 6) {
+ _startTime = getTime();
+ _characterFrame++;
+ if (_characterFrame == 6)
+ _characterFrame = 0;
if (curDirection == kDirectionUp) {
curX -= stepX;
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 52cab6cd32..1145c8c3ff 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -426,7 +426,7 @@ void DrasculaEngine::animation_2_1() {
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
- roomNumber = 16;
+ _roomNumber = 16;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
@@ -512,7 +512,7 @@ void DrasculaEngine::animation_2_1() {
// room number to -1 for the same purpose
// Also check animation_9_6(), where the same hack was used by
// the original
- roomNumber = -1;
+ _roomNumber = -1;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
pause(8);
@@ -734,7 +734,7 @@ void DrasculaEngine::animation_14_2() {
void DrasculaEngine::asco() {
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
black();
updateRoom();
updateScreen();
@@ -1661,7 +1661,7 @@ void DrasculaEngine::animation_9_6() {
// We set the room number to -1 for the same purpose.
// Also check animation_2_1(), where the same hack was used
// by the original
- roomNumber = -2;
+ _roomNumber = -2;
loadPic("nota2.alg", bgSurface, HALF_PAL);
black();
trackProtagonist = 1;
@@ -2176,9 +2176,9 @@ void DrasculaEngine::animation_5_4(){
void DrasculaEngine::animation_6_4() {
debug(4, "animation_6_4()");
- int prevRoom = roomNumber;
+ int prevRoom = _roomNumber;
- roomNumber = 26;
+ _roomNumber = 26;
clearRoom();
loadPic(26, bgSurface, HALF_PAL);
loadPic("aux26.alg", drawSurface3);
@@ -2191,11 +2191,11 @@ void DrasculaEngine::animation_6_4() {
updateScreen();
pause(40);
talk_igor(26, kIgorFront);
- roomNumber = prevRoom;
+ _roomNumber = prevRoom;
clearRoom();
loadPic(96, frontSurface);
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
selectVerb(kVerbNone);
updateRoom();
}
@@ -2224,7 +2224,7 @@ void DrasculaEngine::activatePendulum() {
flags[1] = 2;
hare_se_ve = 0;
- roomNumber = 102;
+ _roomNumber = 102;
loadPic(102, bgSurface, HALF_PAL);
loadPic("an_p1.alg", drawSurface3);
loadPic("an_p2.alg", extraSurface);
diff --git a/engines/drascula/console.cpp b/engines/drascula/console.cpp
index 426b2ade67..c0d2748ec3 100644
--- a/engines/drascula/console.cpp
+++ b/engines/drascula/console.cpp
@@ -41,7 +41,7 @@ bool Console::Cmd_Room(int argc, const char **argv) {
int roomNum = atoi(argv[1]);
- _vm->loadedDifferentChapter = 0;
+ _vm->_loadedDifferentChapter = false;
_vm->enterRoom(roomNum);
_vm->selectVerb(kVerbNone);
_vm->clearRoom();
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index d045d683fc..95a5f7d87f 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -216,7 +216,7 @@ void DrasculaEngine::converse(int index) {
phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3);
phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected);
- if (mouseY > 0 && mouseY < phrase1_bottom) {
+ if (_mouseY > 0 && _mouseY < phrase1_bottom) {
if (game1 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game1 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -224,13 +224,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase1, 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game1 = kDialogOptionClicked;
talk(phrase1, sound1);
response(answer1);
}
- } else if (mouseY > phrase1_bottom && mouseY < phrase2_bottom) {
+ } else if (_mouseY > phrase1_bottom && _mouseY < phrase2_bottom) {
if (game2 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game2 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -238,13 +238,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game2 = kDialogOptionClicked;
talk(phrase2, sound2);
response(answer2);
}
- } else if (mouseY > phrase2_bottom && mouseY < phrase3_bottom) {
+ } else if (_mouseY > phrase2_bottom && _mouseY < phrase3_bottom) {
if (game3 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game3 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -252,16 +252,16 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game3 = kDialogOptionClicked;
talk(phrase3, sound3);
response(answer3);
}
- } else if (mouseY > phrase3_bottom && mouseY < phrase4_bottom) {
+ } else if (_mouseY > phrase3_bottom && _mouseY < phrase4_bottom) {
print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
talk(phrase4, sound4);
breakOut = 1;
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 804881cf9a..cde00baa32 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -91,10 +91,10 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_color = 0;
blinking = 0;
- mouseX = 0;
- mouseY = 0;
- leftMouseButton = 0;
- rightMouseButton = 0;
+ _mouseX = 0;
+ _mouseY = 0;
+ _leftMouseButton = 0;
+ _rightMouseButton = 0;
*textName = 0;
_rnd = new Common::RandomSource("drascula");
@@ -197,7 +197,7 @@ Common::Error DrasculaEngine::run() {
syncSoundSettings();
currentChapter = 1; // values from 1 to 6 will start each part of game
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
setTotalPlayTime(0);
// Check if a save is loaded from the launcher
@@ -218,7 +218,7 @@ Common::Error DrasculaEngine::run() {
curX = -1;
characterMoved = 0;
trackProtagonist = 3;
- num_frame = 0;
+ _characterFrame = 0;
hare_se_ve = 1;
checkFlags = 1;
doBreak = 0;
@@ -231,9 +231,6 @@ Common::Error DrasculaEngine::run() {
curWidth = CHARACTER_WIDTH;
feetHeight = FEET_HEIGHT;
- talkHeight = TALK_HEIGHT;
- talkWidth = TALK_WIDTH;
-
hasAnswer = 0;
savedTime = 0;
breakOut = 0;
@@ -246,7 +243,7 @@ Common::Error DrasculaEngine::run() {
globalSpeed = 0;
curExcuseLook = 0;
curExcuseAction = 0;
- roomNumber = 0;
+ _roomNumber = 0;
for (i = 0; i < 8; i++)
actorFrames[i] = 0;
@@ -268,7 +265,7 @@ Common::Error DrasculaEngine::run() {
loadPic("aux13.alg", bgSurface, COMPLETE_PAL);
loadPic(96, frontSurface);
} else if (currentChapter == 4) {
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_castle();
loadPic(96, frontSurface);
clearRoom();
@@ -330,7 +327,7 @@ void DrasculaEngine::endChapter() {
bool DrasculaEngine::runCurrentChapter() {
int n;
- rightMouseButton = 0;
+ _rightMouseButton = 0;
previousMusic = -1;
@@ -360,14 +357,14 @@ bool DrasculaEngine::runCurrentChapter() {
if (currentChapter == 1) {
pickObject(28);
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_1_1();
selectVerb(kVerbNone);
loadPic("2aux62.alg", drawSurface2);
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter != 0) {
+ if (_loadedDifferentChapter) {
if (!loadGame(_currentSaveSlot)) {
return true;
}
@@ -383,7 +380,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemPhone);
trackProtagonist = 3;
objExit = 162;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(14);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -401,7 +398,7 @@ bool DrasculaEngine::runCurrentChapter() {
flags[1] = 1;
trackProtagonist = 1;
objExit = 99;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(20);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -415,7 +412,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemReefer2);
addObject(kItemOneCoin2);
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(21);
trackProtagonist = 0;
curX = 235;
@@ -437,7 +434,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(20);
trackProtagonist = 1;
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(45);
} else {
if (!loadGame(_currentSaveSlot)) {
@@ -450,7 +447,7 @@ bool DrasculaEngine::runCurrentChapter() {
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(58);
animation_1_6();
} else {
@@ -480,13 +477,13 @@ bool DrasculaEngine::runCurrentChapter() {
// lead to an incorrect setting of the protagonist's tracking flag (above). This
// made the character start walking off screen, as his actual position was
// different than the displayed one
- if (roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
+ if (_roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
gotoObject(178, 121);
gotoObject(169, 135);
- } else if (roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
+ } else if (_roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
walkToObject = 1;
gotoObject(190, 130);
- } else if (roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
+ } else if (_roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
walkToObject = 1;
gotoObject(190, 130);
}
@@ -518,12 +515,12 @@ bool DrasculaEngine::runCurrentChapter() {
checkObjects();
#ifdef _WIN32_WCE
- if (rightMouseButton) {
+ if (_rightMouseButton) {
if (_menuScreen) {
#else
- if (rightMouseButton == 1 && _menuScreen) {
+ if (_rightMouseButton == 1 && _menuScreen) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
if (currentChapter == 2) {
loadPic(menuBackground, cursorSurface);
@@ -549,10 +546,10 @@ bool DrasculaEngine::runCurrentChapter() {
// Do not show the inventory screen in chapter 5, if the right mouse button is clicked
// while the plug (object 16) is held
// Fixes bug #2059621 - "DRASCULA: Plug bug"
- if (rightMouseButton == 1 && !_menuScreen &&
+ if (_rightMouseButton == 1 && !_menuScreen &&
!(currentChapter == 5 && pickedObject == 16)) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
characterMoved = 0;
if (trackProtagonist == 2)
@@ -580,19 +577,19 @@ bool DrasculaEngine::runCurrentChapter() {
}
#endif
- if (leftMouseButton == 1 && _menuBar) {
+ if (_leftMouseButton == 1 && _menuBar) {
delay(100);
selectVerbFromBar();
- } else if (leftMouseButton == 1 && takeObject == 0) {
+ } else if (_leftMouseButton == 1 && takeObject == 0) {
delay(100);
if (verify1())
return true;
- } else if (leftMouseButton == 1 && takeObject == 1) {
+ } else if (_leftMouseButton == 1 && takeObject == 1) {
if (verify2())
return true;
}
- _menuBar = (mouseY < 24 && !_menuScreen) ? true : false;
+ _menuBar = (_mouseY < 24 && !_menuScreen) ? true : false;
Common::KeyCode key = getScan();
if (key == Common::KEYCODE_F1 && !_menuScreen) {
@@ -644,11 +641,11 @@ bool DrasculaEngine::runCurrentChapter() {
} else if (key == Common::KEYCODE_TILDE || key == Common::KEYCODE_BACKQUOTE) {
_console->attach();
_console->onFrame();
- } else if (currentChapter == 6 && key == Common::KEYCODE_0 && roomNumber == 61) {
+ } else if (currentChapter == 6 && key == Common::KEYCODE_0 && _roomNumber == 61) {
loadPic("alcbar.alg", bgSurface, 255);
}
- if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0)
+ if (_leftMouseButton != 0 || _rightMouseButton != 0 || key != 0)
framesWithoutAction = 0;
if (framesWithoutAction == 15000) {
@@ -670,8 +667,8 @@ bool DrasculaEngine::verify1() {
removeObject();
else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX >= _objectX1[l] && mouseY >= _objectY1[l]
- && mouseX <= _objectX2[l] && mouseY <= _objectY2[l] && doBreak == 0) {
+ if (_mouseX >= _objectX1[l] && _mouseY >= _objectY1[l]
+ && _mouseX <= _objectX2[l] && _mouseY <= _objectY2[l] && doBreak == 0) {
if (exitRoom(l))
return true;
if (doBreak == 1)
@@ -679,13 +676,13 @@ bool DrasculaEngine::verify1() {
}
}
- if (mouseX > curX && mouseY > curY
- && mouseX < curX + curWidth && mouseY < curY + curHeight)
+ if (_mouseX > curX && _mouseY > curY
+ && _mouseX < curX + curWidth && _mouseY < curY + curHeight)
doBreak = 1;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && doBreak == 0) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && doBreak == 0) {
roomX = roomObjX[l];
roomY = roomObjY[l];
trackFinal = trackObj[l];
@@ -696,8 +693,8 @@ bool DrasculaEngine::verify1() {
}
if (doBreak == 0) {
- roomX = CLIP(mouseX, floorX1, floorX2);
- roomY = CLIP(mouseY, floorY1 + feetHeight, floorY2);
+ roomX = CLIP(_mouseX, floorX1, floorX2);
+ roomY = CLIP(_mouseY, floorY1 + feetHeight, floorY2);
startWalking();
}
doBreak = 0;
@@ -718,8 +715,8 @@ bool DrasculaEngine::verify2() {
return true;
} else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && visible[l] == 1) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && visible[l] == 1) {
trackFinal = trackObj[l];
walkToObject = 1;
gotoObject(roomObjX[l], roomObjY[l]);
@@ -779,20 +776,20 @@ void DrasculaEngine::updateEvents() {
case Common::EVENT_KEYUP:
break;
case Common::EVENT_MOUSEMOVE:
- mouseX = event.mouse.x;
- mouseY = event.mouse.y;
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
break;
case Common::EVENT_LBUTTONDOWN:
- leftMouseButton = 1;
+ _leftMouseButton = 1;
break;
case Common::EVENT_LBUTTONUP:
- leftMouseButton = 0;
+ _leftMouseButton = 0;
break;
case Common::EVENT_RBUTTONDOWN:
// We changed semantic and react only on button up event
break;
case Common::EVENT_RBUTTONUP:
- rightMouseButton = 1;
+ _rightMouseButton = 1;
break;
default:
break;
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index e547503bee..944191b5fb 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -403,7 +403,7 @@ public:
int actorFrames[8];
int previousMusic, roomMusic;
- int roomNumber;
+ int _roomNumber;
char roomDisk[20];
char currentData[20];
int numRoomObjs;
@@ -428,18 +428,17 @@ public:
int flags[NUM_FLAGS];
int frame_y;
- int curX, curY, characterMoved, curDirection, trackProtagonist, num_frame;
+ int curX, curY, characterMoved, curDirection, trackProtagonist, _characterFrame;
int hare_se_ve; // TODO: what is this for?
int roomX, roomY, checkFlags;
int doBreak;
int stepX, stepY;
int curHeight, curWidth, feetHeight;
- int talkHeight, talkWidth;
int floorX1, floorY1, floorX2, floorY2;
int lowerLimit, upperLimit;
int trackFinal, walkToObject;
int objExit;
- int timeDiff, startTime;
+ int _startTime;
int hasAnswer;
int savedTime;
int breakOut;
@@ -454,14 +453,11 @@ public:
int framesWithoutAction;
int term_int;
int currentChapter;
- int loadedDifferentChapter;
+ bool _loadedDifferentChapter;
int _currentSaveSlot;
int _color;
int musicStopped;
- int mouseX;
- int mouseY;
- int leftMouseButton;
- int rightMouseButton;
+ int _mouseX, _mouseY, _leftMouseButton, _rightMouseButton;
Common::KeyState _keyBuffer[KEYBUFSIZE];
int _keyBufferHead;
@@ -661,7 +657,7 @@ public:
void animation_3_1(); // John talks with the bartender to book a room
void animation_4_1(); // John talks with the pianist
//
- void animation_2_2(); // John enters the chapel via the window
+ void animation_2_2(); // John enters the chapel via the window
void animation_4_2(); // John talks with the blind man (closeup)
void animation_5_2(); // John breaks the chapel window with the pike
void animation_6_2(); // The blind man (closeup) thanks John for giving him money and hands him the sickle
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 3bdf724670..b28de669b6 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -82,7 +82,7 @@ void DrasculaEngine::moveCursor() {
} else if (!_menuScreen && _color != kColorLightGreen)
color_abc(kColorLightGreen);
if (_hasName && !_menuScreen)
- centerText(textName, mouseX, mouseY);
+ centerText(textName, _mouseX, _mouseY);
if (_menuScreen)
showMenu();
else if (_menuBar)
@@ -132,7 +132,7 @@ void DrasculaEngine::showFrame(Common::SeekableReadStream *stream, bool firstFra
byte *prevFrame = (byte *)malloc(64000);
Graphics::Surface *screenSurf = _system->lockScreen();
- byte *screenBuffer = (byte *)screenSurf->pixels;
+ byte *screenBuffer = (byte *)screenSurf->getPixels();
uint16 screenPitch = screenSurf->pitch;
for (int y = 0; y < 200; y++) {
memcpy(prevFrame+y*320, screenBuffer+y*screenPitch, 320);
@@ -417,8 +417,8 @@ void DrasculaEngine::screenSaver() {
delete stream;
updateEvents();
- xr = mouseX;
- yr = mouseY;
+ xr = _mouseX;
+ yr = _mouseY;
while (!shouldQuit()) {
// efecto(bgSurface);
@@ -449,7 +449,7 @@ void DrasculaEngine::screenSaver() {
int x1_, y1_, off1, off2;
Graphics::Surface *screenSurf = _system->lockScreen();
- byte *screenBuffer = (byte *)screenSurf->pixels;
+ byte *screenBuffer = (byte *)screenSurf->getPixels();
uint16 screenPitch = screenSurf->pitch;
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 320; j++) {
@@ -480,18 +480,18 @@ void DrasculaEngine::screenSaver() {
// end of efecto()
updateEvents();
- if (rightMouseButton == 1 || leftMouseButton == 1)
+ if (_rightMouseButton == 1 || _leftMouseButton == 1)
break;
- if (mouseX != xr)
+ if (_mouseX != xr)
break;
- if (mouseY != yr)
+ if (_mouseY != yr)
break;
}
// fin_ghost();
free(copia);
free(ghost);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
showCursor();
}
@@ -538,7 +538,7 @@ int DrasculaEngine::playFrameSSN(Common::SeekableReadStream *stream) {
waitFrameSSN();
Graphics::Surface *screenSurf = _system->lockScreen();
- byte *screenBuffer = (byte *)screenSurf->pixels;
+ byte *screenBuffer = (byte *)screenSurf->getPixels();
uint16 screenPitch = screenSurf->pitch;
if (FrameSSN)
mixVideo(screenBuffer, screenSurface, screenPitch);
@@ -557,7 +557,7 @@ int DrasculaEngine::playFrameSSN(Common::SeekableReadStream *stream) {
free(BufferSSN);
waitFrameSSN();
Graphics::Surface *screenSurf = _system->lockScreen();
- byte *screenBuffer = (byte *)screenSurf->pixels;
+ byte *screenBuffer = (byte *)screenSurf->getPixels();
uint16 screenPitch = screenSurf->pitch;
if (FrameSSN)
mixVideo(screenBuffer, screenSurface, screenPitch);
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index fca8040f59..f0b6d12027 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -51,7 +51,7 @@ bool DrasculaEngine::isCursorVisible() {
void DrasculaEngine::selectVerbFromBar() {
for (int n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1] && n > 0) {
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1] && n > 0) {
selectVerb(n);
return;
}
@@ -143,7 +143,7 @@ void DrasculaEngine::clearMenu() {
int n, verbActivated = 1;
for (n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1])
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1])
verbActivated = 0;
copyRect(OBJWIDTH * n, OBJHEIGHT * verbActivated, _verbBarX[n], 2,
OBJWIDTH, OBJHEIGHT, cursorSurface, screenSurface);
@@ -165,8 +165,8 @@ void DrasculaEngine::showMap() {
_hasName = false;
for (int l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1) {
strcpy(textName, objName[l]);
_hasName = true;
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index f9f68c3317..35dfd3162a 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -91,8 +91,8 @@ void DrasculaEngine::gotoObject(int pointX, int pointY) {
updateRoom();
updateScreen();
- // roomNumber -2 is end credits. Do not show cursor there
- if (cursorVisible && roomNumber != -2)
+ // _roomNumber -2 is end credits. Do not show cursor there
+ if (cursorVisible && _roomNumber != -2)
showCursor();
}
@@ -100,8 +100,8 @@ void DrasculaEngine::checkObjects() {
int l, veo = 0;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1 && isDoor[l] == 0) {
strcpy(textName, objName[l]);
_hasName = true;
@@ -109,8 +109,8 @@ void DrasculaEngine::checkObjects() {
}
}
- if (mouseX > curX + 2 && mouseY > curY + 2
- && mouseX < curX + curWidth - 2 && mouseY < curY + curHeight - 2) {
+ if (_mouseX > curX + 2 && _mouseY > curY + 2
+ && _mouseX < curX + curWidth - 2 && _mouseY < curY + curHeight - 2) {
if (currentChapter == 2 || veo == 0) {
strcpy(textName, "hacker");
_hasName = true;
@@ -223,9 +223,9 @@ int DrasculaEngine::whichObject() {
int n;
for (n = 1; n < ARRAYSIZE(inventoryObjects); n++) {
- if (mouseX > _itemLocations[n].x && mouseY > _itemLocations[n].y &&
- mouseX < _itemLocations[n].x + OBJWIDTH &&
- mouseY < _itemLocations[n].y + OBJHEIGHT) {
+ if (_mouseX > _itemLocations[n].x && _mouseY > _itemLocations[n].y &&
+ _mouseX < _itemLocations[n].x + OBJWIDTH &&
+ _mouseY < _itemLocations[n].y + OBJHEIGHT) {
return n;
}
}
@@ -237,69 +237,69 @@ void DrasculaEngine::updateVisible() {
if (currentChapter == 1) {
// nothing
} else if (currentChapter == 2) {
- if (roomNumber == 2 && flags[40] == 0)
+ if (_roomNumber == 2 && flags[40] == 0)
visible[3] = 0;
- else if (roomNumber == 3 && flags[3] == 1)
+ else if (_roomNumber == 3 && flags[3] == 1)
visible[8] = 0;
- else if (roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
+ else if (_roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
visible[2] = 0;
visible[4] = 1;
- } else if (roomNumber == 7 && flags[35] == 1)
+ } else if (_roomNumber == 7 && flags[35] == 1)
visible[3] = 0;
- else if (roomNumber == 14 && flags[5] == 1)
+ else if (_roomNumber == 14 && flags[5] == 1)
visible[4] = 0;
- else if (roomNumber == 18 && flags[28] == 1)
+ else if (_roomNumber == 18 && flags[28] == 1)
visible[2] = 0;
} else if (currentChapter == 3) {
// nothing
} else if (currentChapter == 4) {
- if (roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
visible[2] = 1;
- if (roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
visible[2] = 0;
- if (roomNumber == 21 && flags[10] == 1)
+ if (_roomNumber == 21 && flags[10] == 1)
visible[2] = 0;
- if (roomNumber == 22 && flags[26] == 1) {
+ if (_roomNumber == 22 && flags[26] == 1) {
visible[2] = 0;
visible[1] = 1;
}
- if (roomNumber == 22 && flags[27] == 1)
+ if (_roomNumber == 22 && flags[27] == 1)
visible[3] = 0;
- if (roomNumber == 26 && flags[21] == 0)
+ if (_roomNumber == 26 && flags[21] == 0)
strcpy(objName[2], _textmisc[0]);
- if (roomNumber == 26 && flags[18] == 1)
+ if (_roomNumber == 26 && flags[18] == 1)
visible[2] = 0;
- if (roomNumber == 26 && flags[12] == 1)
+ if (_roomNumber == 26 && flags[12] == 1)
visible[1] = 0;
- if (roomNumber == 35 && flags[14] == 1)
+ if (_roomNumber == 35 && flags[14] == 1)
visible[2] = 0;
- if (roomNumber == 35 && flags[17] == 1)
+ if (_roomNumber == 35 && flags[17] == 1)
visible[3] = 1;
- if (roomNumber == 35 && flags[15] == 1)
+ if (_roomNumber == 35 && flags[15] == 1)
visible[1] = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[2] = 0;
- if (roomNumber == 49 && flags[6] == 0)
+ if (_roomNumber == 49 && flags[6] == 0)
visible[1] = 0;
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[1] = 1;
- if (roomNumber == 45 && flags[6] == 1)
+ if (_roomNumber == 45 && flags[6] == 1)
visible[3] = 1;
- if (roomNumber == 53 && flags[2] == 1)
+ if (_roomNumber == 53 && flags[2] == 1)
visible[3] = 0;
- if (roomNumber == 54 && flags[13] == 1)
+ if (_roomNumber == 54 && flags[13] == 1)
visible[3] = 0;
- if (roomNumber == 55 && flags[8] == 1)
+ if (_roomNumber == 55 && flags[8] == 1)
visible[1] = 0;
} else if (currentChapter == 6) {
- if (roomNumber == 58 && flags[8] == 0)
+ if (_roomNumber == 58 && flags[8] == 0)
isDoor[1] = 0;
- if (roomNumber == 58 && flags[8] == 1)
+ if (_roomNumber == 58 && flags[8] == 1)
isDoor[1] = 1;
- if (roomNumber == 59)
+ if (_roomNumber == 59)
isDoor[1] = 0;
- if (roomNumber == 60) {
+ if (_roomNumber == 60) {
trackDrascula = 0;
drasculaX = 155;
drasculaY = 69;
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 9f707eaa07..25f3da0080 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1087,7 +1087,7 @@ bool DrasculaEngine::room_102(int fl) {
void DrasculaEngine::updateRefresh() {
// Check generic updaters
for (int i = 0; i < _roomUpdatesSize; i++) {
- if (_roomUpdates[i].roomNum == roomNumber) {
+ if (_roomUpdates[i].roomNum == _roomNumber) {
if (_roomUpdates[i].flag < 0 ||
flags[_roomUpdates[i].flag] == _roomUpdates[i].flagValue) {
if (_roomUpdates[i].type == 0) {
@@ -1107,25 +1107,25 @@ void DrasculaEngine::updateRefresh() {
// Call room-specific updater
char rm[20];
- sprintf(rm, "update_%d", roomNumber);
+ sprintf(rm, "update_%d", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomUpdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomUpdaters[i]->desc)) {
- debug(8, "Calling room updater %d", roomNumber);
+ debug(8, "Calling room updater %d", _roomNumber);
(this->*(_roomHandlers->roomUpdaters[i]->proc))();
break;
}
}
- if (roomNumber == 10)
+ if (_roomNumber == 10)
showMap();
- else if (roomNumber == 45)
+ else if (_roomNumber == 45)
showMap();
}
void DrasculaEngine::updateRefresh_pre() {
// Check generic preupdaters
for (int i = 0; i < _roomPreUpdatesSize; i++) {
- if (_roomPreUpdates[i].roomNum == roomNumber) {
+ if (_roomPreUpdates[i].roomNum == _roomNumber) {
if (_roomPreUpdates[i].flag < 0 ||
flags[_roomPreUpdates[i].flag] == _roomPreUpdates[i].flagValue) {
if (_roomPreUpdates[i].type == 0) {
@@ -1145,16 +1145,16 @@ void DrasculaEngine::updateRefresh_pre() {
// Call room-specific preupdater
char rm[20];
- sprintf(rm, "update_%d_pre", roomNumber);
+ sprintf(rm, "update_%d_pre", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomPreupdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomPreupdaters[i]->desc)) {
- debug(8, "Calling room preupdater %d", roomNumber);
+ debug(8, "Calling room preupdater %d", _roomNumber);
(this->*(_roomHandlers->roomPreupdaters[i]->proc))();
break;
}
}
- if (currentChapter == 1 && roomNumber == 16)
+ if (currentChapter == 1 && _roomNumber == 16)
placeBJ();
}
@@ -1577,12 +1577,12 @@ bool DrasculaEngine::checkAction(int fl) {
hasAnswer = 0;
} else if (currentChapter == 2) {
// Note: the original check was strcmp(num_room, "18.alg")
- if (pickedObject == 11 && fl == 50 && flags[22] == 0 && roomNumber != 18)
+ if (pickedObject == 11 && fl == 50 && flags[22] == 0 && _roomNumber != 18)
talk(315);
else
hasAnswer = 0;
} else if (currentChapter == 3) {
- if (roomNumber == 13) {
+ if (_roomNumber == 13) {
if (room(13, fl)) {
showCursor();
return true;
@@ -1590,13 +1590,13 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 4) {
- if (roomNumber == 28)
+ if (_roomNumber == 28)
talk(178);
else if (pickedObject == 8 && fl == 50 && flags[18] == 0)
talk(481);
else if (pickedObject == 12 && fl == 50 && flags[18] == 0)
talk(487);
- else if (roomNumber == 21) {
+ else if (_roomNumber == 21) {
if (room(21, fl)) {
showCursor();
return true;
@@ -1604,7 +1604,7 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 56) {
+ if (_roomNumber == 56) {
if (room(56, fl)) {
showCursor();
return true;
@@ -1616,9 +1616,9 @@ bool DrasculaEngine::checkAction(int fl) {
talk(308);
else if (pickedObject == kVerbLook && fl == 50 && flags[0] == 0)
talk(310);
- else if (roomNumber == 102)
+ else if (_roomNumber == 102)
room(102, fl);
- else if (roomNumber == 60) {
+ else if (_roomNumber == 60) {
if (room(60, fl)) {
showCursor();
return true;
@@ -1632,7 +1632,7 @@ bool DrasculaEngine::checkAction(int fl) {
if (hasAnswer == 0) {
hasAnswer = 1;
- room(roomNumber, fl);
+ room(_roomNumber, fl);
}
if (hasAnswer == 0 && (_hasName || _menuScreen))
@@ -1684,7 +1684,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
TextResourceParser p(stream, DisposeAfterUse::YES);
- p.parseInt(roomNumber);
+ p.parseInt(_roomNumber);
p.parseInt(roomMusic);
p.parseString(roomDisk);
p.parseInt(palLevel);
@@ -1778,7 +1778,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
copyBackground(0, 171, 0, 0, OBJWIDTH, OBJHEIGHT, backSurface, drawSurface3);
@@ -1808,14 +1808,14 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
}
- if (roomNumber == 24) {
+ if (_roomNumber == 24) {
for (l = floorY1 - 1; l > 74; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
}
}
- if (currentChapter == 5 && roomNumber == 54) {
+ if (currentChapter == 5 && _roomNumber == 54) {
for (l = floorY1 - 1; l > 84; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
@@ -1853,13 +1853,13 @@ void DrasculaEngine::enterRoom(int roomIndex) {
isDoor[7] = 0;
if (currentChapter == 2) {
- if (roomNumber == 14 && flags[39] == 1)
+ if (_roomNumber == 14 && flags[39] == 1)
roomMusic = 16;
- else if (roomNumber == 15 && flags[39] == 1)
+ else if (_roomNumber == 15 && flags[39] == 1)
roomMusic = 16;
- if (roomNumber == 14 && flags[5] == 1)
+ if (_roomNumber == 14 && flags[5] == 1)
roomMusic = 0;
- else if (roomNumber == 15 && flags[5] == 1)
+ else if (_roomNumber == 15 && flags[5] == 1)
roomMusic = 0;
if (previousMusic != roomMusic && roomMusic != 0)
@@ -1872,21 +1872,21 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
if (currentChapter == 2) {
- if (roomNumber == 9 || roomNumber == 2 || roomNumber == 14 || roomNumber == 18)
+ if (_roomNumber == 9 || _roomNumber == 2 || _roomNumber == 14 || _roomNumber == 18)
savedTime = getTime();
}
if (currentChapter == 4) {
- if (roomNumber == 26)
+ if (_roomNumber == 26)
savedTime = getTime();
}
- if (currentChapter == 4 && roomNumber == 24 && flags[29] == 1)
+ if (currentChapter == 4 && _roomNumber == 24 && flags[29] == 1)
animation_7_4();
if (currentChapter == 5) {
- if (roomNumber == 45)
+ if (_roomNumber == 45)
hare_se_ve = 0;
- if (roomNumber == 49 && flags[7] == 0) {
+ if (_roomNumber == 49 && flags[7] == 0) {
playTalkSequence(4); // sequence 4, chapter 5
}
}
diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp
index 996c9d3f03..61d6f0b4af 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -263,7 +263,7 @@ bool DrasculaEngine::loadGame(int slot) {
if (savedChapter != currentChapter) {
_currentSaveSlot = slot;
currentChapter = savedChapter - 1;
- loadedDifferentChapter = 1;
+ _loadedDifferentChapter = true;
delete in;
return false;
}
@@ -283,7 +283,7 @@ bool DrasculaEngine::loadGame(int slot) {
takeObject = in->readSint32LE();
pickedObject = in->readSint32LE();
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
if (!sscanf(currentData, "%d.ald", &roomNum)) {
error("Bad save format");
}
@@ -383,10 +383,10 @@ bool DrasculaEngine::saveLoadScreen() {
updateScreen();
updateEvents();
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
// Check if the user has clicked on a save slot
for (n = 0; n < NUM_SAVES; n++) {
- if (mouseX > 115 && mouseY > 27 + (9 * n) && mouseX < 115 + 175 && mouseY < 27 + 10 + (9 * n)) {
+ if (_mouseX > 115 && _mouseY > 27 + (9 * n) && _mouseX < 115 + 175 && _mouseY < 27 + 10 + (9 * n)) {
selectedSlot = n;
selectedName = _saveNames[selectedSlot];
if (selectedName.empty()) {
@@ -399,14 +399,14 @@ bool DrasculaEngine::saveLoadScreen() {
}
// Check if the user has clicked in the text area above the save slots
- if (mouseX > 117 && mouseY > 15 && mouseX < 295 && mouseY < 24 && !selectedName.empty()) {
+ if (_mouseX > 117 && _mouseY > 15 && _mouseX < 295 && _mouseY < 24 && !selectedName.empty()) {
selectedName = enterName(selectedName);
if (!selectedName.empty())
_saveNames[selectedSlot] = selectedName; // update save name
}
// Check if the user has clicked a button
- if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149) {
+ if (_mouseX > 208 && _mouseY > 123 && _mouseX < 282 && _mouseY < 149) {
// "Save" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -415,14 +415,14 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
updateRoom();
updateScreen();
saveGame(selectedSlot + 1, _saveNames[selectedSlot]);
return true;
}
- } else if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149) {
+ } else if (_mouseX > 125 && _mouseY > 123 && _mouseX < 199 && _mouseY < 149) {
// "Load" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -431,19 +431,19 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
return loadGame(selectedSlot + 1);
}
- } else if (mouseX > 168 && mouseY > 154 && mouseX < 242 && mouseY < 180) {
+ } else if (_mouseX > 168 && _mouseY > 154 && _mouseX < 242 && _mouseY < 180) {
// "Play" button
break;
}
- } // if (leftMouseButton == 1)
+ } // if (_leftMouseButton == 1)
- leftMouseButton = 0;
+ _leftMouseButton = 0;
delay(10);
}
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
return true;
}
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 112f6fd06c..59b5e1d237 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -36,9 +36,9 @@ namespace Drascula {
void DrasculaEngine::updateVolume(Audio::Mixer::SoundType soundType, int prevVolume) {
int vol = _mixer->getVolumeForSoundType(soundType) / 16;
- if (mouseY < prevVolume && vol < 15)
+ if (_mouseY < prevVolume && vol < 15)
vol++;
- if (mouseY > prevVolume && vol > 0)
+ if (_mouseY > prevVolume && vol > 0)
vol--;
_mixer->setVolumeForSoundType(soundType, vol * 16);
}
@@ -78,23 +78,23 @@ void DrasculaEngine::volumeControls() {
while (getScan())
;
- if (rightMouseButton == 1) {
+ if (_rightMouseButton == 1) {
// Clear this to avoid going straight to the inventory
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
break;
}
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
- if (mouseX > 80 && mouseX < 121) {
+ if (_mouseX > 80 && _mouseX < 121) {
updateVolume(Audio::Mixer::kPlainSoundType, masterVolumeY);
}
- if (mouseX > 136 && mouseX < 178) {
+ if (_mouseX > 136 && _mouseX < 178) {
updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY);
}
- if (mouseX > 192 && mouseX < 233) {
+ if (_mouseX > 192 && _mouseX < 233) {
updateVolume(Audio::Mixer::kMusicSoundType, musicVolumeY);
}
}
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index a326852e96..6aabd91c6a 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -381,11 +381,11 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
int face;
if (currentChapter == 6) {
- if (flags[0] == 0 && roomNumber == 102) {
+ if (flags[0] == 0 && _roomNumber == 102) {
talk_pen(said, filename, 0);
return;
}
- if (flags[0] == 0 && roomNumber == 58) {
+ if (flags[0] == 0 && _roomNumber == 58) {
talk_pen(said, filename, 1);
return;
}
@@ -397,7 +397,7 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
}
if (currentChapter == 4) {
- if (roomNumber == 24 || flags[29] == 0) {
+ if (_roomNumber == 24 || flags[29] == 0) {
color_abc(kColorYellow);
}
} else {
@@ -413,59 +413,59 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (!strcmp(menuBackground, "99.alg") || !strcmp(menuBackground, "994.alg"))
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else {
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
drawSurface3, screenSurface);
}
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth,talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH,TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
}
@@ -827,47 +827,47 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (curHeight != 56)
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, (int)(curX + (8.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, (int)(curX + (12.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
(int)(talkOffset + curX + (12.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
(int)(talkOffset + curX + (8.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
}
diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp
index 1f9fa8d24f..108f9d2b60 100644
--- a/engines/dreamweb/monitor.cpp
+++ b/engines/dreamweb/monitor.cpp
@@ -104,7 +104,7 @@ void DreamWebEngine::useMon() {
redrawMainScrn();
workToScreenM();
}
-
+
int DreamWebEngine::findCommand(const char *const cmdList[]) {
// Loop over all commands in the list and see if we get a match
int cmd = 0;
@@ -135,7 +135,7 @@ bool DreamWebEngine::execCommand() {
"KEYS",
NULL
};
-
+
static const char *const comlistFR[] = {
"SORTIR",
"AIDE",
@@ -145,7 +145,7 @@ bool DreamWebEngine::execCommand() {
"TOUCHES", // should be CLES but it is translated as TOUCHES in the game...
NULL
};
-
+
static const char *const comlistDE[] = {
"ENDE",
"HILF",
@@ -155,7 +155,7 @@ bool DreamWebEngine::execCommand() {
"DATEN",
NULL
};
-
+
static const char *const comlistIT[] = {
"ESCI",
"AIUTO",
@@ -165,7 +165,7 @@ bool DreamWebEngine::execCommand() {
"CHIAVI",
NULL
};
-
+
static const char *const comlistES[] = {
"SALIR",
"AYUDA",
diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp
index bc75b97e71..bec58322d5 100644
--- a/engines/dreamweb/print.cpp
+++ b/engines/dreamweb/print.cpp
@@ -67,7 +67,7 @@ void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16* x, uint16 y,
// characters (0 - 31).
if (c < 32 || c == 255)
return;
-
+
uint8 dummyWidth, dummyHeight;
if (width == NULL)
width = &dummyWidth;
diff --git a/engines/engines.mk b/engines/engines.mk
index 6771748a10..5b3eeea61c 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -140,6 +140,11 @@ 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
diff --git a/engines/gob/iniconfig.cpp b/engines/gob/iniconfig.cpp
index bba531723c..032231bd4d 100644
--- a/engines/gob/iniconfig.cpp
+++ b/engines/gob/iniconfig.cpp
@@ -73,7 +73,7 @@ bool INIConfig::getConfig(const Common::String &file, Config &config) {
}
bool INIConfig::openConfig(const Common::String &file, Config &config) {
- config.config = new Common::ConfigFile();
+ config.config = new Common::INIFile();
config.created = false;
if (!config.config->loadFromFile(file)) {
@@ -89,7 +89,7 @@ bool INIConfig::openConfig(const Common::String &file, Config &config) {
}
bool INIConfig::createConfig(const Common::String &file, Config &config) {
- config.config = new Common::ConfigFile();
+ config.config = new Common::INIFile();
config.created = true;
_configs.setVal(file, config);
diff --git a/engines/gob/iniconfig.h b/engines/gob/iniconfig.h
index bf60f2d125..c1890170dc 100644
--- a/engines/gob/iniconfig.h
+++ b/engines/gob/iniconfig.h
@@ -24,7 +24,7 @@
#define GOB_INICONFIG_H
#include "common/str.h"
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/hashmap.h"
namespace Gob {
@@ -43,7 +43,7 @@ public:
private:
struct Config {
- Common::ConfigFile *config;
+ Common::INIFile *config;
bool created;
};
diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp
index 839378a412..870b0f15b3 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -821,7 +821,7 @@ bool Surface::loadIFF(Common::SeekableReadStream &stream) {
return false;
resize(decoder.getSurface()->w, decoder.getSurface()->h);
- memcpy(_vidMem, decoder.getSurface()->pixels, decoder.getSurface()->w * decoder.getSurface()->h);
+ memcpy(_vidMem, decoder.getSurface()->getPixels(), decoder.getSurface()->w * decoder.getSurface()->h);
return true;
}
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index a478492ccc..155989ccee 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -734,7 +734,11 @@ bool VideoPlayer::copyFrame(int slot, Surface &dest,
if (!surface)
return false;
- Surface src(surface->w, surface->h, surface->format.bytesPerPixel, (byte *)surface->pixels);
+ // FIXME? This currently casts away const from the pixel data. However, it
+ // is only used read-only in this case (as far as I can tell). Not casting
+ // the const qualifier away will lead to an additional allocation and copy
+ // of the frame data which is undesirable.
+ Surface src(surface->w, surface->h, surface->format.bytesPerPixel, (byte *)const_cast<void *>(surface->getPixels()));
dest.blit(src, left, top, left + width - 1, top + height - 1, x, y, transp);
return true;
diff --git a/engines/groovie/graphics.cpp b/engines/groovie/graphics.cpp
index 73eb574dec..a4d8a4330c 100644
--- a/engines/groovie/graphics.cpp
+++ b/engines/groovie/graphics.cpp
@@ -82,8 +82,8 @@ void GraphicsMan::mergeFgAndBg() {
uint32 i;
byte *countf, *countb;
- countf = (byte *)_foreground.getBasePtr(0, 0);
- countb = (byte *)_background.getBasePtr(0, 0);
+ countf = (byte *)_foreground.getPixels();
+ countb = (byte *)_background.getPixels();
for (i = 640 * 320; i; i--) {
if (255 == *(countf)) {
*(countf) = *(countb);
@@ -94,7 +94,7 @@ void GraphicsMan::mergeFgAndBg() {
}
void GraphicsMan::updateScreen(Graphics::Surface *source) {
- _vm->_system->copyRectToScreen(source->getBasePtr(0, 0), 640, 0, 80, 640, 320);
+ _vm->_system->copyRectToScreen(source->getPixels(), 640, 0, 80, 640, 320);
change();
}
diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp
index 72a61fefb2..f9a938bfd4 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -160,7 +160,7 @@ bool ROQPlayer::playFrameInternal() {
if (_dirty) {
// Update the screen
- _syst->copyRectToScreen(_bg->getBasePtr(0, 0), _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h);
+ _syst->copyRectToScreen(_bg->getPixels(), _bg->pitch, 0, (_syst->getHeight() - _bg->h) / 2, _bg->w, _bg->h);
_syst->updateScreen();
// Clear the dirty flag
@@ -291,8 +291,8 @@ bool ROQPlayer::processBlockInfo(ROQBlockHeader &blockHeader) {
}
// Clear the buffers with black YUV values
- byte *ptr1 = (byte *)_currBuf->getBasePtr(0, 0);
- byte *ptr2 = (byte *)_prevBuf->getBasePtr(0, 0);
+ byte *ptr1 = (byte *)_currBuf->getPixels();
+ byte *ptr2 = (byte *)_prevBuf->getPixels();
for (int i = 0; i < width * height; i++) {
*ptr1++ = 0;
*ptr1++ = 128;
@@ -436,11 +436,11 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
Graphics::JPEGDecoder *jpg = new Graphics::JPEGDecoder();
jpg->loadStream(*_file);
- const byte *y = (const byte *)jpg->getComponent(1)->getBasePtr(0, 0);
- const byte *u = (const byte *)jpg->getComponent(2)->getBasePtr(0, 0);
- const byte *v = (const byte *)jpg->getComponent(3)->getBasePtr(0, 0);
+ const byte *y = (const byte *)jpg->getComponent(1)->getPixels();
+ const byte *u = (const byte *)jpg->getComponent(2)->getPixels();
+ const byte *v = (const byte *)jpg->getComponent(3)->getPixels();
- byte *ptr = (byte *)_currBuf->getBasePtr(0, 0);
+ byte *ptr = (byte *)_currBuf->getPixels();
for (int i = 0; i < _currBuf->w * _currBuf->h; i++) {
*ptr++ = *y++;
*ptr++ = *u++;
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index cbbdecc3e7..8e3bef9945 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -373,7 +373,7 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) {
DebugMan.isDebugChannelEnabled(kGroovieDebugAll)) {
rect.translate(0, -80);
_vm->_graphicsMan->_foreground.frameRect(rect, 250);
- _vm->_system->copyRectToScreen(_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320);
+ _vm->_system->copyRectToScreen(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320);
_vm->_system->updateScreen();
}
@@ -983,7 +983,7 @@ void Script::o_strcmpnejmp_var() { // 0x21
void Script::o_copybgtofg() { // 0x22
debugScript(1, true, "COPY_BG_TO_FG");
- memcpy(_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_background.getBasePtr(0, 0), 640 * 320);
+ memcpy(_vm->_graphicsMan->_foreground.getPixels(), _vm->_graphicsMan->_background.getPixels(), 640 * 320);
}
void Script::o_strcmpeqjmp() { // 0x23
diff --git a/engines/groovie/stuffit.cpp b/engines/groovie/stuffit.cpp
index 37f12585e7..60a57a0129 100644
--- a/engines/groovie/stuffit.cpp
+++ b/engines/groovie/stuffit.cpp
@@ -249,7 +249,7 @@ void StuffItArchive::update14(uint16 first, uint16 last, byte *code, uint16 *fre
do {
while (++i < last && code[first] > code[i])
;
-
+
while (--j > first && code[first] < code[j])
;
diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp
index 8786e75488..59d966a22f 100644
--- a/engines/groovie/vdx.cpp
+++ b/engines/groovie/vdx.cpp
@@ -358,7 +358,7 @@ void VDXPlayer::getStill(Common::ReadStream *in) {
byte *buf;
if (_flagOne) {
// Paint to the foreground
- buf = (byte *)_fg->getBasePtr(0, 0);
+ buf = (byte *)_fg->getPixels();
if (_flag2Byte) {
mask = 0xff;
} else {
@@ -370,7 +370,7 @@ void VDXPlayer::getStill(Common::ReadStream *in) {
_flagFirstFrame = true;
} else {
// Paint to the background
- buf = (byte *)_bg->getBasePtr(0, 0);
+ buf = (byte *)_bg->getPixels();
}
// Read the palette
@@ -486,9 +486,9 @@ void VDXPlayer::decodeBlockDelta(uint32 offset, byte *colors, uint16 imageWidth)
// TODO: Verify just the else block is required
//if (_flagOne) {
// Paint to the foreground
- //dest = (byte *)_fg->getBasePtr(0, 0) + offset;
+ //dest = (byte *)_fg->getPixels() + offset;
//} else {
- dest = (byte *)_bg->getBasePtr(0, 0) + offset;
+ dest = (byte *)_bg->getPixels() + offset;
//}
// Move the pointers to the beginning of the current block
@@ -496,8 +496,8 @@ void VDXPlayer::decodeBlockDelta(uint32 offset, byte *colors, uint16 imageWidth)
dest += blockOff;
byte *fgBuf = 0;
if (_flagSeven) {
- fgBuf = (byte *)_fg->getBasePtr(0, 0) + offset + blockOff;
- //byte *bgBuf = (byte *)_bg->getBasePtr(0, 0) + offset + blockOff;
+ fgBuf = (byte *)_fg->getPixels() + offset + blockOff;
+ //byte *bgBuf = (byte *)_bg->getPixels() + offset + blockOff;
}
for (int y = TILE_SIZE; y; y--) {
@@ -550,7 +550,7 @@ void VDXPlayer::fadeIn(uint8 *targetpal) {
// TODO: Is it required? If so, move to an appropiate place
// Copy the foreground to the background
- memcpy((byte *)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), (byte *)_vm->_graphicsMan->_background.getBasePtr(0, 0), 640 * 320);
+ memcpy((byte *)_vm->_graphicsMan->_foreground.getPixels(), (byte *)_vm->_graphicsMan->_background.getPixels(), 640 * 320);
// Start a fadein
_vm->_graphicsMan->fadeIn(targetpal);
diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp
index f7b923badf..c09d748b97 100644
--- a/engines/hopkins/computer.cpp
+++ b/engines/hopkins/computer.cpp
@@ -58,7 +58,7 @@ ComputerManager::ComputerManager(HopkinsEngine *vm) {
_minBreakoutMoveSpeed = 0;
_maxBreakoutMoveSpeed = 0;
_lastBreakoutMoveSpeed = 0;
- _breakoutHiscore = 0;
+ _lowestHiScore = 0;
}
/**
@@ -579,26 +579,32 @@ void ComputerManager::displayGamesSubMenu() {
*/
void ComputerManager::loadHiscore() {
byte *ptr = _vm->_globals->allocMemory(100);
- _vm->_saveLoad->load("HISCORE.DAT", ptr);
+ memset(ptr, 0, 100);
+
+ if (_vm->_saveLoad->saveExists(_vm->getTargetName() + "-highscore.dat"))
+ _vm->_saveLoad->load(_vm->getTargetName() + "-highscore.dat", ptr);
for (int scoreIndex = 0; scoreIndex < 6; ++scoreIndex) {
- for (int i = 0; i < 5; ++i) {
+ _score[scoreIndex]._name = " ";
+ _score[scoreIndex]._score = " ";
+
+ for (int i = 0; i < 6; ++i) {
char nextChar = ptr[(16 * scoreIndex) + i];
if (!nextChar)
nextChar = ' ';
- _score[scoreIndex]._name += nextChar;
+ _score[scoreIndex]._name.setChar(nextChar, i);
}
for (int i = 0; i < 9; ++i) {
char nextChar = ptr[(scoreIndex * 16) + 6 + i];
if (!nextChar)
nextChar = '0';
- _score[scoreIndex]._score += nextChar;
+ _score[scoreIndex]._score.setChar(nextChar, i);
}
}
+ _lowestHiScore = atol(_score[5]._score.c_str());
_vm->_globals->freeMemory(ptr);
- _breakoutHiscore = atol(_score[5]._score.c_str());
}
/**
@@ -779,7 +785,7 @@ void ComputerManager::playBreakout() {
_vm->_events->mouseOn();
_vm->_objectsMan->removeSprite(0);
_vm->_objectsMan->removeSprite(1);
- if (_breakoutScore > _breakoutHiscore)
+ if (_breakoutScore > _lowestHiScore)
getScoreName();
if (displayHiscores() != 1)
break;
@@ -823,11 +829,11 @@ int ComputerManager::displayHiscores() {
yp += 46;
// Display the characters of the name
- for (int i = 0; i <= 5; i++)
+ for (int i = 0; i < 6; i++)
displayHiscoreLine(ptr, 9 * i + 69, yp, _score[scoreIndex]._name[i]);
// Display the digits of the score
- for (int i = 0; i <= 8; i++)
+ for (int i = 0; i < 9; i++)
displayHiscoreLine(ptr, 9 * i + 199, yp, _score[scoreIndex]._score[i]);
}
@@ -864,6 +870,19 @@ void ComputerManager::getScoreName() {
_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
byte *ptr = _vm->_fileIO->loadFile("ALPHA.SPR");
_vm->_graphicsMan->fadeInBreakout();
+
+ // Figure out the line to put the new high score on
+ int scoreLine = 0;
+ while (scoreLine < 5 && _breakoutScore < atol(_score[scoreLine]._score.c_str()))
+ ++scoreLine;
+
+ // If it's not the lasat line, move the lines down
+ for (int line = 5; line > scoreLine; --line) {
+ _score[line]._name = _score[line - 1]._name;
+ _score[line]._score = _score[line - 1]._score;
+ }
+
+ // Get the name for the new high score
for (int strPos = 0; strPos <= 4; strPos++) {
displayHiscoreLine(ptr, 9 * strPos + 140, 78, 1);
@@ -873,13 +892,15 @@ void ComputerManager::getScoreName() {
if ((curChar > '9') && (curChar < 'A'))
curChar = ' ';
- _score[5]._name.setChar(curChar, strPos);
+ _score[scoreLine]._name.setChar(curChar, strPos);
displayHiscoreLine(ptr, 9 * strPos + 140, 78, curChar);
for (int idx = 0; idx < 12; ++idx)
_vm->_events->refreshScreenAndEvents();
}
- _score[5]._score = " ";
+
+ // Set up the new score
+ _score[scoreLine]._score = " ";
char score[16];
sprintf(score, "%d", _breakoutScore);
@@ -888,8 +909,8 @@ void ComputerManager::getScoreName() {
++scoreLen;
while (score[scoreLen]);
- for (int i = scoreLen, scorePos = 8; i >= 0; i--) {
- _score[5]._score.setChar(score[i], scorePos--);
+ for (int i = scoreLen - 1, scorePos = 8; i >= 0; i--) {
+ _score[scoreLine]._score.setChar(score[i], scorePos--);
}
_vm->_graphicsMan->fadeOutBreakout();
_vm->_globals->freeMemory(ptr);
@@ -970,10 +991,10 @@ void ComputerManager::saveScore() {
}
byte *ptr = _vm->_globals->allocMemory(100);
- memset(ptr, 0, 99);
+ memset(ptr, 0, 100);
for (int scorePlaceIdx = 0; scorePlaceIdx <= 5; scorePlaceIdx++) {
int curBufPtr = 16 * scorePlaceIdx;
- for (int namePos = 0; namePos <= 4; namePos++) {
+ for (int namePos = 0; namePos < 6; namePos++) {
char curChar = _score[scorePlace[scorePlaceIdx]]._name[namePos];
if (!curChar)
curChar = ' ';
@@ -991,7 +1012,7 @@ void ComputerManager::saveScore() {
ptr[curBufPtr + 15] = 0;
}
- _vm->_saveLoad->saveFile("HISCORE.DAT", ptr, 100);
+ _vm->_saveLoad->saveFile(_vm->getTargetName() + "-highscore.dat", ptr, 100);
_vm->_globals->freeMemory(ptr);
}
diff --git a/engines/hopkins/computer.h b/engines/hopkins/computer.h
index cdd653f793..1771bba7d6 100644
--- a/engines/hopkins/computer.h
+++ b/engines/hopkins/computer.h
@@ -63,7 +63,7 @@ private:
bool _ballUpFl;
int _breakoutLevelNbr;
int _padPositionX;
- int _breakoutHiscore;
+ int _lowestHiScore;
int _minBreakoutMoveSpeed;
int _maxBreakoutMoveSpeed;
int _lastBreakoutMoveSpeed;
diff --git a/engines/hopkins/detection.cpp b/engines/hopkins/detection.cpp
index 9d16b0ab51..c617a5aacf 100644
--- a/engines/hopkins/detection.cpp
+++ b/engines/hopkins/detection.cpp
@@ -56,6 +56,10 @@ bool HopkinsEngine::getIsDemo() const {
return _gameDescription->desc.flags & ADGF_DEMO;
}
+const Common::String &HopkinsEngine::getTargetName() const {
+ return _targetName;
+}
+
} // End of namespace Hopkins
static const PlainGameDescriptor hopkinsGames[] = {
diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp
index 6cdfbf47d1..3b8fedf0ee 100644
--- a/engines/hopkins/dialogs.cpp
+++ b/engines/hopkins/dialogs.cpp
@@ -505,7 +505,7 @@ void DialogsManager::inventAnim() {
return;
if (_vm->_objectsMan->_eraseVisibleCounter && !_vm->_objectsMan->_visibleFl) {
- _vm->_graphicsMan->copySurface(_vm->_graphicsMan->_backBuffer, _oldInventX, 27, 48, 38,
+ _vm->_graphicsMan->copySurface(_vm->_graphicsMan->_backBuffer, _oldInventX, 27, 48, 38,
_vm->_graphicsMan->_frontBuffer, _oldInventX, 27);
_vm->_graphicsMan->addDirtyRect(_oldInventX, 27, _oldInventX + 48, 65);
--_vm->_objectsMan->_eraseVisibleCounter;
@@ -691,7 +691,7 @@ void DialogsManager::showSaveLoad(SaveLoadMode mode) {
Graphics::Surface thumb8;
_vm->_saveLoad->convertThumb16To8(header._thumbnail, &thumb8);
- byte *thumb = (byte *)thumb8.pixels;
+ byte *thumb = (byte *)thumb8.getPixels();
int16 startPosX_ = _vm->_events->_startPos.x;
switch (slotNumber) {
diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp
index 28f22ed99e..a9a0a81f08 100644
--- a/engines/hopkins/globals.cpp
+++ b/engines/hopkins/globals.cpp
@@ -134,7 +134,7 @@ Globals::~Globals() {
void Globals::setConfig() {
// CHECKME: Should be in Globals() but it doesn't work
// The Polish version is a translation of the English version. The filenames are the same.
- // The Russian version looks like a translation of the English version, based on the filenames.
+ // The Russian version looks like a translation of the English version, based on the filenames.
switch (_vm->getLanguage()) {
case Common::EN_ANY:
case Common::PL_POL:
diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp
index ebc5cfa8da..de9f043763 100644
--- a/engines/hopkins/graphics.cpp
+++ b/engines/hopkins/graphics.cpp
@@ -325,7 +325,7 @@ void GraphicsManager::loadPCX640(byte *surface, const Common::String &file, byte
// Copy out the dimensions and pixels of the decoded surface
_largeScreenFl = s->w > SCREEN_WIDTH;
- Common::copy((byte *)s->pixels, (byte *)s->pixels + (s->pitch * s->h), surface);
+ Common::copy((const byte *)s->getPixels(), (const byte *)s->getBasePtr(0, s->h), surface);
// Copy out the palette
const byte *palSrc = pcxDecoder.getPalette();
@@ -1179,7 +1179,7 @@ void GraphicsManager::displayZones() {
Common::Rect r(_vm->_objectsMan->_bob[bobId]._oldX, _vm->_objectsMan->_bob[bobId]._oldY,
_vm->_objectsMan->_bob[bobId]._oldX + _vm->_objectsMan->_bob[bobId]._oldWidth,
_vm->_objectsMan->_bob[bobId]._oldY + _vm->_objectsMan->_bob[bobId]._oldHeight);
-
+
displayDebugRect(screenSurface, r, 0xff0000);
}
}
@@ -1202,15 +1202,13 @@ void GraphicsManager::displayZones() {
void GraphicsManager::displayLines() {
Graphics::Surface *screenSurface = g_system->lockScreen();
- uint16* pixels = (uint16*)screenSurface->pixels;
-
- for (int lineIndex = 0; lineIndex < _vm->_linesMan->_linesNumb; lineIndex++) {
+ for (int lineIndex = 0; lineIndex < _vm->_linesMan->_linesNumb; lineIndex++) {
int i = 0;
do {
int x = _vm->_linesMan->_lineItem[lineIndex]._lineData[i] - _scrollPosX;
int y = _vm->_linesMan->_lineItem[lineIndex]._lineData[i+1];
if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT) {
- pixels[ y * screenSurface->w + x ] = 0xffff;
+ WRITE_UINT16(screenSurface->getBasePtr(x, y), 0xffff);
}
i += 2;
}
@@ -1230,7 +1228,7 @@ void GraphicsManager::displayDebugRect(Graphics::Surface *surface, const Common:
r.top = MAX(r.top, (int16)0);
r.right = MIN(r.right, (int16)SCREEN_WIDTH);
r.bottom = MIN(r.bottom, (int16)SCREEN_HEIGHT);
-
+
// If there's an on-screen portion, display it
if (r.isValidRect())
surface->frameRect(r, color);
diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h
index 268db7fc2b..8767f5ec4d 100644
--- a/engines/hopkins/graphics.h
+++ b/engines/hopkins/graphics.h
@@ -125,7 +125,7 @@ public:
public:
GraphicsManager(HopkinsEngine *vm);
~GraphicsManager();
-
+
void clearPalette();
void clearScreen();
void clearVesaScreen();
diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp
index b773808c50..96131f2968 100644
--- a/engines/hopkins/hopkins.cpp
+++ b/engines/hopkins/hopkins.cpp
@@ -92,7 +92,7 @@ bool HopkinsEngine::canLoadGameStateCurrently() {
* Returns true if it is currently okay to save the game
*/
bool HopkinsEngine::canSaveGameStateCurrently() {
- return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl
+ return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl
&& _globals->_curRoomNum != 0 && !isUnderwaterSubScene();
}
@@ -111,8 +111,6 @@ Common::Error HopkinsEngine::saveGameState(int slot, const Common::String &desc)
}
Common::Error HopkinsEngine::run() {
- _saveLoad->initSaves();
-
_globals->setConfig();
_fileIO->initCensorship();
initializeSystem();
diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h
index 398e41a4d2..d8c30e5004 100644
--- a/engines/hopkins/hopkins.h
+++ b/engines/hopkins/hopkins.h
@@ -164,6 +164,7 @@ public:
Common::Platform getPlatform() const;
uint16 getVersion() const;
bool getIsDemo() const;
+ const Common::String &getTargetName() const;
int getRandomNumber(int maxNumber);
Common::String generateSaveName(int slotNumber);
diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp
index 98fb15046e..b0dea7e6d1 100644
--- a/engines/hopkins/saveload.cpp
+++ b/engines/hopkins/saveload.cpp
@@ -55,19 +55,18 @@ bool SaveLoadManager::save(const Common::String &file, const void *buf, size_t n
return false;
}
+bool SaveLoadManager::saveExists(const Common::String &file) {
+ Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(file);
+ bool result = savefile != NULL;
+ delete savefile;
+ return result;
+}
+
// Save File
bool SaveLoadManager::saveFile(const Common::String &file, const void *buf, size_t n) {
return save(file, buf, n);
}
-void SaveLoadManager::initSaves() {
- Common::String dataFilename = "HISCORE.DAT";
- byte data[100];
- Common::fill(&data[0], &data[100], 0);
-
- saveFile(dataFilename, data, 100);
-}
-
void SaveLoadManager::load(const Common::String &file, byte *buf) {
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(file);
if (savefile == NULL)
@@ -234,14 +233,14 @@ void SaveLoadManager::createThumbnail(Graphics::Surface *s) {
Graphics::Surface thumb8;
thumb8.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
- _vm->_graphicsMan->reduceScreenPart(_vm->_graphicsMan->_frontBuffer, (byte *)thumb8.pixels,
+ _vm->_graphicsMan->reduceScreenPart(_vm->_graphicsMan->_frontBuffer, (byte *)thumb8.getPixels(),
_vm->_events->_startPos.x, 20, SCREEN_WIDTH, SCREEN_HEIGHT - 40, 80);
// Convert the 8-bit pixel to 16 bit surface
s->create(w, h, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
- const byte *srcP = (const byte *)thumb8.pixels;
- uint16 *destP = (uint16 *)s->pixels;
+ const byte *srcP = (const byte *)thumb8.getPixels();
+ uint16 *destP = (uint16 *)s->getPixels();
for (int yp = 0; yp < h; ++yp) {
// Copy over the line, using the source pixels as lookups into the pixels palette
@@ -259,6 +258,10 @@ void SaveLoadManager::createThumbnail(Graphics::Surface *s) {
}
void SaveLoadManager::syncSavegameData(Common::Serializer &s, int version) {
+ // The brief version 3 had the highscores embedded. They're in a separate file now, so skip
+ if (version == 3 && s.isLoading())
+ s.skip(100);
+
s.syncBytes(&_vm->_globals->_saveData->_data[0], 2050);
syncCharacterLocation(s, _vm->_globals->_saveData->_cloneHopkins);
syncCharacterLocation(s, _vm->_globals->_saveData->_realHopkins);
@@ -296,8 +299,8 @@ void SaveLoadManager::convertThumb16To8(Graphics::Surface *thumb16, Graphics::Su
pixelFormat16.colorToRGB(p, paletteR[palIndex], paletteG[palIndex], paletteB[palIndex]);
}
- const uint16 *srcP = (const uint16 *)thumb16->pixels;
- byte *destP = (byte *)thumb8->pixels;
+ const uint16 *srcP = (const uint16 *)thumb16->getPixels();
+ byte *destP = (byte *)thumb8->getPixels();
for (int yp = 0; yp < thumb16->h; ++yp) {
const uint16 *lineSrcP = srcP;
diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h
index 6fee814180..5b77c11f12 100644
--- a/engines/hopkins/saveload.h
+++ b/engines/hopkins/saveload.h
@@ -35,7 +35,7 @@ namespace Hopkins {
class HopkinsEngine;
-#define HOPKINS_SAVEGAME_VERSION 2
+#define HOPKINS_SAVEGAME_VERSION 4
struct hopkinsSavegameHeader {
uint8 _version;
@@ -56,7 +56,7 @@ private:
public:
SaveLoadManager(HopkinsEngine *vm);
- void initSaves();
+ bool saveExists(const Common::String &file);
bool save(const Common::String &file, const void *buf, size_t n);
bool saveFile(const Common::String &file, const void *buf, size_t n);
void load(const Common::String &file, byte *buf);
diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp
index 0f07d52aee..5dcee3ae94 100644
--- a/engines/hugo/dialogs.cpp
+++ b/engines/hugo/dialogs.cpp
@@ -140,8 +140,8 @@ 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]->pixels;
- byte *dst = (byte *)_arrayBmp[i * 2 + 1]->pixels;
+ 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);
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index bcf06055f8..b140cfdba2 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -66,7 +66,7 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
_console = new HugoConsole(this);
_rnd = 0;
-
+
_screen = NULL;
_mouse = NULL;
_inventory = NULL;
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 505e356049..6f314c8774 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -89,11 +89,7 @@ void intro_v1d::preNewGame() {
void intro_v1d::introInit() {
_introState = 0;
_introTicks = 0;
- _surf.w = 320;
- _surf.h = 200;
- _surf.pixels = _vm->_screen->getFrontBuffer();
- _surf.pitch = 320;
- _surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surf.init(320, 200, 320, _vm->_screen->getFrontBuffer(), Graphics::PixelFormat::createFormatCLUT8());
_vm->_screen->displayList(kDisplayInit);
}
@@ -243,11 +239,7 @@ void intro_v2d::preNewGame() {
void intro_v2d::introInit() {
_vm->_screen->displayList(kDisplayInit);
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
- _surf.w = 320;
- _surf.h = 200;
- _surf.pixels = _vm->_screen->getFrontBuffer();
- _surf.pitch = 320;
- _surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surf.init(320, 200, 320, _vm->_screen->getFrontBuffer(), Graphics::PixelFormat::createFormatCLUT8());
char buffer[128];
@@ -289,11 +281,7 @@ void intro_v3d::preNewGame() {
void intro_v3d::introInit() {
_vm->_screen->displayList(kDisplayInit);
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
- _surf.w = 320;
- _surf.h = 200;
- _surf.pixels = _vm->_screen->getFrontBuffer();
- _surf.pitch = 320;
- _surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surf.init(320, 200, 320, _vm->_screen->getFrontBuffer(), Graphics::PixelFormat::createFormatCLUT8());
char buffer[128];
if (_vm->_boot._registered)
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index bcbfe27b69..ee0303c8c3 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -737,7 +737,7 @@ void KyraEngine_MR::loadAlbumPageWSA() {
if (_album.curPage != 14) {
filename = Common::String::format("PAGE%x.WSA", _album.curPage+1);
_album.rightPage.wsa->open(filename.c_str(), 1, 0);
- _album.rightPage.maxFrame = _album.leftPage.wsa->frames()-1;
+ _album.rightPage.maxFrame = _album.rightPage.wsa->frames()-1;
}
}
diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp
index c9486d9c45..d2b4907b6a 100644
--- a/engines/kyra/scene_mr.cpp
+++ b/engines/kyra/scene_mr.cpp
@@ -577,6 +577,7 @@ void KyraEngine_MR::initSceneScreen(int unk1) {
}
updateCharPal(0);
+ _screen->updateScreen();
if (!_menuDirectlyToLoad) {
_emc->start(&_sceneScriptState, 3);
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 054397a34a..8c97e46a8f 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -718,6 +718,13 @@ void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upF
_vm->delay((delayAcc >> 8) * 1000 / 60);
delayAcc &= 0xFF;
}
+
+ // In case we should quit we setup the final palette here. This avoids
+ // ugly palette glitches when quitting while fading. This can for example
+ // be noticed when quitting while viewing the family album in Kyra3.
+ if (_vm->shouldQuit()) {
+ setScreenPalette(pal);
+ }
}
void Screen::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) {
diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp
index a19d678e35..24c523c856 100644
--- a/engines/kyra/text_rpg.cpp
+++ b/engines/kyra/text_rpg.cpp
@@ -129,7 +129,7 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
while (c) {
- char a = tolower(_ctrl[1]);
+ char a = tolower((unsigned char)_ctrl[1]);
if (!_tempString2 && c == '%') {
if (a == 'd') {
diff --git a/engines/lastexpress/data/animation.cpp b/engines/lastexpress/data/animation.cpp
index 7618259e69..832bcc2e26 100644
--- a/engines/lastexpress/data/animation.cpp
+++ b/engines/lastexpress/data/animation.cpp
@@ -270,7 +270,7 @@ void Animation::play() {
draw(s);
// XXX: Update the screen
- g_system->copyRectToScreen(s->pixels, s->pitch, 0, 0, s->w, s->h);
+ g_system->copyRectToScreen(s->getPixels(), s->pitch, 0, 0, s->w, s->h);
// Free the temporary surface
s->free();
diff --git a/engines/lastexpress/data/scene.h b/engines/lastexpress/data/scene.h
index 69a1417459..b99e56a74c 100644
--- a/engines/lastexpress/data/scene.h
+++ b/engines/lastexpress/data/scene.h
@@ -83,6 +83,7 @@ class Scene;
class SceneHotspot {
public:
enum Action {
+ kActionNone = 0,
kActionInventory = 1,
kActionSavePoint = 2,
kActionPlaySound = 3,
@@ -152,8 +153,19 @@ public:
byte cursor;
uint32 next;
- SceneHotspot() {}
+ SceneHotspot() {
+ coordsOffset = 0;
+ scene = kSceneNone;
+ location = 0;
+ action = kActionNone;
+ param1 = 0;
+ param2 = 0;
+ param3 = 0;
+ cursor = 0;
+ next = 0;
+ }
~SceneHotspot();
+
static SceneHotspot *load(Common::SeekableReadStream *stream);
bool isInside(const Common::Point &point);
diff --git a/engines/lastexpress/data/sequence.cpp b/engines/lastexpress/data/sequence.cpp
index a5bcba84cd..c7073b560c 100644
--- a/engines/lastexpress/data/sequence.cpp
+++ b/engines/lastexpress/data/sequence.cpp
@@ -128,8 +128,8 @@ AnimFrame::~AnimFrame() {
}
Common::Rect AnimFrame::draw(Graphics::Surface *s) {
- byte *inp = (byte *)_image.pixels;
- uint16 *outp = (uint16 *)s->pixels;
+ byte *inp = (byte *)_image.getPixels();
+ uint16 *outp = (uint16 *)s->getPixels();
for (int i = 0; i < 640 * 480; i++, inp++, outp++) {
if (*inp)
*outp = _palette[*inp];
@@ -155,7 +155,7 @@ void AnimFrame::decomp4(Common::SeekableReadStream *in, const FrameInfo &f) {
}
void AnimFrame::decomp34(Common::SeekableReadStream *in, const FrameInfo &f, byte mask, byte shift) {
- byte *p = (byte *)_image.getBasePtr(0, 0);
+ byte *p = (byte *)_image.getPixels();
uint32 skip = f.initialSkip / 2;
uint32 size = f.decompressedEndOffset / 2;
@@ -200,7 +200,7 @@ void AnimFrame::decomp34(Common::SeekableReadStream *in, const FrameInfo &f, byt
}
void AnimFrame::decomp5(Common::SeekableReadStream *in, const FrameInfo &f) {
- byte *p = (byte *)_image.getBasePtr(0, 0);
+ byte *p = (byte *)_image.getPixels();
uint32 skip = f.initialSkip / 2;
uint32 size = f.decompressedEndOffset / 2;
@@ -235,7 +235,7 @@ void AnimFrame::decomp5(Common::SeekableReadStream *in, const FrameInfo &f) {
}
void AnimFrame::decomp7(Common::SeekableReadStream *in, const FrameInfo &f) {
- byte *p = (byte *)_image.getBasePtr(0, 0);
+ byte *p = (byte *)_image.getPixels();
uint32 skip = f.initialSkip / 2;
uint32 size = f.decompressedEndOffset / 2;
@@ -288,7 +288,7 @@ void AnimFrame::decomp7(Common::SeekableReadStream *in, const FrameInfo &f) {
}
void AnimFrame::decompFF(Common::SeekableReadStream *in, const FrameInfo &f) {
- byte *p = (byte *)_image.getBasePtr(0, 0);
+ byte *p = (byte *)_image.getPixels();
uint32 skip = f.initialSkip / 2;
uint32 size = f.decompressedEndOffset / 2;
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index db3a3e3962..7c83aff93d 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -487,7 +487,9 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
// Handle right-click to interrupt sequence
Common::Event ev;
- _engine->getEventManager()->pollEvent(ev);
+ if (!_engine->getEventManager()->pollEvent(ev))
+ break;
+
if (ev.type == Common::EVENT_RBUTTONUP)
break;
@@ -596,7 +598,9 @@ bool Debugger::cmdPlaySbe(int argc, const char **argv) {
// Handle right-click to interrupt sequence
Common::Event ev;
- _engine->getEventManager()->pollEvent(ev);
+ if (!_engine->getEventManager()->pollEvent(ev))
+ break;
+
if (ev.type == Common::EVENT_RBUTTONUP)
break;
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index a2c7226b93..82688fff2e 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -587,8 +587,8 @@ void SceneManager::updateDoorsAndClock() {
Common::String name = Common::String::format("633X%c-%02d.seq", (index - firstIndex) + 65, scene->position);
Sequence *sequence = loadSequence1(name, 255);
- // If the sequence doesn't exists, skip
- if (!sequence || !sequence->isLoaded())
+ // If the sequence doesn't exists or could not be loaded, skip index
+ if (!sequence)
continue;
// Adjust frame data and store in frame list
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 2c484f6976..944f6d47b1 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -502,6 +502,7 @@ public:
volume = _defaultVolume;
//Game data
+ field_0 = 0;
time = kTimeCityParis;
timeDelta = _defaultTimeDelta;
timeTicks = 0;
diff --git a/engines/lastexpress/graphics.cpp b/engines/lastexpress/graphics.cpp
index 753c3a39e4..9ced38a2e1 100644
--- a/engines/lastexpress/graphics.cpp
+++ b/engines/lastexpress/graphics.cpp
@@ -131,11 +131,11 @@ void GraphicsManager::mergePlanes() {
// Clear screen surface
_screen.fillRect(Common::Rect(640, 480), 0);
- uint16 *screen = (uint16 *)_screen.pixels;
- uint16 *inventory = (uint16 *)_inventory.pixels;
- uint16 *overlay = (uint16 *)_overlay.pixels;
- uint16 *backgroundC = (uint16 *)_backgroundC.pixels;
- uint16 *backgroundA = (uint16 *)_backgroundA.pixels;
+ uint16 *screen = (uint16 *)_screen.getPixels();
+ uint16 *inventory = (uint16 *)_inventory.getPixels();
+ uint16 *overlay = (uint16 *)_overlay.getPixels();
+ uint16 *backgroundC = (uint16 *)_backgroundC.getPixels();
+ uint16 *backgroundA = (uint16 *)_backgroundA.getPixels();
for (int i = 0; i < 640 * 480; i++) {
@@ -160,7 +160,7 @@ void GraphicsManager::mergePlanes() {
void GraphicsManager::updateScreen() {
g_system->fillScreen(0);
- g_system->copyRectToScreen(_screen.getBasePtr(0, 0), 640 * 2, 0, 0, 640, 480);
+ g_system->copyRectToScreen(_screen.getPixels(), 640 * 2, 0, 0, 640, 480);
}
} // End of namespace LastExpress
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 01d2634dec..bc1624d171 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -165,10 +165,10 @@ Common::Error LastExpressEngine::run() {
void LastExpressEngine::pollEvents() {
Common::Event ev;
- _eventMan->pollEvent(ev);
+ if (!_eventMan->pollEvent(ev))
+ return;
switch (ev.type) {
-
case Common::EVENT_LBUTTONUP:
getGameLogic()->getGameState()->getGameFlags()->mouseLeftClick = true;
break;
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 7fab4521f7..d0b439677d 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -260,8 +260,10 @@ void Hotspot::setAnimation(HotspotAnimData *newRecord) {
_anim = NULL;
_numFrames = 0;
_frameNumber = 0;
- if (!newRecord) return;
- if (!disk.exists(newRecord->animId)) return;
+ if (!newRecord)
+ return;
+ if (!disk.exists(newRecord->animId))
+ return;
// Scan for any size overrides - some animations get their size set after decoding, but
// we want it in advance so we can decode the animation straight to a graphic surface
@@ -516,7 +518,8 @@ void Hotspot::endAction() {
}
void Hotspot::setDirection(Direction dir) {
- if ((_numFrames == 0) || (_direction == dir)) return;
+ if ((_numFrames == 0) || (_direction == dir))
+ return;
uint8 newFrameNumber = 0;
switch (dir) {
@@ -634,7 +637,8 @@ void Hotspot::setOccupied(bool occupiedFlag) {
if (xp < 0) {
xp = -xp;
widthVal -= xp;
- if (widthVal <= 0) return;
+ if (widthVal <= 0)
+ return;
xp = 0;
}
@@ -642,7 +646,8 @@ void Hotspot::setOccupied(bool occupiedFlag) {
int x2 = xp + widthVal - ROOM_PATHS_WIDTH - 1;
if (x2 >= 0) {
widthVal -= (x2 + 1);
- if (widthVal <= 0) return;
+ if (widthVal <= 0)
+ return;
}
RoomPathsData &paths = Resources::getReference().getRoom(_roomNumber)->paths;
@@ -656,14 +661,16 @@ void Hotspot::setOccupied(bool occupiedFlag) {
// walks the character a single step in a sequence defined by the walking list
bool Hotspot::walkingStep() {
- if (_pathFinder.isEmpty()) return true;
+ if (_pathFinder.isEmpty())
+ return true;
// Check to see if the end of the next straight walking slice
if (_pathFinder.stepCtr() >= _pathFinder.top().numSteps()) {
// Move to next slice in walking sequence
_pathFinder.stepCtr() = 0;
_pathFinder.pop();
- if (_pathFinder.isEmpty()) return true;
+ if (_pathFinder.isEmpty())
+ return true;
}
if (_pathFinder.stepCtr() == 0)
@@ -782,13 +789,15 @@ void Hotspot::showMessage(uint16 messageId, uint16 destCharacterId) {
uint16 *v = (uint16 *) (msgData + READ_LE_UINT16(msgData + idx + sizeof(uint16)));
while ((idVal = READ_LE_UINT16(v)) != 0xffff) {
++v;
- if (READ_LE_UINT16(v) == messageId) break;
+ if (READ_LE_UINT16(v) == messageId)
+ break;
++v;
}
// default response if a specific response not found
- if (idVal == 0xffff) idVal = 0x8c4;
+ if (idVal == 0xffff)
+ idVal = 0x8c4;
debugC(ERROR_DETAILED, kLureDebugStrings, "Hotspot::showMessage idVal=%xh", idVal);
if (idVal == 0x76) {
@@ -826,7 +835,8 @@ void Hotspot::handleTalkDialog() {
Room &room = Room::getReference();
// Return if no talk dialog is necessary
- if (_data->talkCountdown == 0) return;
+ if (_data->talkCountdown == 0)
+ return;
debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk countdown = %d", _data->talkCountdown);
if (_data->talkCountdown == CONVERSE_COUNTDOWN_SIZE) {
@@ -933,7 +943,8 @@ static const uint16 validRoomExitHotspots[] = {0x2711, 0x2712, 0x2714, 0x2715, 0
bool Hotspot::isRoomExit(uint16 id) {
for (const uint16 *p = &validRoomExitHotspots[0]; *p != 0; ++p)
- if (*p == id) return true;
+ if (*p == id)
+ return true;
return false;
}
@@ -1043,7 +1054,7 @@ BarPlaceResult Hotspot::getBarPlace() {
index = -1;
while (++index < NUM_SERVE_CUSTOMERS) {
if (barEntry.customers[index].hotspotId == 0)
- break;
+ break;
}
if (index == NUM_SERVE_CUSTOMERS)
@@ -1391,7 +1402,8 @@ void Hotspot::doGet(HotspotData *hotspot) {
Resources &res = Resources::getReference();
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1409,7 +1421,8 @@ void Hotspot::doGet(HotspotData *hotspot) {
if (sequenceOffset != 0) {
uint16 execResult = Script::execute(sequenceOffset);
- if (execResult == 1) return;
+ if (execResult == 1)
+ return;
else if (execResult != 0) {
showMessage(execResult);
return;
@@ -1432,7 +1445,8 @@ void Hotspot::doOperate(HotspotData *hotspot) {
Action action = currentActions().top().supportData().action();
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1467,7 +1481,8 @@ void Hotspot::doOpen(HotspotData *hotspot) {
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1487,7 +1502,8 @@ void Hotspot::doOpen(HotspotData *hotspot) {
if (sequenceOffset != 0) {
sequenceOffset = Script::execute(sequenceOffset);
- if (sequenceOffset == 1) return;
+ if (sequenceOffset == 1)
+ return;
if (sequenceOffset != 0) {
if (_exitCtr != 0)
_exitCtr = 4;
@@ -1522,7 +1538,8 @@ void Hotspot::doClose(HotspotData *hotspot) {
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1575,7 +1592,8 @@ void Hotspot::doUse(HotspotData *hotspot) {
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1616,7 +1634,8 @@ void Hotspot::doGive(HotspotData *hotspot) {
}
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1662,7 +1681,8 @@ void Hotspot::doTalkTo(HotspotData *hotspot) {
(hotspot->hotspotId != BLACKSMITH_ID))) {
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1706,7 +1726,8 @@ void Hotspot::doTell(HotspotData *hotspot) {
assert(character);
HotspotPrecheckResult hsResult = actionPrecheck(hotspot);
- if (hsResult == PC_WAIT) return;
+ if (hsResult == PC_WAIT)
+ return;
else if (hsResult != PC_EXECUTE) {
endAction();
return;
@@ -1800,7 +1821,8 @@ void Hotspot::doAsk(HotspotData *hotspot) {
_data->useHotspotId = usedId;
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1886,14 +1908,17 @@ void Hotspot::doStatus(HotspotData *hotspot) {
HotspotData const &rec = **i;
if (rec.roomNumber == PLAYER_ID) {
- if (numItems++ == 0) strcat(buffer, ": ");
- else strcat(buffer, ", ");
+ if (numItems++ == 0)
+ strcat(buffer, ": ");
+ else
+ strcat(buffer, ", ");
strings.getString(rec.nameId, buffer + strlen(buffer));
}
}
// If there were no items, add in the word 'nothing'
- if (numItems == 0) strcat(buffer, stringList.getString(S_INV_NOTHING));
+ if (numItems == 0)
+ strcat(buffer, stringList.getString(S_INV_NOTHING));
// If the player has money, add it in
uint16 numGroats = res.fieldList().numGroats();
@@ -1943,7 +1968,8 @@ void Hotspot::doBribe(HotspotData *hotspot) {
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -1968,7 +1994,8 @@ void Hotspot::doBribe(HotspotData *hotspot) {
sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, BRIBE);
if (sequenceOffset != 0) {
sequenceOffset = Script::execute(sequenceOffset);
- if (sequenceOffset != 0) return;
+ if (sequenceOffset != 0)
+ return;
}
uint16 talkIndex = res.fieldList().getField(TALK_INDEX);
@@ -2004,7 +2031,8 @@ void Hotspot::doLockUnlock(HotspotData *hotspot) {
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -2156,7 +2184,8 @@ void Hotspot::npcTalkNpcToNpc(HotspotData *hotspot) {
fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
HotspotPrecheckResult result = actionPrecheck(hotspot);
- if (result == PC_WAIT) return;
+ if (result == PC_WAIT)
+ return;
else if (result != PC_EXECUTE) {
endAction();
return;
@@ -2594,7 +2623,8 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
if (h.characterMode() == CHARMODE_PLAYER_WAIT) {
h.updateMovement();
- if (bumpedPlayer) return;
+ if (bumpedPlayer)
+ return;
} else {
// All other character modes
if (h.delayCtr() > 0) {
@@ -2691,7 +2721,8 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
res.pausedList().scan(h);
pfResult = pathFinder.process();
- if (pfResult == PF_UNFINISHED) break;
+ if (pfResult == PF_UNFINISHED)
+ break;
debugC(ERROR_DETAILED, kLureDebugAnimations,
"pathFinder done: result = %d", pfResult);
@@ -2863,7 +2894,8 @@ void HotspotTickHandlers::roomExitAnimHandler(Hotspot &h) {
Room &room = Room::getReference();
RoomExitJoinData *rec = res.getExitJoin(h.hotspotId());
- if (!rec) return;
+ if (!rec)
+ return;
RoomExitJoinStruct &rs = (rec->hotspots[0].hotspotId == h.hotspotId()) ?
rec->hotspots[0] : rec->hotspots[1];
@@ -3036,7 +3068,8 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
res.pausedList().scan(h);
pfResult = pathFinder.process();
- if (pfResult == PF_UNFINISHED) break;
+ if (pfResult == PF_UNFINISHED)
+ break;
// Pathfinding is now complete
buffer = pathFinder.getDebugInfo();
@@ -3474,7 +3507,8 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) {
showSelections |= (entry->descId & 0x3fff) != TALK_MAGIC_ID;
}
- if ((entry->preSequenceId & 0x8000) != 0) break;
+ if ((entry->preSequenceId & 0x8000) != 0)
+ break;
}
if (showSelections && (numLines > 1)) {
@@ -3584,7 +3618,8 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) {
debugC(ERROR_DETAILED, kLureDebugAnimations, "Character response pre id = %xh",
_talkResponse->preSequenceId);
- if (!_talkResponse->preSequenceId) break;
+ if (!_talkResponse->preSequenceId)
+ break;
responseNumber = Script::execute(_talkResponse->preSequenceId);
debugC(ERROR_DETAILED, kLureDebugAnimations, "Character response new response = %d",
responseNumber);
@@ -3680,9 +3715,12 @@ void HotspotTickHandlers::grubAnimHandler(Hotspot &h) {
character = ratpouch;
}
- if (character->x() < 72) frameNumber = 0;
- else if (character->x() < 172) frameNumber = 1;
- else frameNumber = 2;
+ if (character->x() < 72)
+ frameNumber = 0;
+ else if (character->x() < 172)
+ frameNumber = 1;
+ else
+ frameNumber = 2;
h.setActionCtr(frameNumber);
h.setFrameNumber(frameNumber);
@@ -3782,7 +3820,8 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) {
// Moving right
h.setPosition(h.x() + 2, h.y());
h.setActionCtr(h.actionCtr() + 1);
- if (h.actionCtr() >= 6) h.setActionCtr(0);
+ if (h.actionCtr() >= 6)
+ h.setActionCtr(0);
}
} else {
// Stop the barman moving
@@ -4006,6 +4045,7 @@ void HotspotTickHandlers::rackSerfAnimHandler(Hotspot &h) {
h.setActionCtr(4);
h.setLayer(2);
+ // Deliberate fall-through
case 4:
if (HotspotScript::execute(&h)) {
h.setLayer(255);
@@ -4230,7 +4270,8 @@ PathFinderResult PathFinder::process() {
while (1) {
// Loop through to process cells in the given area
- if (!returnFlag) _yCtr = 0;
+ if (!returnFlag)
+ _yCtr = 0;
while (returnFlag || (_yCtr < ROOM_PATHS_HEIGHT)) {
if (!returnFlag) _xCtr = 0;
@@ -4238,7 +4279,8 @@ PathFinderResult PathFinder::process() {
if (!returnFlag) {
processCell(&_layer[(_yChangeStart + _yCtr * _yChangeInc) * DECODED_PATHS_WIDTH +
(_xChangeStart + _xCtr * _xChangeInc)]);
- if (breakFlag && (_countdownCtr <= 0)) return PF_UNFINISHED;
+ if (breakFlag && (_countdownCtr <= 0))
+ return PF_UNFINISHED;
} else {
returnFlag = false;
}
@@ -4248,7 +4290,8 @@ PathFinderResult PathFinder::process() {
}
// If the destination cell has been filled in, then break out of loop
- if (*_pDest != 0) break;
+ if (*_pDest != 0)
+ break;
if (_cellPopulated) {
// At least one cell populated, so go repeat loop
@@ -4306,27 +4349,37 @@ PathFinderResult PathFinder::process() {
currDirection = NO_DIRECTION;
while (1) {
v = *pCurrent - 1;
- if (v == 0) break;
+ if (v == 0)
+ break;
newDirection = NO_DIRECTION;
if (!altFlag && (currDirection != LEFT) && (currDirection != RIGHT)) {
// Standard order direction checking
- if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
- else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
- else if (*(pCurrent + 1) == v) newDirection = LEFT;
- else if (*(pCurrent - 1) == v) newDirection = RIGHT;
+ if (*(pCurrent - DECODED_PATHS_WIDTH) == v)
+ newDirection = DOWN;
+ else if (*(pCurrent + DECODED_PATHS_WIDTH) == v)
+ newDirection = UP;
+ else if (*(pCurrent + 1) == v)
+ newDirection = LEFT;
+ else if (*(pCurrent - 1) == v)
+ newDirection = RIGHT;
} else {
// Alternate order direction checking
- if (*(pCurrent + 1) == v) newDirection = LEFT;
- else if (*(pCurrent - 1) == v) newDirection = RIGHT;
- else if (*(pCurrent - DECODED_PATHS_WIDTH) == v) newDirection = DOWN;
- else if (*(pCurrent + DECODED_PATHS_WIDTH) == v) newDirection = UP;
+ if (*(pCurrent + 1) == v)
+ newDirection = LEFT;
+ else if (*(pCurrent - 1) == v)
+ newDirection = RIGHT;
+ else if (*(pCurrent - DECODED_PATHS_WIDTH) == v)
+ newDirection = DOWN;
+ else if (*(pCurrent + DECODED_PATHS_WIDTH) == v)
+ newDirection = UP;
}
if (newDirection == NO_DIRECTION)
error("Path finding process failed");
// Process for the specified direction
- if (newDirection != currDirection) add(newDirection, 0);
+ if (newDirection != currDirection)
+ add(newDirection, 0);
switch (newDirection) {
case UP:
@@ -4373,8 +4426,10 @@ PathFinderResult PathFinder::process() {
}
// Final Step
- if (_xPos < 0) add(RIGHT, -_xPos);
- else if (_xPos > 0) add(LEFT, _xPos);
+ if (_xPos < 0)
+ add(RIGHT, -_xPos);
+ else if (_xPos > 0)
+ add(LEFT, _xPos);
return result;
}
@@ -4401,16 +4456,20 @@ void PathFinder::processCell(uint16 *p) {
// Check the surrounding cells (up,down,left,right) for values
// Up
vTemp = *(p - DECODED_PATHS_WIDTH);
- if ((vTemp != 0) && (vTemp < vMax)) vMax = vTemp;
+ if ((vTemp != 0) && (vTemp < vMax))
+ vMax = vTemp;
// Down
vTemp = *(p + DECODED_PATHS_WIDTH);
- if ((vTemp != 0) && (vTemp < vMax)) vMax = vTemp;
+ if ((vTemp != 0) && (vTemp < vMax))
+ vMax = vTemp;
// Left
vTemp = *(p - 1);
- if ((vTemp != 0) && (vTemp < vMax)) vMax = vTemp;
+ if ((vTemp != 0) && (vTemp < vMax))
+ vMax = vTemp;
// Right
vTemp = *(p + 1);
- if ((vTemp != 0) && (vTemp < vMax)) vMax = vTemp;
+ if ((vTemp != 0) && (vTemp < vMax))
+ vMax = vTemp;
if (vMax != 0xffff) {
// A surrounding cell with a value was found
@@ -4432,7 +4491,8 @@ void PathFinder::scanLine(int numScans, int changeAmount, uint16 *&pEnd, int &v)
for (int ctr = 1; ctr <= numScans; ++ctr) {
pTemp += changeAmount;
if ((*pTemp != 0) && (*pTemp != 0xffff)) {
- if ((v < ctr) || ((v == ctr) && (*pTemp >= *pEnd))) return;
+ if ((v < ctr) || ((v == ctr) && (*pTemp >= *pEnd)))
+ return;
pEnd = pTemp;
v = ctr;
break;
@@ -4447,11 +4507,15 @@ void PathFinder::initVars() {
_destX = _hotspot->destX();
_destY = _hotspot->destY();
- if (_destX < 10) _destX -= 50;
- if (_destX >= FULL_SCREEN_WIDTH-10) _destX += 50;
+ if (_destX < 10)
+ _destX -= 50;
+ if (_destX >= FULL_SCREEN_WIDTH-10)
+ _destX += 50;
- _xPos = 0; _yPos = 0;
- _xDestPos = 0; _yDestPos = 0;
+ _xPos = 0;
+ _yPos = 0;
+ _xDestPos = 0;
+ _yDestPos = 0;
_xCurrent = _hotspot->x();
if (_xCurrent < 0) {
@@ -4621,7 +4685,8 @@ void Support::characterChangeRoom(Hotspot &h, uint16 roomNumber,
if (h.hotspotId() == PLAYER_ID) {
// Room change code for the player
- if (room.cursorState() != CS_NONE) return;
+ if (room.cursorState() != CS_NONE)
+ return;
PlayerNewPosition &p = fields.playerNewPos();
if (checkForIntersectingCharacter(h, newX, newY - 48, roomNumber)) {
@@ -4678,7 +4743,8 @@ bool Support::charactersIntersecting(HotspotData *hotspot1, HotspotData *hotspot
bool Support::isCharacterInList(uint16 *lst, int numEntries, uint16 charId) {
while (numEntries-- > 0)
- if (*lst++ == charId) return true;
+ if (*lst++ == charId)
+ return true;
return false;
}
diff --git a/engines/made/graphics.cpp b/engines/made/graphics.cpp
index 4d3fc7116a..a8e33774f6 100644
--- a/engines/made/graphics.cpp
+++ b/engines/made/graphics.cpp
@@ -83,7 +83,7 @@ void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, u
if ((maskFlags != 0) && (maskFlags != 2) && (pixelFlags != 0) && (pixelFlags != 2) && (cmdFlags != 0))
error("decompressImage() Unsupported flags: cmdFlags = %02X; maskFlags = %02X, pixelFlags = %02X", cmdFlags, maskFlags, pixelFlags);
- byte *destPtr = (byte *)surface.getBasePtr(0, 0);
+ byte *destPtr = (byte *)surface.getPixels();
byte lineBuf[640 * 4];
byte bitBuf[40];
@@ -196,7 +196,7 @@ void decompressMovieImage(byte *source, Graphics::Surface &surface, uint16 cmdOf
byte *maskBuffer = source + maskOffs;
byte *pixelBuffer = source + pixelOffs;
- byte *destPtr = (byte *)surface.getBasePtr(0, 0);
+ byte *destPtr = (byte *)surface.getPixels();
byte bitBuf[40];
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index cf450f7e25..573ff7faf1 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -248,7 +248,7 @@ void PmvPlayer::handleEvents() {
}
void PmvPlayer::updateScreen() {
- _vm->_system->copyRectToScreen(_surface->pixels, _surface->pitch,
+ _vm->_system->copyRectToScreen(_surface->getPixels(), _surface->pitch,
(320 - _surface->w) / 2, (200 - _surface->h) / 2, _surface->w, _surface->h);
_vm->_system->updateScreen();
}
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index ea7d57f82d..30848e8ec1 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -344,12 +344,12 @@ void Screen::drawSpriteChannels(const ClipInfo &clipInfo, int16 includeStateMask
void Screen::updateSprites() {
// TODO: This needs some more work, dirty rectangles are currently not used
- memcpy(_workScreen->pixels, _backgroundScreen->pixels, 64000);
+ memcpy(_workScreen->getPixels(), _backgroundScreen->getPixels(), 64000);
drawSpriteChannels(_backgroundScreenDrawCtx, 3, 0);
drawSpriteChannels(_workScreenDrawCtx, 1, 2);
- _vm->_system->copyRectToScreen(_workScreen->pixels, _workScreen->pitch, 0, 0, _workScreen->w, _workScreen->h);
+ _vm->_system->copyRectToScreen(_workScreen->getPixels(), _workScreen->pitch, 0, 0, _workScreen->w, _workScreen->h);
_vm->_screen->updateScreenAndWait(10);
}
@@ -593,7 +593,7 @@ void Screen::show() {
return;
drawSpriteChannels(_backgroundScreenDrawCtx, 3, 0);
- memcpy(_workScreen->pixels, _backgroundScreen->pixels, 64000);
+ memcpy(_workScreen->getPixels(), _backgroundScreen->getPixels(), 64000);
drawSpriteChannels(_workScreenDrawCtx, 1, 2);
_fx->run(_visualEffectNum, _workScreen, _palette, _newPalette, _paletteColorCount);
@@ -775,7 +775,7 @@ void Screen::unlockScreen() {
}
void Screen::showWorkScreen() {
- _vm->_system->copyRectToScreen(_workScreen->pixels, _workScreen->pitch, 0, 0, _workScreen->w, _workScreen->h);
+ _vm->_system->copyRectToScreen(_workScreen->getPixels(), _workScreen->pitch, 0, 0, _workScreen->w, _workScreen->h);
}
void Screen::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
diff --git a/engines/made/screenfx.cpp b/engines/made/screenfx.cpp
index ad71f1fb49..d069308a4b 100644
--- a/engines/made/screenfx.cpp
+++ b/engines/made/screenfx.cpp
@@ -368,7 +368,7 @@ void ScreenEffects::vfx07(Graphics::Surface *surface, byte *palette, byte *newPa
// "Screen slide in" right to left
void ScreenEffects::vfx08(Graphics::Surface *surface, byte *palette, byte *newPalette, int colorCount) {
for (int x = 8; x <= 320; x += 8) {
- _screen->copyRectToScreen(surface->getBasePtr(0, 0), surface->pitch, 320 - x, 0, x, 200);
+ _screen->copyRectToScreen(surface->getPixels(), surface->pitch, 320 - x, 0, x, 200);
_screen->updateScreenAndWait(25);
}
setPalette(palette);
@@ -529,7 +529,7 @@ void ScreenEffects::vfx19(Graphics::Surface *surface, byte *palette, byte *newPa
// "Screen slide in" bottom to top
void ScreenEffects::vfx20(Graphics::Surface *surface, byte *palette, byte *newPalette, int colorCount) {
for (int y = 4; y <= 200; y += 4) {
- _screen->copyRectToScreen(surface->getBasePtr(0, 0), surface->pitch, 0, 200 - y, 320, y);
+ _screen->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 200 - y, 320, y);
_screen->updateScreenAndWait(25);
}
diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp
index c57778fb71..0e3b50aa98 100644
--- a/engines/made/scriptfuncs.cpp
+++ b/engines/made/scriptfuncs.cpp
@@ -574,7 +574,7 @@ int16 ScriptFunctions::sfLoadMouseCursor(int16 argc, int16 *argv) {
PictureResource *flex = _vm->_res->getPicture(argv[2]);
if (flex) {
Graphics::Surface *surf = flex->getPicture();
- CursorMan.replaceCursor(surf->pixels, surf->w, surf->h, argv[1], argv[0], 0);
+ CursorMan.replaceCursor(surf->getPixels(), surf->w, surf->h, argv[1], argv[0], 0);
_vm->_res->freeResource(flex);
}
return 0;
diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp
index bc19fe2d3e..b321e043d9 100644
--- a/engines/mohawk/bitmap.cpp
+++ b/engines/mohawk/bitmap.cpp
@@ -580,7 +580,7 @@ void MohawkBitmap::drawRaw(Graphics::Surface *surface) {
_data->skip(_header.bytesPerRow - _header.width * 3);
} else {
- _data->read((byte *)surface->pixels + y * _header.width, _header.width);
+ _data->read((byte *)surface->getBasePtr(0, y), _header.width);
_data->skip(_header.bytesPerRow - _header.width);
}
}
@@ -599,7 +599,7 @@ void MohawkBitmap::drawRLE8(Graphics::Surface *surface, bool isLE) {
for (uint16 i = 0; i < _header.height; i++) {
uint16 rowByteCount = isLE ? _data->readUint16LE() : _data->readUint16BE();
int32 startPos = _data->pos();
- byte *dst = (byte *)surface->pixels + i * _header.width;
+ byte *dst = (byte *)surface->getBasePtr(0, i);
int16 remaining = _header.width;
while (remaining > 0) {
@@ -779,7 +779,7 @@ MohawkSurface *DOSBitmap::decodeImage(Common::SeekableReadStream *stream) {
}
Graphics::Surface *surface = createSurface(_header.width, _header.height);
- memset(surface->pixels, 0, _header.width * _header.height);
+ memset(surface->getPixels(), 0, _header.width * _header.height);
// Expand the <8bpp data to one byte per pixel
switch (getBitsPerPixel()) {
@@ -801,7 +801,7 @@ MohawkSurface *DOSBitmap::decodeImage(Common::SeekableReadStream *stream) {
void DOSBitmap::expandMonochromePlane(Graphics::Surface *surface, Common::SeekableReadStream *rawStream) {
assert(surface->format.bytesPerPixel == 1);
- byte *dst = (byte *)surface->pixels;
+ byte *dst = (byte *)surface->getPixels();
// Expand the 8 pixels in a byte into a full byte per pixel
@@ -830,7 +830,7 @@ void DOSBitmap::expandEGAPlanes(Graphics::Surface *surface, Common::SeekableRead
// Note that the image is in EGA planar form and not just standard 4bpp
// This seems to contradict the PoP specs which seem to do something else
- byte *dst = (byte *)surface->pixels;
+ byte *dst = (byte *)surface->getPixels();
for (uint32 i = 0; i < surface->h; i++) {
uint x = 0;
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index c7bd03678f..f70efde5fb 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -121,11 +121,11 @@ void MystCursorManager::setCursor(uint16 id) {
// Myst ME stores some cursors as 24bpp images instead of 8bpp
if (surface->format.bytesPerPixel == 1) {
- CursorMan.replaceCursor(surface->pixels, surface->w, surface->h, hotspotX, hotspotY, 0);
+ CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, 0);
CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
} else {
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
- CursorMan.replaceCursor(surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
+ CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
}
_vm->_needsUpdate = true;
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index efa0dd3fd3..634ff441b6 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -311,8 +311,8 @@ void MohawkEngine_LivingBooks::loadBookInfo(const Common::String &filename) {
// - fDebugWindow (always 0?)
if (_bookInfoFile.hasSection("Globals")) {
- const Common::ConfigFile::SectionKeyList globals = _bookInfoFile.getKeys("Globals");
- for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
+ const Common::INIFile::SectionKeyList globals = _bookInfoFile.getKeys("Globals");
+ for (Common::INIFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
LBCode tempCode(this, 0);
uint offset = tempCode.parseCode(command);
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index 76da7d8219..615fcd0e16 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -28,7 +28,7 @@
#include "mohawk/livingbooks_graphics.h"
#include "mohawk/sound.h"
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/rect.h"
#include "common/queue.h"
#include "common/random.h"
@@ -759,7 +759,7 @@ public:
private:
LivingBooksConsole *_console;
- Common::ConfigFile _bookInfoFile;
+ Common::INIFile _bookInfoFile;
Common::String getBookInfoFileName() const;
void loadBookInfo(const Common::String &filename);
diff --git a/engines/mohawk/livingbooks_lbx.cpp b/engines/mohawk/livingbooks_lbx.cpp
index 2b8b22ec81..dcf8caa4a5 100644
--- a/engines/mohawk/livingbooks_lbx.cpp
+++ b/engines/mohawk/livingbooks_lbx.cpp
@@ -33,7 +33,7 @@ public:
bool call(uint callId, const Common::Array<LBValue> &params, LBValue &result);
protected:
- Common::ConfigFile _dataFile;
+ Common::INIFile _dataFile;
Common::String _curSection;
void open(const Common::String &filename);
@@ -77,8 +77,8 @@ bool LBXDataFile::call(uint callId, const Common::Array<LBValue> &params, LBValu
case kLBXDataFileGetSectionList:
{
Common::SharedPtr<LBList> list = Common::SharedPtr<LBList>(new LBList);
- Common::ConfigFile::SectionList sections = _dataFile.getSections();
- for (Common::List<Common::ConfigFile::Section>::const_iterator i = sections.begin(); i != sections.end(); ++i)
+ Common::INIFile::SectionList sections = _dataFile.getSections();
+ for (Common::List<Common::INIFile::Section>::const_iterator i = sections.begin(); i != sections.end(); ++i)
list->array.push_back(LBValue(i->name));
result = LBValue(list);
}
@@ -103,8 +103,8 @@ bool LBXDataFile::call(uint callId, const Common::Array<LBValue> &params, LBValu
error("incorrect number of parameters (%d) to LBXDataFile::loadCurSectionVars", params.size());
{
- const Common::ConfigFile::SectionKeyList globals = _dataFile.getKeys(_curSection);
- for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
+ const Common::INIFile::SectionKeyList globals = _dataFile.getKeys(_curSection);
+ for (Common::INIFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
LBCode tempCode(_vm, 0);
uint offset = tempCode.parseCode(command);
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 8140817eb3..975c6c2a21 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -418,6 +418,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_sound->stopSound();
_sound->stopBackgroundMyst();
+ _video->stopVideos();
if (linkSrcSound)
_sound->playSoundBlocking(linkSrcSound);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f17d765c99..dc5f433ce7 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -691,6 +691,7 @@ void Myst::toggleVar(uint16 var) {
else
_state.courtyardImageBoxes |= mask;
}
+ break;
case 41: // Vault white page
if (_globals.ending != 4) {
if (_dockVaultState == 1) {
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
index 05e66a3924..cd15960b85 100644
--- a/engines/mohawk/riven_graphics.cpp
+++ b/engines/mohawk/riven_graphics.cpp
@@ -255,7 +255,7 @@ void RivenGraphics::runScheduledTransition() {
}
// For now, just copy the image to screen without doing any transition.
- _vm->_system->copyRectToScreen(_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->copyRectToScreen(_mainScreen->getPixels(), _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
_vm->_system->updateScreen();
_scheduledTransition = -1; // Clear scheduled transition
@@ -345,7 +345,7 @@ void RivenGraphics::drawInventoryImage(uint16 id, const Common::Rect *rect) {
mhkSurface->convertToTrueColor();
Graphics::Surface *surface = mhkSurface->getSurface();
- _vm->_system->copyRectToScreen(surface->pixels, surface->pitch, rect->left, rect->top, surface->w, surface->h);
+ _vm->_system->copyRectToScreen(surface->getPixels(), surface->pitch, rect->left, rect->top, surface->w, surface->h);
delete mhkSurface;
}
@@ -420,7 +420,7 @@ void RivenGraphics::updateCredits() {
} else {
// Otheriwse, we're scrolling
// Move the screen up one row
- memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
+ memmove(_mainScreen->getPixels(), _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
// Only update as long as we're not before the last frame
// Otherwise, we're just moving up a row (which we already did)
@@ -437,7 +437,7 @@ void RivenGraphics::updateCredits() {
}
// Now flush the new screen
- _vm->_system->copyRectToScreen(_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->copyRectToScreen(_mainScreen->getPixels(), _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
_vm->_system->updateScreen();
}
}
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 8b0130d711..b7e06a2b9f 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -245,7 +245,7 @@ bool VideoManager::updateMovies() {
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);
- _vm->_system->copyRectToScreen(frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
// We've drawn something to the screen, make sure we update it
updateScreen = true;
diff --git a/engines/mortevielle/actions.cpp b/engines/mortevielle/actions.cpp
new file mode 100644
index 0000000000..b68dd48b0f
--- /dev/null
+++ b/engines/mortevielle/actions.cpp
@@ -0,0 +1,1674 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/dialogs.h"
+#include "mortevielle/menu.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+
+#include "common/scummsys.h"
+
+namespace Mortevielle {
+
+/**
+ * Engine function - Move
+ * @remarks Originally called 'taller'
+ */
+void MortevielleEngine::fctMove() {
+ int oldMenu = (_menu._moveMenu[6]._menuId << 8) | _menu._moveMenu[6]._actionId;
+ if ((_coreVar._currPlace == ROOM26) && (_currAction == oldMenu)) {
+ _coreVar._currPlace = LANDING;
+ _caff = _coreVar._currPlace;
+ drawPictureWithText();
+ handleDescriptionText(2, _coreVar._currPlace);
+ }
+ if ((_coreVar._currPlace == LANDING) && (_currAction == oldMenu)) {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_GO_TO));
+ displayStatusArrow();
+
+ if (_keyPressedEsc)
+ _destinationOk = false;
+
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+
+ setCoordinates(1);
+
+ if (_num == 0)
+ return;
+
+ if (_num == 1) {
+ _coreVar._currPlace = OWN_ROOM;
+ _menu.setDestinationText(OWN_ROOM);
+ } else if (_num == 7) {
+ _coreVar._currPlace = ATTIC;
+ _menu.setDestinationText(ATTIC);
+ } else if (_num != 6)
+ _coreVar._currPlace = ROOM26;
+
+ if ((_num > 1) && (_num < 6))
+ _roomDoorId = _num - 1;
+ else if (_num > 7)
+ _roomDoorId = _num - 3;
+
+ if (_num != 6)
+ prepareDisplayText();
+ else
+ showMoveMenuAlert();
+ return;
+ }
+ exitRoom();
+ int menuChoice = 1;
+ oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
+ while (oldMenu != _currAction) {
+ ++menuChoice;
+ oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
+ }
+
+ switch (_coreVar._currPlace) {
+ case MOUNTAIN:
+ if (menuChoice == 1)
+ gotoManorFront();
+ else if (menuChoice == 2)
+ checkManorDistance();
+ _menu.setDestinationText(_coreVar._currPlace);
+ return;
+ case INSIDE_WELL:
+ if (menuChoice == 1)
+ floodedInWell();
+ else if (menuChoice == 2)
+ gotoManorBack();
+ _menu.setDestinationText(_coreVar._currPlace);
+ return;
+ case BUREAU:
+ if (menuChoice == 1)
+ menuChoice = 6;
+ break;
+ case KITCHEN:
+ if (menuChoice == 2)
+ menuChoice = 6;
+ else if (menuChoice == 5)
+ menuChoice = 16;
+ break;
+ case CELLAR:
+ if (menuChoice == 3)
+ menuChoice = 6;
+ break;
+ case LANDING:
+ case ROOM26:
+ if (menuChoice == 4)
+ menuChoice = 6;
+ break;
+ }
+
+ if ((_coreVar._currPlace > MOUNTAIN) && (_coreVar._currPlace != ROOM26))
+ menuChoice += 10;
+
+ if ((_coreVar._currPlace == CHAPEL) && (menuChoice == 13))
+ menuChoice = 16;
+ else if (_coreVar._currPlace == MANOR_FRONT) {
+ if (menuChoice == 12)
+ menuChoice = 16;
+ else if (menuChoice > 13)
+ menuChoice = 15;
+ } else if ((_coreVar._currPlace == MANOR_BACK) && (menuChoice > 14))
+ menuChoice = 15;
+ else if ((_coreVar._currPlace == WELL) && (menuChoice > 13) && (menuChoice != 17))
+ menuChoice = 15;
+
+ switch (menuChoice) {
+ case 1:
+ _coreVar._currPlace = BUREAU;
+ break;
+ case 2:
+ _coreVar._currPlace = KITCHEN;
+ break;
+ case 3:
+ _coreVar._currPlace = CELLAR;
+ break;
+ case 4:
+ _coreVar._currPlace = LANDING;
+ break;
+ case 5:
+ case 12:
+ gotoManorFront();
+ break;
+ case 6:
+ case 11:
+ gotoDiningRoom();
+ break;
+ case 13:
+ _coreVar._currPlace = CHAPEL;
+ break;
+ case 14:
+ _coreVar._currPlace = WELL;
+ break;
+ case 15:
+ checkManorDistance();
+ break;
+ case 16:
+ gotoManorBack();
+ break;
+ case 17:
+ if ((_coreVar._wellObjectId != 120) && (_coreVar._wellObjectId != 140))
+ _crep = 997;
+ else if (_coreVar._wellObjectId == 120)
+ _crep = 181;
+ else if (_coreVar._faithScore > 80) {
+ _crep = 1505;
+ loseGame();
+ } else {
+ _coreVar._currPlace = INSIDE_WELL;
+ prepareDisplayText();
+ }
+ break;
+ }
+
+ if ((menuChoice < 5) || (menuChoice == 13) || (menuChoice == 14))
+ prepareDisplayText();
+ resetRoomVariables(_coreVar._currPlace);
+ _menu.setDestinationText(_coreVar._currPlace);
+}
+
+/**
+ * Engine function - Take
+ * @remarks Originally called 'tprendre'
+ */
+void MortevielleEngine::fctTake() {
+ if (_caff > 99) {
+ int cx = _caff;
+ putInHand(cx);
+ if (_crep != 139) {
+ if (_currBitIndex > 0)
+ _coreVar._faithScore += 3;
+ if (_obpart) {
+ if (_coreVar._currPlace == PURPLE_ROOM)
+ _coreVar._purpleRoomObjectId = 0;
+ if (_coreVar._currPlace == ATTIC) {
+ if (_coreVar._atticBallHoleObjectId == _caff)
+ _coreVar._atticBallHoleObjectId = 0;
+ if (_coreVar._atticRodHoleObjectId == _caff)
+ _coreVar._atticRodHoleObjectId = 0;
+ }
+ if (_coreVar._currPlace == CELLAR)
+ _coreVar._cellarObjectId = 0;
+ if (_coreVar._currPlace == CRYPT)
+ _coreVar._cryptObjectId = 0;
+ if (_coreVar._currPlace == SECRET_PASSAGE)
+ _coreVar._secretPassageObjectId = 0;
+ if (_coreVar._currPlace == WELL)
+ _coreVar._wellObjectId = 0;
+ _menu.unsetSearchMenu();
+ _obpart = false;
+ prepareDisplayText();
+ } else {
+ _tabdon[kAcha + ((_curSearchObjId - 1) * 10) + _searchCount - 1] = 0;
+ prepareNextObject();
+ ++_takeObjCount;
+ if (_takeObjCount > 6) {
+ _coreVar._faithScore += 2;
+ _takeObjCount = 0;
+ }
+ }
+ }
+ return;
+ }
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_TAKE));
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ if (_caff == 3) {
+ setCoordinates(2);
+ if (_num == 1) {
+ _crep = 152;
+ return;
+ }
+ }
+ setCoordinates(5);
+ if ((_num == 0) || ((_num == 1) && (_coreVar._currPlace == CRYPT))) {
+ setCoordinates(8);
+ if (_num != 0) {
+ 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);
+ }
+ }
+ 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;
+ }
+ } else {
+ if ( ((_coreVar._currPlace == OWN_ROOM) && (_num == 3))
+ || ((_coreVar._currPlace == GREEN_ROOM) && (_num == 4))
+ || ((_coreVar._currPlace == PURPLE_ROOM) && (_num == 1))
+ || ((_coreVar._currPlace == DARKBLUE_ROOM) && (_num == 3))
+ || ((_coreVar._currPlace == BLUE_ROOM) && (_num == 6))
+ || ((_coreVar._currPlace == RED_ROOM) && (_num == 2))
+ || ((_coreVar._currPlace == BATHROOM) && (_num == 6))
+ || ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 4))
+ || ((_coreVar._currPlace == JULIA_ROOM) && (_num == 4))
+ || ((_coreVar._currPlace == DINING_ROOM) && (_num > 2))
+ || ((_coreVar._currPlace == BUREAU) && (_num == 7))
+ || ((_coreVar._currPlace == KITCHEN) && (_num == 6))
+ || ((_coreVar._currPlace == ATTIC) && (_num > 4))
+ || ((_coreVar._currPlace > ATTIC) && (_coreVar._currPlace != INSIDE_WELL)) )
+ _crep = 997;
+ else if (_coreVar._currPlace == INSIDE_WELL) {
+ _crep = 1504;
+ loseGame();
+ } else
+ _crep = 120;
+ }
+}
+/**
+ * Engine function - Inventory / Take
+ * @remarks Originally called 'tsprendre'
+ */
+void MortevielleEngine::fctInventoryTake() {
+ int inventIndex = 0;
+ int oldMenu = 0;
+ do {
+ ++inventIndex;
+ oldMenu = (_menu._inventoryMenu[inventIndex]._menuId << 8) | _menu._inventoryMenu[inventIndex]._actionId;
+ } while (oldMenu != _currAction);
+ int cz = 0;
+ int cy = 0;
+ do {
+ ++cy;
+ if (_coreVar._inventory[cy] != 0)
+ ++cz;
+ } while (cz != inventIndex);
+ cz = _coreVar._inventory[cy];
+ _coreVar._inventory[cy] = 0;
+ _menu.setInventoryText();
+ putInHand(cz);
+ _crep = 998;
+ clearDescriptionBar();
+}
+
+/**
+ * Engine function - Lift
+ * @remarks Originally called 'tsoulever'
+ */
+void MortevielleEngine::fctLift() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_LIFT));
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ setCoordinates(3);
+ if (_num == 0) {
+ setCoordinates(8);
+ if (_num != 0) {
+ if (_currBitIndex > 0)
+ ++_coreVar._faithScore;
+ _crep = 997;
+ if ((_coreVar._currPlace == PURPLE_ROOM) && (_coreVar._purpleRoomObjectId != 0))
+ displayLookScreen(_coreVar._purpleRoomObjectId);
+ }
+ return;
+ }
+ if (_currBitIndex > 0)
+ ++_coreVar._faithScore;
+ int tmpPlace = _coreVar._currPlace;
+ if (_coreVar._currPlace == CRYPT)
+ tmpPlace = 14;
+ else if (_coreVar._currPlace == MOUNTAIN)
+ tmpPlace = 15;
+ _crep = _tabdon[kAsoul + (tmpPlace << 3) + (_num - 1)];
+ if (_crep == 255)
+ _crep = 997;
+}
+
+/**
+ * Engine function - Read
+ * @remarks Originally called 'tlire'
+ */
+void MortevielleEngine::fctRead() {
+ if (_caff > 99)
+ getReadDescription(_caff);
+ else {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_READ));
+ displayStatusArrow();
+ if (!(_anyone) && !(_keyPressedEsc)) {
+ setCoordinates(4);
+ if (_num != 0)
+ _crep = 107;
+ }
+ }
+}
+
+/**
+ * Engine function - Self / Read
+ * @remarks Originally called 'tslire'
+ */
+void MortevielleEngine::fctSelfRead() {
+ if (_coreVar._selectedObjectId == 0)
+ _crep = 186;
+ else
+ getReadDescription(_coreVar._selectedObjectId);
+}
+
+/**
+ * Engine function - Look
+ * @remarks Originally called 'tregarder'
+ */
+void MortevielleEngine::fctLook() {
+ if (_caff > 99) {
+ _crep = 103;
+ return;
+ }
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_LOOK));
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ setCoordinates(5);
+ if (_num == 0) {
+ setCoordinates(8);
+ _crep = 131;
+ if (_num != 0) {
+ if (_coreVar._currPlace == ATTIC) {
+ if (_num == 1) {
+ _crep = 164;
+ if (_coreVar._atticRodHoleObjectId != 0)
+ displayLookScreen(_coreVar._atticRodHoleObjectId);
+ else if (_coreVar._atticBallHoleObjectId != 0)
+ displayLookScreen(_coreVar._atticBallHoleObjectId);
+ } else {
+ _crep = 193;
+ if (_coreVar._atticRodHoleObjectId != 0)
+ displayLookScreen(_coreVar._atticRodHoleObjectId);
+ }
+ }
+ if (_coreVar._currPlace == CELLAR) {
+ _crep = 164;
+ if (_coreVar._cellarObjectId != 0)
+ displayLookScreen(_coreVar._cellarObjectId);
+ }
+ if (_coreVar._currPlace == SECRET_PASSAGE) {
+ _crep = 174;
+ if (_coreVar._secretPassageObjectId != 0)
+ displayLookScreen(_coreVar._secretPassageObjectId);
+ }
+ if (_coreVar._currPlace == WELL) {
+ _crep = 131;
+ if (_coreVar._wellObjectId != 0)
+ displayLookScreen(_coreVar._wellObjectId);
+ }
+ }
+ return;
+ }
+ int cx = _coreVar._currPlace;
+ if (_coreVar._currPlace == CHAPEL)
+ cx = 17;
+ if ((_coreVar._currPlace > MANOR_FRONT) && (_coreVar._currPlace < DOOR))
+ cx -= 4;
+ if (_coreVar._currPlace == ROOM26)
+ cx = 21;
+ _crep = _tabdon[kArega + (cx * 7) + _num - 1];
+ if ((_coreVar._currPlace == ATTIC) && (_num == 8))
+ _crep = 126;
+ if (_coreVar._currPlace == MOUNTAIN)
+ _crep = 103;
+ if (_crep == 255)
+ _crep = 131;
+ if ((_coreVar._currPlace == GREEN_ROOM) && (_num == 1))
+ displayLookScreen(144);
+ if ((_coreVar._currPlace == BLUE_ROOM) && (_num == 3))
+ displayLookScreen(147);
+ if ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 3))
+ displayLookScreen(149);
+ if ((_coreVar._currPlace == JULIA_ROOM) && (_num == 2))
+ displayLookScreen(30);
+ if ((_coreVar._currPlace == DINING_ROOM) && (_num == 3))
+ displayLookScreen(31);
+}
+
+/**
+ * Engine function - Self / Look
+ * @remarks Originally called 'tsregarder'
+ */
+void MortevielleEngine::fctSelftLook() {
+ if (_coreVar._selectedObjectId != 0)
+ displayLookScreen(_coreVar._selectedObjectId);
+ else
+ _crep = 186;
+}
+
+/**
+ * Engine function - Search
+ * @remarks Originally called 'tfouiller'
+ */
+void MortevielleEngine::fctSearch() {
+ static const byte answerArr[14] = {123, 104, 123, 131, 131, 123, 104, 131, 123, 123, 106, 123, 123, 107};
+
+ if (_caff > 99) {
+ getSearchDescription(_caff);
+ return;
+ }
+
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_SEARCH));
+
+ displayStatusArrow();
+ if (_anyone || _keyPressedEsc)
+ return;
+
+ if (_coreVar._currPlace == INSIDE_WELL) {
+ _crep = 1504;
+ loseGame();
+ return;
+ }
+
+ setCoordinates(6);
+ if (_num == 0) {
+ setCoordinates(7);
+ if (_num != 0) {
+ int i;
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
+ if (_currBitIndex > 0)
+ _coreVar._faithScore += 3;
+
+ _curSearchObjId = getFirstObject();
+ if (_curSearchObjId != 0) {
+ _searchCount = 0;
+ _heroSearching = true;
+ _menu.setSearchMenu();
+ prepareNextObject();
+ } else
+ _crep = 997;
+ } else
+ _crep = 187;
+ } else {
+ setCoordinates(8);
+ _crep = 997;
+ if (_num != 0) {
+ if (_currBitIndex > 0)
+ _coreVar._faithScore += 3;
+ if ((_coreVar._currPlace != WELL) && (_coreVar._currPlace != SECRET_PASSAGE) && (_coreVar._currPlace != ATTIC)) {
+ if (_coreVar._currPlace == PURPLE_ROOM) {
+ _crep = 123;
+ if (_coreVar._purpleRoomObjectId != 0)
+ displayLookScreen(_coreVar._purpleRoomObjectId);
+ }
+ if (_coreVar._currPlace == CRYPT) {
+ _crep = 123;
+ if (_coreVar._cryptObjectId != 0)
+ displayLookScreen(_coreVar._cryptObjectId);
+ }
+ }
+ }
+ }
+ } else {
+ if (_currBitIndex > 0)
+ _coreVar._faithScore += 3;
+ _crep = 997;
+ if (_coreVar._currPlace < CELLAR)
+ _crep = answerArr[_coreVar._currPlace];
+
+ if ((_coreVar._currPlace == TOILETS) && (_num == 2))
+ _crep = 162;
+
+ if (_coreVar._currPlace == KITCHEN) {
+ if ((_num == 3) || (_num == 4))
+ _crep = 162;
+ else if (_num == 5)
+ _crep = 159;
+ }
+
+ if (_coreVar._currPlace == MOUNTAIN)
+ _crep = 104;
+ else if (_coreVar._currPlace == CRYPT)
+ _crep = 155;
+ }
+}
+
+/**
+ * Engine function - Self / Search
+ * @remarks Originally called 'tsfouiller'
+ */
+void MortevielleEngine::fctSelfSearch() {
+ if (_coreVar._selectedObjectId != 0)
+ getSearchDescription(_coreVar._selectedObjectId);
+ else
+ _crep = 186;
+}
+
+/**
+ * Engine function - Open
+ * @remarks Originally called 'touvrir'
+ */
+void MortevielleEngine::fctOpen() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_OPEN));
+
+ if (_caff == ROOM26) {
+ if (_roomDoorId != OWN_ROOM) {
+ _currAction = _menu._opcodeEnter;
+ _syn = true;
+ } else
+ _crep = 997;
+ return;
+ }
+
+ if (_caff == LANDING) {
+ showMoveMenuAlert();
+ return;
+ }
+
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+
+ setCoordinates(7);
+ if (_num != 0) {
+ if (_currBitIndex > 0)
+ _coreVar._faithScore += 2;
+ ++_openObjCount;
+ int i;
+ for (i = 1; (i <= 6); i++) {
+ if ((_openObjects[i] == 0) || (_openObjects[i] == _num))
+ break;
+ }
+
+ if (i > 6) {
+ warning("Unexpected action: Too many open objects");
+ return;
+ }
+
+ if (_openObjects[i] == _num)
+ // display "Already Opened"
+ _crep = 18;
+ else {
+ if (!( ((_num == 3) && ((_coreVar._currPlace == OWN_ROOM)
+ || (_coreVar._currPlace == JULIA_ROOM)
+ || (_coreVar._currPlace == BLUE_ROOM)
+ || (_coreVar._currPlace == BATHROOM)))
+ || ((_num == 4) && ((_coreVar._currPlace == GREEN_ROOM)
+ || (_coreVar._currPlace == PURPLE_ROOM)
+ || (_coreVar._currPlace == RED_ROOM)))
+ || ((_coreVar._currPlace == DARKBLUE_ROOM) && (_num == 5))
+ || ((_num == 6) && ((_coreVar._currPlace == BATHROOM)
+ || (_coreVar._currPlace == DINING_ROOM)
+ || (_coreVar._currPlace == GREEN_ROOM2)
+ || (_coreVar._currPlace == ATTIC)))
+ || ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 2))
+ || ((_coreVar._currPlace == KITCHEN) && (_num == 7))) ) {
+ if ( ((_coreVar._currPlace > DINING_ROOM) && (_coreVar._currPlace < CELLAR))
+ || ((_coreVar._currPlace > RED_ROOM) && (_coreVar._currPlace < DINING_ROOM))
+ || (_coreVar._currPlace == OWN_ROOM)
+ || (_coreVar._currPlace == PURPLE_ROOM)
+ || (_coreVar._currPlace == BLUE_ROOM)) {
+ if (getRandomNumber(1, 4) == 3)
+ _soundManager.startSpeech(7, 9, 1);
+ }
+ _openObjects[i] = _num;
+ displayAnimFrame(1, _num);
+ _soundManager.waitSpeech();
+ }
+ int tmpPlace = _coreVar._currPlace;
+ if (_coreVar._currPlace == CRYPT)
+ tmpPlace = CELLAR;
+ _crep = _tabdon[kAouvr + (tmpPlace * 7) + _num - 1];
+ if (_crep == 254)
+ _crep = 999;
+ }
+ }
+}
+
+/**
+ * Engine function - Place
+ * @remarks Originally called 'tmettre'
+ */
+void MortevielleEngine::fctPlace() {
+ if (_coreVar._selectedObjectId == 0) {
+ _crep = 186;
+ return;
+ }
+
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_PUT));
+
+ displayStatusArrow();
+ if (_keyPressedEsc)
+ _crep = 998;
+
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+
+ setCoordinates(8);
+ if (_num != 0) {
+ _crep = 999;
+ if (_caff == ATTIC) {
+ if (_num == 1) {
+ if (_coreVar._atticBallHoleObjectId != 0) {
+ _crep = 188;
+ } else {
+ _coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
+ if (_coreVar._selectedObjectId == 141)
+ displayAnimFrame(1, 7);
+ }
+ } else if (_coreVar._atticRodHoleObjectId != 0) {
+ _crep = 188;
+ } else {
+ _coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
+ if (_coreVar._selectedObjectId == 159)
+ displayAnimFrame(1, 6);
+ }
+ }
+
+ if (_caff == CELLAR) {
+ if (_coreVar._cellarObjectId != 0) {
+ _crep = 188;
+ } else {
+ _coreVar._cellarObjectId = _coreVar._selectedObjectId;
+ if (_coreVar._selectedObjectId == 151) {
+ // Open hidden passage
+ displayAnimFrame(1, 2);
+ displayAnimFrame(1, 1);
+ handleDescriptionText(2, 165);
+ displayEmptyHand();
+ _soundManager.startSpeech(6, -9, 1);
+
+ // Do you want to enter the hidden passage?
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ if (answer == 1) {
+ Common::String alertTxt = getString(582);
+ _dialogManager.show(alertTxt);
+
+ bool enterPassageFl = _dialogManager.showKnowledgeCheck();
+ _mouse.hideMouse();
+ clearScreen();
+ drawRightFrame();
+ clearDescriptionBar();
+ clearVerbBar();
+ _mouse.showMouse();
+ prepareRoom();
+ drawClock();
+ if (_currBitIndex != 0)
+ showPeoplePresent(_currBitIndex);
+ else
+ displayAloneText();
+
+ _menu.displayMenu();
+ if (enterPassageFl) {
+ _coreVar._currPlace = SECRET_PASSAGE;
+ _menu.setDestinationText(SECRET_PASSAGE);
+ } else {
+ _menu.setDestinationText(_coreVar._currPlace);
+ setPal(14);
+ drawPicture();
+ displayAnimFrame(1, 2);
+ displayAnimFrame(1, 1);
+ alertTxt = getString(577);
+ _dialogManager.show(alertTxt);
+ displayAnimFrame(2, 1);
+ _crep = 166;
+ }
+ prepareDisplayText();
+ } else {
+ displayAnimFrame(2, 1);
+ _crep = 166;
+ }
+ return;
+ }
+ }
+ }
+
+ if (_caff == CRYPT) {
+ if (_coreVar._cryptObjectId == 0)
+ _coreVar._cryptObjectId = _coreVar._selectedObjectId;
+ else
+ _crep = 188;
+ }
+
+ if (_caff == SECRET_PASSAGE) {
+ if (_coreVar._secretPassageObjectId != 0) {
+ _crep = 188;
+ } else if (_coreVar._selectedObjectId == 143) {
+ _coreVar._secretPassageObjectId = 143;
+ displayAnimFrame(1, 1);
+ } else {
+ _crep = 1512;
+ loseGame();
+ }
+ }
+
+ if (_caff == WELL) {
+ if (_coreVar._wellObjectId != 0) {
+ _crep = 188;
+ } else if ((_coreVar._selectedObjectId == 140) || (_coreVar._selectedObjectId == 120)) {
+ _coreVar._wellObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 1);
+ } else {
+ _crep = 185;
+ }
+ }
+
+ if (_crep != 188)
+ displayEmptyHand();
+ }
+}
+
+/**
+ * Engine function - Turn
+ * @remarks Originally called 'ttourner'
+ */
+void MortevielleEngine::fctTurn() {
+ if (_caff > 99) {
+ _crep = 149;
+ return;
+ }
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_TURN));
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ setCoordinates(9);
+ if (_num != 0) {
+ _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));
+ if (answer == 1)
+ _endGame = true;
+ else
+ _crep = 168;
+ }
+ 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));
+ if (answer == 1) {
+ _coreVar._currPlace = CRYPT;
+ prepareDisplayText();
+ } else
+ _crep = 176;
+ }
+ }
+}
+
+/**
+ * Engine function - Hide Self
+ * @remarks Originally called 'tcacher'
+ */
+void MortevielleEngine::fctSelfHide() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_HIDE_SELF));
+ displayStatusArrow();
+ if (!(_anyone) && !(_keyPressedEsc)) {
+ setCoordinates(10);
+ if (_num == 0)
+ _hiddenHero = false;
+ else {
+ _hiddenHero = true;
+ _crep = 999;
+ }
+ }
+}
+
+/**
+ * Engine function - Attach
+ * @remarks Originally called 'tattacher'
+ */
+void MortevielleEngine::fctAttach() {
+ if (_coreVar._selectedObjectId == 0)
+ _crep = 186;
+ else {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_TIE));
+ displayStatusArrow();
+ if (!(_anyone) && !(_keyPressedEsc)) {
+ setCoordinates(8);
+ _crep = 997;
+ if ((_num != 0) && (_coreVar._currPlace == WELL)) {
+ _crep = 999;
+ if ((_coreVar._selectedObjectId == 120) || (_coreVar._selectedObjectId == 140)) {
+ _coreVar._wellObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 1);
+ } else
+ _crep = 185;
+ displayEmptyHand();
+ }
+ }
+ }
+}
+
+/**
+ * Engine function - Close
+ * @remarks Originally called 'tfermer'
+ */
+void MortevielleEngine::fctClose() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_CLOSE));
+
+ if (_caff < ROOM26) {
+ displayStatusArrow();
+ if (_keyPressedEsc)
+ _crep = 998;
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ setCoordinates(7);
+ if (_num != 0) {
+ int i;
+ for (i = 1; i <= 6; ++i) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
+ displayAnimFrame(2, _num);
+ _crep = 998;
+ _openObjects[i] = 0;
+ --_openObjCount;
+ if (_openObjCount < 0)
+ _openObjCount = 0;
+ int objId = getFirstObject();
+ if (_curSearchObjId == objId)
+ _curSearchObjId = 0;
+ } else {
+ _crep = 187;
+ }
+ }
+ }
+ if (_caff == ROOM26)
+ _crep = 999;
+}
+
+/**
+ * Engine function - Knock
+ * @remarks Originally called 'tfrapper'
+ */
+void MortevielleEngine::fctKnock() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_HIT));
+
+ if (_coreVar._currPlace == LANDING) {
+ _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU));
+ return;
+ }
+
+ if (_coreVar._currPlace < DOOR) {
+ displayStatusArrow();
+ if (!(_anyone) && !(_keyPressedEsc)) {
+ if ((_coreVar._currPlace < MOUNTAIN) && (_coreVar._currPlace != LANDING))
+ _crep = 133;
+ else
+ _crep = 997;
+ }
+
+ return;
+ }
+
+ if (_coreVar._currPlace == ROOM26) {
+ int rand = (getRandomNumber(0, 8)) - 4;
+ _soundManager.startSpeech(11, rand, 1);
+ int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
+ if (_roomDoorId != OWN_ROOM) {
+ if (pres != -500) {
+ if (rand > pres)
+ _crep = 190;
+ else {
+ setPresenceFlags(_roomDoorId);
+ getKnockAnswer();
+ }
+ } else
+ getKnockAnswer();
+ }
+
+ if (_roomDoorId == GREEN_ROOM2)
+ _crep = 190;
+ }
+}
+
+/**
+ * Engine function - Self / Put
+ * @remarks Originally called 'tposer'
+ */
+void MortevielleEngine::fctSelfPut() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_POSE));
+ if (_coreVar._selectedObjectId == 0)
+ _crep = 186;
+ else {
+ if (_caff > 99) {
+ _crep = 999;
+ putObject();
+ if (_crep != 192)
+ displayEmptyHand();
+ return;
+ }
+ displayStatusArrow();
+ if ((_anyone) || (_keyPressedEsc))
+ return;
+ setCoordinates(7);
+ _crep = 124;
+ if (_num != 0) {
+ int objId = getFirstObject();
+ if (objId == 0)
+ _crep = 997;
+ else {
+ int i;
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
+ _curSearchObjId = objId;
+ _crep = 999;
+ } else
+ _crep = 187;
+ }
+ } else {
+ setCoordinates(8);
+ if (_num != 0) {
+ _crep = 998;
+ if (_caff == PURPLE_ROOM) {
+ if (_coreVar._purpleRoomObjectId != 0)
+ _crep = 188;
+ else
+ _coreVar._purpleRoomObjectId = _coreVar._selectedObjectId;
+ }
+
+ if (_caff == ATTIC) {
+ if (_num == 1) {
+ if (_coreVar._atticBallHoleObjectId != 0)
+ _crep = 188;
+ else {
+ _coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 7);
+ }
+ } else if (_coreVar._atticRodHoleObjectId != 0) {
+ _crep = 188;
+ } else {
+ _coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 6);
+ }
+ }
+
+ if (_caff == CRYPT) {
+ if (_coreVar._cryptObjectId != 0)
+ _crep = 188;
+ else
+ _coreVar._cryptObjectId = _coreVar._selectedObjectId;
+ }
+
+ if (_caff == WELL)
+ _crep = 185;
+ if ((_caff == CELLAR) || (_caff == SECRET_PASSAGE))
+ _crep = 124;
+ } else {
+ _crep = 124;
+ if (_caff == WELL) {
+ setCoordinates(5);
+ if (_num != 0)
+ _crep = 185;
+ }
+ }
+ }
+ if (_caff == INSIDE_WELL)
+ _crep = 185;
+ if ((_crep == 999) || (_crep == 185) || (_crep == 998)) {
+ if (_crep == 999)
+ putObject();
+ if (_crep != 192)
+ displayEmptyHand();
+ }
+ }
+}
+
+/**
+ * Engine function - Listen
+ * @remarks Originally called 'tecouter'
+ */
+void MortevielleEngine::fctListen() {
+ if (_coreVar._currPlace != ROOM26)
+ _crep = 101;
+ else {
+ if (_currBitIndex != 0)
+ ++_coreVar._faithScore;
+ int rand;
+ int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
+ if (_roomDoorId != OWN_ROOM) {
+ if (pres != -500) {
+ if (rand > pres)
+ _crep = 101;
+ else {
+ setPresenceFlags(_roomDoorId);
+ int day, hour, minute;
+ updateHour(day, hour, minute);
+ rand = getRandomNumber(1, 100);
+ if ((hour >= 0) && (hour < 8)) {
+ if (rand > 30)
+ _crep = 101;
+ else
+ _crep = 178;
+ } else if (rand > 70)
+ _crep = 101;
+ else
+ _crep = 178;
+ }
+ } else
+ _crep = 178;
+ }
+ }
+}
+
+/**
+ * Engine function - Eat
+ * @remarks Originally called 'tmanger'
+ */
+void MortevielleEngine::fctEat() {
+ if ((_coreVar._currPlace > LANDING) && (_coreVar._currPlace < ROOM26)) {
+ _crep = 148;
+ } else {
+ exitRoom();
+ _coreVar._currPlace = DINING_ROOM;
+ _caff = DINING_ROOM;
+ resetRoomVariables(_coreVar._currPlace);
+ _menu.setDestinationText(_coreVar._currPlace);
+
+ int day, hour, minute;
+ updateHour(day, hour, minute);
+ if ((hour == 12) || (hour == 13) || (hour == 19)) {
+ _coreVar._faithScore -= (_coreVar._faithScore / 7);
+ if (hour == 12) {
+ if (minute == 0)
+ hour = 4;
+ else
+ hour = 3;
+ }
+
+ if ((hour == 13) || (hour == 19)) {
+ if (minute == 0)
+ hour = 2;
+ else
+ hour = 1;
+ }
+
+ _currentHourCount += hour;
+ _crep = 135;
+ prepareRoom();
+ } else {
+ _crep = 134;
+ }
+ }
+}
+
+/**
+ * Engine function - Enter
+ * @remarks Originally called 'tentrer'
+ */
+void MortevielleEngine::fctEnter() {
+ if ((_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) {
+ gotoDiningRoom();
+ _menu.setDestinationText(_coreVar._currPlace);
+ } else if (_coreVar._currPlace == LANDING)
+ showMoveMenuAlert();
+ else if (_roomDoorId == OWN_ROOM)
+ _crep = 997;
+ else if ((_roomDoorId == JULIA_ROOM) && (_coreVar._selectedObjectId != 136)) {
+ _crep = 189;
+ _coreVar._availableQuestion[8] = '*';
+ } else {
+ int pres = 0;
+ if (!_blo)
+ 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);
+ displayAnimFrame(1, 1);
+ _soundManager.waitSpeech();
+
+ int charIndex = convertBitIndexToCharacterIndex(pres);
+ ++_coreVar._faithScore;
+ _coreVar._currPlace = LANDING;
+ _currMenu = MENU_DISCUSS;
+ _currAction = (_menu._discussMenu[charIndex]._menuId << 8) | _menu._discussMenu[charIndex]._actionId;
+ _syn = true;
+ if (_roomDoorId == JULIA_ROOM) {
+ _col = true;
+ _caff = 70;
+ drawPictureWithText();
+ handleDescriptionText(2, _caff);
+ } else
+ _col = false;
+ resetRoomVariables(_roomDoorId);
+ _roomDoorId = OWN_ROOM;
+ }
+ } else {
+ int randVal = (getRandomNumber(0, 10)) - 5;
+ _soundManager.startSpeech(7, randVal, 1);
+ displayAnimFrame(1, 1);
+ _soundManager.waitSpeech();
+
+ _coreVar._currPlace = _roomDoorId;
+ prepareDisplayText();
+ resetRoomVariables(_coreVar._currPlace);
+ _menu.setDestinationText(_coreVar._currPlace);
+ _roomDoorId = OWN_ROOM;
+ _savedBitIndex = 0;
+ _currBitIndex = 0;
+ }
+ }
+}
+
+/**
+ * Engine function - Sleep
+ * @remarks Originally called 'tdormir'
+ */
+void MortevielleEngine::fctSleep() {
+ if ((_coreVar._currPlace > LANDING) && (_coreVar._currPlace < ROOM26)) {
+ _crep = 148;
+ return;
+ }
+ if (_coreVar._currPlace != OWN_ROOM) {
+ exitRoom();
+ _coreVar._currPlace = OWN_ROOM;
+ prepareDisplayText();
+ drawPictureWithText();
+ resetRoomVariables(_coreVar._currPlace);
+ _menu.setDestinationText(_coreVar._currPlace);
+ }
+ clearVerbBar();
+ clearDescriptionBar();
+ prepareScreenType2();
+ displayTextBlock(getEngineString(S_WANT_TO_WAKE_UP));
+ int day, hour, minute;
+ updateHour(day, hour, minute);
+
+ int answer;
+ do {
+ if (hour < 8) {
+ _coreVar._faithScore -= (_coreVar._faithScore / 20);
+ int z = (7 - hour) * 2;
+ if (minute == 30)
+ --z;
+ _currentHourCount += z;
+ hour = 7;
+ }
+ _currentHourCount += 2;
+ ++hour;
+ if (hour > 23)
+ hour = 0;
+ prepareRoom();
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
+ _anyone = false;
+ } while (answer != 1);
+ _crep = 998;
+ _num = 0;
+}
+
+/**
+ * Engine function - Force
+ * @remarks Originally called 'tdefoncer'
+ */
+void MortevielleEngine::fctForce() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_SMASH));
+ if (_caff < DOOR)
+ displayStatusArrow();
+
+ if ((!_anyone) && (!_keyPressedEsc)) {
+ if (_coreVar._currPlace != ROOM26)
+ _crep = 997;
+ else {
+ _crep = 143;
+ _coreVar._faithScore += 2;
+ }
+ }
+}
+
+/**
+ * Engine function - Leave
+ * @remarks Originally called 'tsortir'
+ */
+void MortevielleEngine::fctLeave() {
+ exitRoom();
+ _crep = 0;
+ if ((_coreVar._currPlace == MOUNTAIN) || (_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK) || (_coreVar._currPlace == WELL))
+ _crep = 997;
+ else {
+ int nextPlace = OWN_ROOM;
+
+ if ((_coreVar._currPlace < CRYPT) || (_coreVar._currPlace == ROOM26))
+ nextPlace = DINING_ROOM;
+ else if ((_coreVar._currPlace == DINING_ROOM) || (_coreVar._currPlace == CHAPEL))
+ nextPlace = MANOR_FRONT;
+ else if ((_coreVar._currPlace < DINING_ROOM) || (_coreVar._currPlace == ATTIC))
+ nextPlace = LANDING;
+ else if (_coreVar._currPlace == CRYPT) {
+ nextPlace = SECRET_PASSAGE;
+ _crep = 176;
+ } else if (_coreVar._currPlace == SECRET_PASSAGE)
+ nextPlace = checkLeaveSecretPassage();
+ else if (_coreVar._currPlace == INSIDE_WELL)
+ nextPlace = WELL;
+
+ if (_crep != 997)
+ _coreVar._currPlace = nextPlace;
+
+ _caff = nextPlace;
+ if (_crep == 0)
+ _crep = nextPlace;
+ resetRoomVariables(nextPlace);
+ _menu.setDestinationText(nextPlace);
+ }
+}
+
+/**
+ * Engine function - Wait
+ * @remarks Originally called 'tattendre'
+ */
+void MortevielleEngine::fctWait() {
+ _savedBitIndex = 0;
+ clearVerbBar();
+
+ int answer;
+ do {
+ ++_currentHourCount;
+ prepareRoom();
+ if (!_blo)
+ getPresence(_coreVar._currPlace);
+ if ((_currBitIndex != 0) && (_savedBitIndex == 0)) {
+ _crep = 998;
+ if ((_coreVar._currPlace == ATTIC) || (_coreVar._currPlace == CELLAR))
+ initCaveOrCellar();
+ if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
+ _anyone = true;
+ _savedBitIndex = _currBitIndex;
+ if (!_anyone)
+ prepareRoom();
+ return;
+ }
+ handleDescriptionText(2, 102);
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
+ } while (answer != 2);
+ _crep = 998;
+ if (!_anyone)
+ prepareRoom();
+}
+
+/**
+ * Engine function - Sound
+ * @remarks Originally called 'tsonder'
+ */
+void MortevielleEngine::fctSound() {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_PROBE2));
+ if (_caff < 27) {
+ displayStatusArrow();
+ if (!(_anyone) && (!_keyPressedEsc))
+ _crep = 145;
+ _num = 0;
+ }
+}
+
+/**
+ * Engine function - Discuss
+ * @remarks Originally called 'tparler'
+ */
+void MortevielleEngine::fctDiscuss() {
+ bool questionAsked[47];
+ int cy, cx;
+ int x, y;
+ Common::String lib[47];
+
+ int choice;
+ int displId;
+
+ endSearch();
+ if (_col)
+ displId = 128;
+ else {
+ cx = 0;
+ int oldMenu;
+ do {
+ ++cx;
+ oldMenu = (_menu._discussMenu[cx]._menuId << 8) | _menu._discussMenu[cx]._actionId;
+ } while (oldMenu != _currAction);
+ _caff = 69 + cx;
+ drawPictureWithText();
+ handleDescriptionText(2, _caff);
+ displId = _caff + 60;
+ }
+ testKey(false);
+ menuUp();
+ _mouse.hideMouse();
+ clearScreen();
+ drawDiscussionBox();
+ startDialog(displId);
+ clearScreen();
+ for (int ix = 1; ix <= 46; ++ix)
+ questionAsked[ix] = false;
+ for (int ix = 1; ix <= 45; ++ix) {
+ lib[ix] = getString(ix + kQuestionStringIndex);
+ for (int i = lib[ix].size(); i <= 40; ++i)
+ lib[ix] = lib[ix] + ' ';
+ }
+ lib[46] = lib[45];
+ lib[45] = ' ';
+ _mouse.showMouse();
+ do {
+ choice = 0;
+ int posX = 0;
+ int posY = 0;
+ for (int icm = 1; icm < 43; icm++) {
+ _screenSurface.putxy(posX, posY);
+ if (_coreVar._availableQuestion[icm] == '*') {
+ // If question already asked, write it in reverse video
+ if (questionAsked[icm])
+ displayQuestionText(lib[icm], 1);
+ else
+ displayQuestionText(lib[icm], 0);
+ }
+
+ if (icm == 23) {
+ posY = 0;
+ posX = 320;
+ } else
+ posY += 8;
+ }
+ _screenSurface.putxy(320, 176);
+ displayQuestionText(lib[46], 0);
+ char retKey = '\0';
+ bool click;
+ do {
+ bool dummyFl;
+ _mouse.moveMouse(dummyFl, retKey);
+ if (shouldQuit())
+ return;
+
+ _mouse.getMousePosition(x, y, click);
+ x *= (3 - kResolutionScaler);
+ if (x > 319)
+ cx = 41;
+ else
+ cx = 1;
+ cy = ((uint)y >> 3) + 1; // 0-199 => 1-25
+ if ((cy > 23) || ((cx == 41) && ((cy >= 20) && (cy <= 22)))) {
+ if (choice != 0) {
+ posY = ((choice - 1) % 23) << 3;
+ if (choice > 23)
+ posX = 320;
+ else
+ posX = 0;
+ _screenSurface.putxy(posX, posY);
+ if (questionAsked[choice])
+ displayQuestionText(lib[choice], 0);
+ else
+ displayQuestionText(lib[choice], 1);
+ questionAsked[choice] = !questionAsked[choice];
+ choice = 0;
+ }
+ } else {
+ int ix = cy;
+ if (cx == 41)
+ ix += 23;
+ if (ix != choice) {
+ if (choice != 0) {
+ posY = ((choice - 1) % 23) << 3;
+ if (choice > 23)
+ posX = 320;
+ else
+ posX = 0;
+ _screenSurface.putxy(posX, posY);
+ if (questionAsked[choice])
+ displayQuestionText(lib[choice], 0);
+ else
+ displayQuestionText(lib[choice], 1);
+ questionAsked[choice] = ! questionAsked[choice];
+ }
+ if ((ix == 46) || (_coreVar._availableQuestion[ix] == '*')) {
+ posY = ((ix - 1) % 23) << 3;
+ if (ix > 23)
+ posX = 320;
+ else
+ posX = 0;
+ _screenSurface.putxy(posX, posY);
+ if (questionAsked[ix])
+ displayQuestionText(lib[ix], 0);
+ else
+ displayQuestionText(lib[ix], 1);
+ questionAsked[ix] = ! questionAsked[ix];
+ choice = ix;
+ } else
+ choice = 0;
+ }
+ }
+ } while (!((retKey == '\15') || (((click != 0) || getMouseClick()) && (choice != 0))));
+ setMouseClick(false);
+
+ // If choice is not "End of Conversation"
+ if (choice != 46) {
+ int ix = choice - 1;
+ if (_col) {
+ _col = false;
+ _coreVar._currPlace = 15;
+ int maxRandVal;
+ if (_openObjCount > 0)
+ maxRandVal = 8;
+ else
+ maxRandVal = 4;
+ if (getRandomNumber(1, maxRandVal) == 2)
+ displId = 129;
+ else {
+ displId = 138;
+ _coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
+ }
+ } else if (_charAnswerCount[_caff - 69] < _charAnswerMax[_caff - 69]) {
+ displId = _tabdon[kArep + (ix << 3) + (_caff - 70)];
+ _coreVar._faithScore += _tabdon[kArcf + ix];
+ ++_charAnswerCount[_caff - 69];
+ } else {
+ _coreVar._faithScore += 3;
+ displId = 139;
+ }
+ _mouse.hideMouse();
+ clearScreen();
+ drawDiscussionBox();
+ startDialog(displId);
+ _mouse.showMouse();
+ if ((displId == 84) || (displId == 86)) {
+ _coreVar._pctHintFound[5] = '*';
+ _coreVar._availableQuestion[7] = '*';
+ }
+ if ((displId == 106) || (displId == 108) || (displId == 94)) {
+ for (int indx = 29; indx <= 31; ++indx)
+ _coreVar._availableQuestion[indx] = '*';
+ _coreVar._pctHintFound[7] = '*';
+ }
+ if (displId == 70) {
+ _coreVar._pctHintFound[8] = '*';
+ _coreVar._availableQuestion[32] = '*';
+ }
+ _mouse.hideMouse();
+ clearScreen();
+ _mouse.showMouse();
+ }
+ } while ((choice != 46) && (displId != 138));
+ if (_col) {
+ _coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
+ _mouse.hideMouse();
+ clearScreen();
+ drawDiscussionBox();
+ startDialog(138);
+ _mouse.showMouse();
+ _col = false;
+ _coreVar._currPlace = LANDING;
+ }
+ _controlMenu = 0;
+ _mouse.hideMouse();
+ clearScreen();
+ drawRightFrame();
+ _mouse.showMouse();
+ showPeoplePresent(_currBitIndex);
+ prepareRoom();
+ drawClock();
+ prepareDisplayText();
+ /* chech;*/
+ _menu.setDestinationText(_coreVar._currPlace);
+ clearVerbBar();
+}
+
+/**
+ * Engine function - Smell
+ * @remarks Originally called 'tsentir'
+ */
+void MortevielleEngine::fctSmell() {
+ _crep = 119;
+ if (_caff < ROOM26) {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_SMELL));
+ displayStatusArrow();
+ if (!(_anyone) && !(_keyPressedEsc))
+ if (_caff == CRYPT)
+ _crep = 153;
+ } else if (_caff == 123)
+ _crep = 110;
+ _num = 0;
+}
+
+/**
+ * Engine function - Scratch
+ * @remarks Originally called 'tgratter'
+ */
+void MortevielleEngine::fctScratch() {
+ _crep = 155;
+ if (_caff < 27) {
+ if (!_syn)
+ displayTextInVerbBar(getEngineString(S_SCRATCH));
+ displayStatusArrow();
+ }
+ _num = 0;
+}
+
+/**
+ * The game is over
+ * @remarks Originally called 'tmaj1'
+ */
+void MortevielleEngine::endGame() {
+ _quitGame = true;
+ displayNarrativePicture(13, 152);
+ displayEmptyHand();
+ clearUpperLeftPart();
+ clearDescriptionBar();
+ clearVerbBar();
+ handleDescriptionText(9, 1509);
+ testKey(false);
+ _mouse.hideMouse();
+ _caff = 70;
+ _text.taffich();
+ clearScreen();
+ drawDiscussionBox();
+ startDialog(141);
+ _mouse.showMouse();
+ clearUpperLeftPart();
+ handleDescriptionText(9, 1509);
+ handleDescriptionText(2, 142);
+ testKey(false);
+ _caff = 32;
+ drawPictureWithText();
+ handleDescriptionText(6, 34);
+ handleDescriptionText(2, 35);
+ startMusicOrSpeech(0);
+ testKey(false);
+ // A wait message was displayed.
+ // testKey (aka tkey1) was called before and after.
+ // This double call is useless, thus removed
+ resetVariables();
+}
+
+/**
+ * You lost!
+ * @remarks Originally called 'tencore'
+ */
+void MortevielleEngine::askRestart() {
+ clearDescriptionBar();
+ startMusicOrSpeech(0);
+ testKey(false);
+ displayEmptyHand();
+ resetVariables();
+ initGame();
+ _currHour = 10;
+ _currHalfHour = 0;
+ _currDay = 0;
+ _minute = 0;
+ _hour = 10;
+ _day = 0;
+ handleDescriptionText(2, 180);
+
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ _quitGame = (answer != 1);
+}
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/debugger.cpp b/engines/mortevielle/debugger.cpp
new file mode 100644
index 0000000000..4ef5151c81
--- /dev/null
+++ b/engines/mortevielle/debugger.cpp
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/debugger.h"
+
+namespace Mortevielle {
+
+Debugger::Debugger() : GUI::Debugger() {
+ 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));
+}
+
+bool Debugger::Cmd_showAllQuestions(int argc, const char **argv) {
+ for (int i = 1; i <= 10; ++i)
+ _vm->_coreVar._pctHintFound[i] = '*';
+
+ for (int i = 1; i <= 42; ++i)
+ _vm->_coreVar._availableQuestion[i] = '*';
+
+ for (int i = 0; i < 9; i++) {
+ _vm->_charAnswerCount[i] = 0;
+ _vm->_charAnswerMax[i] = 999;
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_resetParano(int argc, const char **argv) {
+ _vm->_coreVar._faithScore = 0;
+
+ 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
new file mode 100644
index 0000000000..9041d90110
--- /dev/null
+++ b/engines/mortevielle/debugger.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MORTEVIELLE_DEBUGGER_H
+#define MORTEVIELLE_DEBUGGER_H
+
+#include "common/scummsys.h"
+#include "gui/debugger.h"
+
+namespace Mortevielle {
+
+class MortevielleEngine;
+
+class Debugger : public GUI::Debugger {
+private:
+ MortevielleEngine *_vm;
+
+protected:
+ bool Cmd_showAllQuestions(int argc, const char **argv);
+ bool Cmd_resetParano(int argc, const char **argv);
+
+public:
+ Debugger();
+ virtual ~Debugger() {}
+ void setParent(MortevielleEngine *vm);
+};
+
+} // End of namespace Mortevielle
+
+#endif
diff --git a/engines/mortevielle/detection.cpp b/engines/mortevielle/detection.cpp
new file mode 100644
index 0000000000..ee9cb40c99
--- /dev/null
+++ b/engines/mortevielle/detection.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 "base/plugins.h"
+#include "engines/advancedDetector.h"
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/saveload.h"
+
+namespace Mortevielle {
+struct MortevielleGameDescription {
+ ADGameDescription desc;
+ Common::Language originalLanguage;
+ uint8 dataFeature;
+};
+
+uint32 MortevielleEngine::getGameFlags() const { return _gameDescription->desc.flags; }
+
+Common::Language MortevielleEngine::getLanguage() const { return _gameDescription->desc.language; }
+
+Common::Language MortevielleEngine::getOriginalLanguage() const { return _gameDescription->originalLanguage; }
+
+bool MortevielleEngine::useOriginalData() const { return _gameDescription->dataFeature == kUseOriginalData; }
+
+}
+
+static const PlainGameDescriptor MortevielleGame[] = {
+ {"mortevielle", "Mortville Manor"},
+ {0, 0}
+};
+
+#include "mortevielle/detection_tables.h"
+
+class MortevielleMetaEngine : public AdvancedMetaEngine {
+public:
+ MortevielleMetaEngine() : AdvancedMetaEngine(Mortevielle::MortevielleGameDescriptions, sizeof(Mortevielle::MortevielleGameDescription),
+ MortevielleGame) {
+ _md5Bytes = 512;
+ _singleid = "mortevielle";
+ // Use kADFlagUseExtraAsHint to distinguish between original and improved versions
+ // (i.e. use or not of the game data file).
+ _flags = kADFlagUseExtraAsHint;
+ }
+ virtual const char *getName() const {
+ return "Mortevielle";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Mortville Manor (C) 1987-89 Lankhor";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual int getMaximumSaveSlot() const;
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool MortevielleMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new Mortevielle::MortevielleEngine(syst, (const Mortevielle::MortevielleGameDescription *)desc);
+ }
+ return desc != 0;
+}
+
+bool MortevielleMetaEngine::hasFeature(MetaEngineFeature f) const {
+ switch (f) {
+ case kSupportsListSaves:
+ case kSupportsDeleteSave:
+ case kSupportsLoadingDuringStartup:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSavesSupportCreationDate:
+ return true;
+ default:
+ return false;
+ }
+}
+
+int MortevielleMetaEngine::getMaximumSaveSlot() const { return 99; }
+
+SaveStateList MortevielleMetaEngine::listSaves(const char *target) const {
+ return Mortevielle::SavegameManager::listSaves(target);
+}
+
+SaveStateDescriptor MortevielleMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Mortevielle::MortevielleEngine::generateSaveFilename(target, slot);
+ return Mortevielle::SavegameManager::querySaveMetaInfos(filename);
+}
+
+
+#if PLUGIN_ENABLED_DYNAMIC(MORTEVIELLE)
+ REGISTER_PLUGIN_DYNAMIC(MORTEVIELLE, PLUGIN_TYPE_ENGINE, MortevielleMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(MORTEVIELLE, PLUGIN_TYPE_ENGINE, MortevielleMetaEngine);
+#endif
diff --git a/engines/mortevielle/detection_tables.h b/engines/mortevielle/detection_tables.h
new file mode 100644
index 0000000000..8d0cd5630c
--- /dev/null
+++ b/engines/mortevielle/detection_tables.h
@@ -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.
+ *
+ */
+
+namespace Mortevielle {
+
+static const MortevielleGameDescription MortevielleGameDescriptions[] = {
+ // French
+ {
+ {
+ "mortevielle",
+ "",
+ {
+ {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::FR_FRA, kUseOriginalData
+ },
+ // German
+ {
+ {
+ "mortevielle",
+ "",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseOriginalData
+ },
+
+ // German, improved translation
+ {
+ {
+ "mortevielle",
+ "Improved Translation",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseEngineDataFile
+ },
+
+ // DOS English version doesn't exist. Technically, they are French or German versions,
+ // using English strings stored mort.dat
+
+ // English on top of French version
+ {
+ {
+ "mortevielle",
+ "",
+ {
+ {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::FR_FRA, kUseEngineDataFile
+ },
+
+ // English on top of German version
+ {
+ {
+ "mortevielle",
+ "",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseEngineDataFile
+ },
+
+ { AD_TABLE_END_MARKER , Common::EN_ANY, kUseEngineDataFile}
+};
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/dialogs.cpp b/engines/mortevielle/dialogs.cpp
new file mode 100644
index 0000000000..9a2ade60ab
--- /dev/null
+++ b/engines/mortevielle/dialogs.cpp
@@ -0,0 +1,472 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+
+#include "mortevielle/dialogs.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+
+#include "common/str.h"
+
+namespace Mortevielle {
+
+/**
+ * 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->_mouse.hideMouse();
+ while (_vm->keyPressed())
+ _vm->getChar();
+
+ _vm->setMouseClick(false);
+
+ int colNumb = 0;
+ int lignNumb = 0;
+ int caseNumb = 0;
+ Common::String alertStr = "";
+ Common::String caseStr;
+
+ decodeAlertDetails(msg, caseNumb, lignNumb, colNumb, alertStr, caseStr);
+
+ Common::Point curPos;
+ if (alertStr == "") {
+ drawAlertBox(10, 5, colNumb);
+ } else {
+ drawAlertBox(8, 7, colNumb);
+ int i = 0;
+ _vm->_screenSurface._textPos.y = 70;
+ do {
+ curPos.x = 320;
+ Common::String displayStr = "";
+ while ((alertStr[i + 1] != '\174') && (alertStr[i + 1] != '\135')) {
+ ++i;
+ 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);
+ ++i;
+ } while (alertStr[i] != ']');
+ }
+ int esp;
+ if (caseNumb == 1)
+ esp = colNumb - 40;
+ else
+ esp = (uint)(colNumb - caseNumb * 40) / 2;
+
+ int coldep = 320 - ((uint)colNumb / 2) + ((uint)esp / 2);
+ Common::String buttonStr[3];
+ setButtonText(caseStr, coldep, caseNumb, &buttonStr[0], esp);
+
+ int limit[3][3];
+ memset(&limit[0][0], 0, sizeof(int) * 3 * 3);
+
+ limit[1][1] = ((uint)(coldep) / 2) * kResolutionScaler;
+ limit[1][2] = limit[1][1] + 40;
+ if (caseNumb == 1) {
+ limit[2][1] = limit[2][2];
+ } else {
+ limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * kResolutionScaler;
+ limit[2][2] = (limit[2][1]) + 40;
+ }
+ _vm->_mouse.showMouse();
+ int id = 0;
+ bool dummyFl = false;
+ bool test3;
+ do {
+ char dummyKey = '\377';
+ _vm->_mouse.moveMouse(dummyFl, dummyKey);
+ if (_vm->shouldQuit())
+ return 0;
+
+ 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]);
+ bool test2 = test1;
+ if (caseNumb > 1)
+ test2 |= ((curPos.x > limit[2][1]) && (curPos.x < limit[2][2]));
+ if (test2) {
+ newaff = true;
+
+ int ix;
+ if (test1)
+ ix = 1;
+ else
+ ix = 2;
+ if (ix != id) {
+ _vm->_mouse.hideMouse();
+ if (id != 0) {
+ setPosition(id, coldep, esp);
+
+ Common::String tmpStr(" ");
+ tmpStr += buttonStr[id];
+ tmpStr += " ";
+ _vm->_screenSurface.drawString(tmpStr, 0);
+ }
+ setPosition(ix, coldep, esp);
+
+ Common::String tmp2 = " ";
+ tmp2 += buttonStr[ix];
+ tmp2 += " ";
+ _vm->_screenSurface.drawString(tmp2, 1);
+
+ id = ix;
+ _vm->_mouse.showMouse();
+ }
+ }
+ }
+ if ((id != 0) && !newaff) {
+ _vm->_mouse.hideMouse();
+ setPosition(id, coldep, esp);
+
+ Common::String tmp3(" ");
+ tmp3 += buttonStr[id];
+ tmp3 += " ";
+ _vm->_screenSurface.drawString(tmp3, 0);
+
+ id = 0;
+ _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();
+ if (!test3) {
+ id = 1;
+ setPosition(1, coldep, esp);
+ Common::String tmp4(" ");
+ tmp4 += buttonStr[1];
+ tmp4 += " ";
+ _vm->_screenSurface.drawString(tmp4, 1);
+ }
+ _vm->_mouse.showMouse();
+
+ /* Restore the background area */
+ _vm->_screenSurface.copyFrom(_vm->_backgroundSurface, 0, 0);
+
+ return id;
+}
+
+/**
+ * Alert function - Decode Alert Details
+ * @remarks Originally called 'decod'
+ */
+void DialogManager::decodeAlertDetails(Common::String inputStr, int &choiceNumb, int &lineNumb, int &col, Common::String &choiceStr, Common::String &choiceListStr) {
+ // The second character of the string contains the number of choices
+ choiceNumb = atoi(inputStr.c_str() + 1);
+
+ choiceStr = "";
+ col = 0;
+ lineNumb = 0;
+
+ // Originally set to 5, decreased to 4 because strings are 0 based, and not 1 based as in Pascal
+ int i = 4;
+ int k = 0;
+ bool empty = true;
+
+ for (; inputStr[i] != ']'; ++i) {
+ choiceStr += inputStr[i];
+ if ((inputStr[i] == '|') || (inputStr[i + 1] == ']')) {
+ if (k > col)
+ col = k;
+ k = 0;
+ ++lineNumb;
+ } else if (inputStr[i] != ' ')
+ empty = false;
+ ++k;
+ }
+
+ if (empty) {
+ choiceStr = "";
+ col = 20;
+ } else {
+ choiceStr += ']';
+ col += 6;
+ }
+
+ choiceListStr = Common::String(inputStr.c_str() + i);
+ col *= 6;
+}
+
+void DialogManager::setPosition(int ji, int coldep, int esp) {
+ _vm->_screenSurface.putxy(coldep + (40 + esp) * (ji - 1), 98);
+}
+
+/**
+ * Alert function - Draw Alert Box
+ * @remarks Originally called 'fait_boite'
+ */
+void DialogManager::drawAlertBox(int firstLine, int lineNum, int width) {
+ if (width > 640)
+ width = 640;
+ int x = 320 - ((uint)width / 2);
+ 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));
+}
+
+/**
+ * Alert function - Set Button Text
+ * @remarks Originally called 'fait_choix'
+ */
+void DialogManager::setButtonText(Common::String c, int coldep, int nbcase, Common::String *str, int esp) {
+ int i = 1;
+ int x = coldep;
+ for (int l = 1; l <= nbcase; ++l) {
+ str[l] = "";
+ do {
+ ++i;
+ char ch = c[i];
+ str[l] += ch;
+ } while (c[i + 1] != ']');
+ i += 2;
+
+ while (str[l].size() < 3)
+ str[l] += ' ';
+
+ _vm->_screenSurface.putxy(x, 98);
+
+ Common::String tmp(" ");
+ tmp += str[l];
+ tmp += " ";
+
+ _vm->_screenSurface.drawString(tmp, 0);
+ x += esp + 40;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+/**
+ * Questions asked before entering the hidden passage
+ */
+bool DialogManager::showKnowledgeCheck() {
+ const int textIndexArr[10] = {511, 516, 524, 531, 545, 552, 559, 563, 570, 576};
+ const int correctAnswerArr[10] = {4, 7, 1, 6, 4, 4, 2, 5, 3, 1 };
+
+ Hotspot coor[kMaxHotspots+1];
+
+ for (int i = 0; i <= kMaxHotspots; ++i) {
+ coor[i]._rect = Common::Rect();
+ coor[i]._enabled = false;
+ }
+
+ Common::String choiceArray[15];
+
+ int currChoice, prevChoice;
+ int correctCount = 0;
+
+ for (int indx = 0; indx < 10; ++indx) {
+ _vm->_mouse.hideMouse();
+ _vm->clearScreen();
+ _vm->_mouse.showMouse();
+ int dialogHeight = 23;
+ _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);
+
+ int firstOption;
+ int lastOption;
+
+ if (indx != 9) {
+ firstOption = textIndexArr[indx] + 1;
+ lastOption = textIndexArr[indx + 1] - 1;
+ } else {
+ firstOption = 503;
+ lastOption = 510;
+ }
+ int optionPosY = 35;
+ int maxLength = 0;
+
+ prevChoice = 1;
+ for (int j = firstOption; j <= lastOption; ++j, ++prevChoice) {
+ tmpStr = _vm->getString(j);
+ if ((int) tmpStr.size() > maxLength)
+ maxLength = tmpStr.size();
+ _vm->_text.displayStr(tmpStr, 100, optionPosY, 100, 1, 0);
+ choiceArray[prevChoice] = tmpStr;
+ optionPosY += 8;
+ }
+
+ for (int j = 1; j <= lastOption - firstOption + 1; ++j) {
+ coor[j]._rect = Common::Rect(45 * kResolutionScaler, 27 + j * 8, (maxLength * 3 + 55) * kResolutionScaler, 34 + j * 8);
+ coor[j]._enabled = true;
+
+ while ((int)choiceArray[j].size() < maxLength) {
+ choiceArray[j] += ' ';
+ }
+ }
+ coor[lastOption - firstOption + 2]._enabled = false;
+ int rep = 6;
+ _vm->_screenSurface.drawBox(80, 33, 40 + (maxLength * rep), (lastOption - firstOption) * 8 + 16, 15);
+ rep = 0;
+
+ prevChoice = 0;
+ warning("Expected answer: %d", correctAnswerArr[indx]);
+ do {
+ _vm->setMouseClick(false);
+ bool flag;
+ char key;
+ _vm->_mouse.moveMouse(flag, key);
+ if (_vm->shouldQuit())
+ return false;
+
+ currChoice = 1;
+ 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);
+ }
+ if (prevChoice != currChoice) {
+ tmpStr = choiceArray[currChoice] + '$';
+ _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);
+ prevChoice = 0;
+ }
+ } while (!((prevChoice != 0) && _vm->getMouseClick()));
+
+ if (prevChoice == correctAnswerArr[indx])
+ // Answer is correct
+ ++correctCount;
+ else {
+ // Skip questions that may give hints on previous wrong answer
+ if (indx == 4)
+ ++indx;
+ else if ((indx == 6) || (indx == 7))
+ indx = 9;
+ }
+ }
+
+ return (correctCount == 10);
+}
+
+/*------------------------------------------------------------------------*/
+
+/**
+ * Draw the F3/F8 dialog
+ */
+void DialogManager::drawF3F8() {
+ Common::String f3 = _vm->getEngineString(S_F3);
+ 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);
+
+ // Get the width of the written text strings
+ 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);
+}
+
+/**
+ * Alert function - Loop until F8 is pressed, update
+ * Graphical Device if modified
+ * @remarks Originally called 'diver'
+ */
+void DialogManager::checkForF8(int SpeechNum, bool drawFrame2Fl) {
+ _vm->testKeyboard();
+ do {
+ _vm->_soundManager.startSpeech(SpeechNum, 0, 0);
+ _vm->_key = waitForF3F8();
+ if (_vm->shouldQuit())
+ return;
+ } while (_vm->_key != 66); // keycode for F8
+}
+
+/**
+ * Alert function - Loop until F3 or F8 is pressed
+ * @remarks Originally called 'atf3f8'
+ */
+int DialogManager::waitForF3F8() {
+ int key;
+
+ do {
+ key = _vm->gettKeyPressed();
+ if (_vm->shouldQuit())
+ return key;
+ } while ((key != 61) && (key != 66));
+
+ return key;
+}
+
+/**
+ * Intro function - display intro screen
+ * @remarks Originally called 'aff50'
+ */
+void DialogManager::displayIntroScreen(bool drawFrame2Fl) {
+ _vm->_caff = 50;
+ _vm->_maff = 0;
+ _vm->_text.taffich();
+ _vm->draw(63, 12);
+ if (drawFrame2Fl)
+ displayIntroFrame2();
+ else
+ _vm->handleDescriptionText(2, kDialogStringIndex + 142);
+
+ // Draw the f3/f8 dialog
+ drawF3F8();
+}
+
+/**
+ * Intro function - display 2nd frame of intro
+ * @remarks Originally called 'ani50'
+ */
+void DialogManager::displayIntroFrame2() {
+ _vm->_crep = _vm->getAnimOffset(1, 1);
+ _vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
+ _vm->_crep = _vm->getAnimOffset(2, 1);
+ _vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
+ _vm->_largestClearScreen = false;
+ _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
new file mode 100644
index 0000000000..3f30851960
--- /dev/null
+++ b/engines/mortevielle/dialogs.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_ALERT_H
+#define MORTEVIELLE_ALERT_H
+
+#include "common/rect.h"
+#include "common/str.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+static const int NUM_LINES = 7;
+const int kMaxHotspots = 14;
+
+struct Hotspot {
+ Common::Rect _rect;
+ bool _enabled;
+};
+
+class DialogManager {
+private:
+ MortevielleEngine *_vm;
+
+ void decodeAlertDetails(Common::String inputStr, int &choiceNumb, int &lineNumb, int &col, Common::String &choiceStr, Common::String &choiceListStr);
+ void setPosition(int ji, int coldep, int esp);
+ 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);
+ int show(const Common::String &msg);
+ void drawF3F8();
+ void checkForF8(int SpeechNum, bool drawFrame2Fl);
+ int waitForF3F8();
+ void displayIntroScreen(bool drawFrame2Fl);
+ void displayIntroFrame2();
+ bool showKnowledgeCheck();
+};
+
+} // End of namespace Mortevielle
+#endif
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
new file mode 100644
index 0000000000..daf7926438
--- /dev/null
+++ b/engines/mortevielle/graphics.cpp
@@ -0,0 +1,1167 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/graphics.h"
+#include "mortevielle/mouse.h"
+
+#include "common/endian.h"
+#include "common/system.h"
+#include "graphics/palette.h"
+
+namespace Mortevielle {
+
+/*-------------------------------------------------------------------------*
+ * Palette Manager
+ *
+ *-------------------------------------------------------------------------*/
+
+/**
+ * Set palette entries from the 64 color available EGA palette
+ */
+void PaletteManager::setPalette(const int *palette, uint idx, uint size) {
+ assert((idx + size) <= 16);
+
+ // Build up the EGA palette
+ byte egaPalette[64 * 3];
+
+ byte *p = &egaPalette[0];
+ for (int i = 0; i < 64; ++i) {
+ *p++ = (i >> 2 & 1) * 0xaa + (i >> 5 & 1) * 0x55;
+ *p++ = (i >> 1 & 1) * 0xaa + (i >> 4 & 1) * 0x55;
+ *p++ = (i & 1) * 0xaa + (i >> 3 & 1) * 0x55;
+ }
+
+ // Loop through setting palette colors based on the passed indexes
+ for (; size > 0; --size, ++idx) {
+ int palIndex = palette[idx];
+ assert(palIndex < 64);
+
+ const byte *pRgb = (const byte *)&egaPalette[palIndex * 3];
+ g_system->getPaletteManager()->setPalette(pRgb, idx, 1);
+ }
+}
+
+/**
+ * Set the default EGA palette
+ */
+void PaletteManager::setDefaultPalette() {
+ const int defaultPalette[16] = { 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63 };
+ setPalette(defaultPalette, 0, 16);
+}
+
+/*-------------------------------------------------------------------------*
+ * Image decoding
+ *
+ * The code in this section is responsible for decoding image resources.
+ * Images are broken down into rectangular sections, which can use one
+ * of 18 different encoding methods.
+ *-------------------------------------------------------------------------*/
+
+#define INCR_XSIZE { if (_xSize & 1) ++_xSize; }
+#define DEFAULT_WIDTH (SCREEN_WIDTH / 2)
+#define BUFFER_SIZE 40000
+
+void GfxSurface::decode(const byte *pSrc) {
+ w = h = 0;
+ // If no transparency, use invalid (for EGA) palette index of 16. Otherwise get index to use
+ _transparency = (*pSrc == 0) ? 16 : *(pSrc + 2);
+ bool offsetFlag = *pSrc++ == 0;
+ int entryCount = *pSrc++;
+ pSrc += 2;
+
+ if (offsetFlag)
+ pSrc += 30;
+
+ // First run through the data to calculate starting offsets
+ const byte *p = pSrc;
+ _offset.x = _offset.y = 999;
+
+ assert(entryCount > 0);
+ for (int idx = 0; idx < entryCount; ++idx) {
+ _xp = READ_BE_UINT16(p + 4);
+ if (_xp < _offset.x)
+ _offset.x = _xp;
+
+ _yp = READ_BE_UINT16(p + 6);
+ if (_yp < _offset.y)
+ _offset.y = _yp;
+
+ // Move to next entry
+ int size = READ_BE_UINT16(p) + READ_BE_UINT16(p + 2);
+ if ((size % 2) == 1)
+ ++size;
+
+ p += size + 14;
+ }
+
+ // Temporary output buffer
+ byte *outputBuffer = (byte *)malloc(sizeof(byte) * 65536);
+ memset(outputBuffer, _transparency, 65536);
+
+ byte *pDest = &outputBuffer[0];
+ const byte *pSrcStart = pSrc;
+ const byte *pLookup = NULL;
+
+ byte *lookupTable = (byte *)malloc(sizeof(byte) * BUFFER_SIZE);
+ byte *srcBuffer = (byte *)malloc(sizeof(byte) * BUFFER_SIZE);
+
+ // Main processing loop
+ for (int entryIndex = 0; entryIndex < entryCount; ++entryIndex) {
+ int lookupBytes = READ_BE_UINT16(pSrc);
+ int srcSize = READ_BE_UINT16(pSrc + 2);
+ _xp = READ_BE_UINT16(pSrc + 4) - _offset.x;
+ _yp = READ_BE_UINT16(pSrc + 6) - _offset.y;
+ assert((_xp >= 0) && (_yp >= 0) && (_xp < SCREEN_WIDTH) && (_yp < SCREEN_ORIG_HEIGHT));
+ pSrc += 8;
+
+ int decomCode = READ_BE_UINT16(pSrc);
+ _xSize = READ_BE_UINT16(pSrc + 2) + 1;
+ _ySize = READ_BE_UINT16(pSrc + 4) + 1;
+ majTtxTty();
+
+ pSrc += 6;
+ pDest = &outputBuffer[0];
+
+ _lookupIndex = 0;
+ _nibbleFlag = false;
+
+ int decomIndex = 0;
+ if (decomCode >> 8) {
+ // Build up reference table
+ int tableOffset = 0;
+
+ if (decomCode & 1) {
+ // Handle decompression of the pattern lookup table
+ do {
+ int outerCount = desanalyse(pSrc);
+ int innerCount = desanalyse(pSrc);
+
+ const byte *pSrcSaved = pSrc;
+ bool savedNibbleFlag = _nibbleFlag;
+ int savedLookupIndex = _lookupIndex;
+
+ do {
+ pSrc = pSrcSaved;
+ _nibbleFlag = savedNibbleFlag;
+ _lookupIndex = savedLookupIndex;
+
+ for (int idx = 0; idx < innerCount; ++idx, ++tableOffset) {
+ assert(tableOffset < BUFFER_SIZE);
+ lookupTable[tableOffset] = nextNibble(pSrc);
+ }
+ } while (--outerCount > 0);
+ } while (_lookupIndex < (lookupBytes - 1));
+
+ } else {
+ assert(lookupBytes < BUFFER_SIZE);
+ for (int idx = 0; idx < (lookupBytes * 2); ++idx)
+ lookupTable[idx] = nextNibble(pSrc);
+ }
+
+ if (_nibbleFlag) {
+ ++pSrc;
+ _nibbleFlag = false;
+ }
+ if ((lookupBytes + srcSize) & 1)
+ ++pSrc;
+
+ tableOffset = 0;
+ _lookupIndex = 0;
+
+ if (decomCode & 2) {
+ // Handle decompression of the temporary source buffer
+ do {
+ int outerCount = desanalyse(pSrc);
+ int innerCount = desanalyse(pSrc);
+ _lookupIndex += innerCount;
+
+ if (_nibbleFlag) {
+ ++pSrc;
+ ++_lookupIndex;
+ _nibbleFlag = false;
+ }
+
+ const byte *pStart = pSrc;
+ do {
+ pSrc = pStart;
+ for (int idx = 0; idx < innerCount; ++idx) {
+ assert(tableOffset < BUFFER_SIZE);
+ srcBuffer[tableOffset++] = *pSrc++;
+ }
+ } while (--outerCount > 0);
+ } while (_lookupIndex < (srcSize - 1));
+ } else {
+ assert(srcSize < BUFFER_SIZE);
+ for (int idx = 0; idx < srcSize; ++idx)
+ srcBuffer[idx] = *pSrc++;
+ }
+
+ if (_nibbleFlag)
+ ++pSrc;
+
+ // Switch over to using the decompressed source and lookup buffers
+ pSrcStart = pSrc;
+ pDest = &outputBuffer[_yp * DEFAULT_WIDTH + _xp];
+ pSrc = &srcBuffer[0];
+ pLookup = &lookupTable[0] - 1;
+
+ _lookupValue = _lookupIndex = 0;
+ _nibbleFlag = false;
+ decomIndex = decomCode >> 8;
+ }
+
+ // Main decompression switch
+ switch (decomIndex) {
+ case 0:
+ // Draw rect at pos
+ pDest = &outputBuffer[_yp * DEFAULT_WIDTH + _xp];
+ pSrcStart = pSrc;
+ INCR_XSIZE;
+
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest += DEFAULT_WIDTH) {
+ byte *pDestLine = pDest;
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *pDestLine++ = nextNibble(pSrc);
+ }
+ }
+
+ pSrcStart += lookupBytes + ((lookupBytes & 1) ? 1 : 0);
+ break;
+
+ case 1:
+ // Draw rect using horizontal lines alternating left to right, then right to left
+ INCR_XSIZE;
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr) {
+ if ((yCtr % 2) == 0) {
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *pDest++ = nextByte(pSrc, pLookup);
+ }
+ } else {
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *--pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ pDest += DEFAULT_WIDTH;
+ }
+ break;
+
+ case 2:
+ // Draw rect alternating top to bottom, bottom to top
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ if ((xCtr % 2) == 0) {
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest += DEFAULT_WIDTH) {
+ *pDest = nextByte(pSrc, pLookup);
+ }
+ } else {
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr) {
+ pDest -= DEFAULT_WIDTH;
+ *pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ ++pDest;
+ }
+ break;
+
+ case 3:
+ // Draw horizontal area?
+ _thickness = 2;
+ horizontal(pSrc, pDest, pLookup);
+ break;
+
+ case 4:
+ // Draw vertical area?
+ _thickness = 2;
+ vertical(pSrc, pDest, pLookup);
+ break;
+
+ case 5:
+ _thickness = 3;
+ horizontal(pSrc, pDest, pLookup);
+ break;
+
+ case 6:
+ _thickness = 4;
+ vertical(pSrc, pDest, pLookup);
+ break;
+
+ case 7:
+ // Draw rect using horizontal lines left to right
+ INCR_XSIZE;
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest += DEFAULT_WIDTH) {
+ byte *pDestLine = pDest;
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr)
+ *pDestLine++ = nextByte(pSrc, pLookup);
+ }
+ break;
+
+ case 8:
+ // Draw box
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr, ++pDest) {
+ byte *pDestLine = pDest;
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDestLine += DEFAULT_WIDTH)
+ *pDestLine = nextByte(pSrc, pLookup);
+ }
+ break;
+
+ case 9:
+ _thickness = 4;
+ horizontal(pSrc, pDest, pLookup);
+ break;
+
+ case 10:
+ _thickness = 6;
+ horizontal(pSrc, pDest, pLookup);
+ break;
+
+ case 11:
+ decom11(pSrc, pDest, pLookup);
+ break;
+
+ case 12:
+ INCR_XSIZE;
+ _thickness = _xInc = 1;
+ _yInc = DEFAULT_WIDTH;
+ _yEnd = _ySize;
+ _xEnd = _xSize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 13:
+ INCR_XSIZE;
+ _thickness = _xSize;
+ _yInc = 1;
+ _yEnd = _xSize;
+ _xInc = DEFAULT_WIDTH;
+ _xEnd = _ySize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 14:
+ _thickness = _yInc = 1;
+ _yEnd = _xSize;
+ _xInc = DEFAULT_WIDTH;
+ _xEnd = _ySize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 15:
+ INCR_XSIZE;
+ _thickness = 2;
+ _yInc = DEFAULT_WIDTH;
+ _yEnd = _ySize;
+ _xInc = 1;
+ _xEnd = _xSize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 16:
+ _thickness = 3;
+ _yInc = 1;
+ _yEnd = _xSize;
+ _xInc = DEFAULT_WIDTH;
+ _xEnd = _ySize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 17:
+ INCR_XSIZE;
+ _thickness = 3;
+ _yInc = DEFAULT_WIDTH;
+ _yEnd = _ySize;
+ _xInc = 1;
+ _xEnd = _xSize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ case 18:
+ INCR_XSIZE;
+ _thickness = 5;
+ _yInc = DEFAULT_WIDTH;
+ _yEnd = _ySize;
+ _xInc = 1;
+ _xEnd = _xSize;
+ diag(pSrc, pDest, pLookup);
+ break;
+
+ default:
+ error("Unknown decompression block type %d", decomIndex);
+ }
+
+ pSrc = pSrcStart;
+ debugC(2, kMortevielleGraphics, "Decoding image block %d position %d,%d size %d,%d method %d",
+ entryIndex + 1, _xp, _yp, w, h, decomIndex);
+ }
+
+ // At this point, the outputBuffer has the data for the image. Initialize the surface
+ // with the calculated size, and copy the lines to the surface
+ create(w, h, Graphics::PixelFormat::createFormatCLUT8());
+
+ for (int yCtr = 0; yCtr < h; ++yCtr) {
+ const byte *copySrc = &outputBuffer[yCtr * DEFAULT_WIDTH];
+ byte *copyDest = (byte *)getBasePtr(0, yCtr);
+
+ Common::copy(copySrc, copySrc + w, copyDest);
+ }
+
+ ::free(outputBuffer);
+ ::free(lookupTable);
+ ::free(srcBuffer);
+}
+
+void GfxSurface::majTtxTty() {
+ if (!_yp)
+ w += _xSize;
+
+ if (!_xp)
+ h += _ySize;
+}
+
+/**
+ * Decompression Function - get next nibble
+ * @remarks Originally called 'suiv'
+ */
+byte GfxSurface::nextNibble(const byte *&pSrc) {
+ int v = *pSrc;
+ if (_nibbleFlag) {
+ ++pSrc;
+ ++_lookupIndex;
+ _nibbleFlag = false;
+ return v & 0xf;
+ } else {
+ _nibbleFlag = !_nibbleFlag;
+ return v >> 4;
+ }
+}
+
+/**
+ * Decompression Function - get next byte
+ * @remarks Originally called 'csuiv'
+ */
+byte GfxSurface::nextByte(const byte *&pSrc, const byte *&pLookup) {
+ assert(pLookup);
+
+ while (!_lookupValue) {
+ int v;
+ do {
+ v = nextNibble(pSrc) & 0xff;
+ _lookupValue += v;
+ } while (v == 0xf);
+ ++pLookup;
+ }
+
+ --_lookupValue;
+ return *pLookup;
+}
+
+int GfxSurface::desanalyse(const byte *&pSrc) {
+ int total = 0;
+ int v = nextNibble(pSrc);
+ if (v == 0xf) {
+ int v2;
+ do {
+ v2 = nextNibble(pSrc);
+ total += v2;
+ } while (v2 == 0xf);
+
+ total *= 15;
+ v = nextNibble(pSrc);
+ }
+
+ total += v;
+ return total;
+}
+
+void GfxSurface::horizontal(const byte *&pSrc, byte *&pDest, const byte *&pLookup) {
+ INCR_XSIZE;
+ byte *pDestEnd = pDest + (_ySize - 1) * DEFAULT_WIDTH + _xSize;
+
+ for (;;) {
+ // If position is past end point, then skip this line
+ if (((_thickness - 1) * DEFAULT_WIDTH) + pDest >= pDestEnd) {
+ if (--_thickness == 0)
+ break;
+ continue;
+ }
+
+ bool continueFlag = false;
+ do {
+ for (int xIndex = 0; xIndex < _xSize; ++xIndex) {
+ if ((xIndex % 2) == 0) {
+ if (xIndex != 0)
+ ++pDest;
+
+ // Write out vertical slice top to bottom
+ for (int yIndex = 0; yIndex < _thickness; ++yIndex, pDest += DEFAULT_WIDTH)
+ *pDest = nextByte(pSrc, pLookup);
+
+ ++pDest;
+ } else {
+ // Write out vertical slice bottom to top
+ for (int yIndex = 0; yIndex < _thickness; ++yIndex) {
+ pDest -= DEFAULT_WIDTH;
+ *pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ }
+
+ if ((_xSize % 2) == 0) {
+ int blockSize = _thickness * DEFAULT_WIDTH;
+ pDest += blockSize;
+ blockSize -= DEFAULT_WIDTH;
+
+ if (pDestEnd < (pDest + blockSize)) {
+ do {
+ if (--_thickness == 0)
+ return;
+ } while ((pDest + (_thickness - 1) * DEFAULT_WIDTH) >= pDestEnd);
+ }
+ } else {
+ while ((pDest + (_thickness - 1) * DEFAULT_WIDTH) >= pDestEnd) {
+ if (--_thickness == 0)
+ return;
+ }
+ }
+
+ for (int xIndex = 0; xIndex < _xSize; ++xIndex, --pDest) {
+ if ((xIndex % 2) == 0) {
+ // Write out vertical slice top to bottom
+ for (int yIndex = 0; yIndex < _thickness; ++yIndex, pDest += DEFAULT_WIDTH)
+ *pDest = nextByte(pSrc, pLookup);
+ } else {
+ // Write out vertical slice top to bottom
+ for (int yIndex = 0; yIndex < _thickness; ++yIndex) {
+ pDest -= DEFAULT_WIDTH;
+ *pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ }
+
+ if ((_xSize % 2) == 1) {
+ ++pDest;
+
+ if ((pDest + (_thickness - 1) * DEFAULT_WIDTH) < pDestEnd) {
+ continueFlag = true;
+ break;
+ }
+ } else {
+ pDest += _thickness * DEFAULT_WIDTH + 1;
+ continueFlag = true;
+ break;
+ }
+
+ ++pDest;
+ } while (((_thickness - 1) * DEFAULT_WIDTH + pDest) < pDestEnd);
+
+ if (continueFlag)
+ continue;
+
+ // Move to next line
+ if (--_thickness == 0)
+ break;
+ }
+}
+
+void GfxSurface::vertical(const byte *&pSrc, byte *&pDest, const byte *&pLookup) {
+ int drawIndex = 0;
+
+ for (;;) {
+ // Reduce thickness as necessary
+ while ((drawIndex + _thickness) > _xSize) {
+ if (--_thickness == 0)
+ return;
+ }
+
+ // Loop
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr) {
+ if ((yCtr % 2) == 0) {
+ if (yCtr > 0)
+ pDest += DEFAULT_WIDTH;
+
+ drawIndex += _thickness;
+ for (int xCtr = 0; xCtr < _thickness; ++xCtr)
+ *pDest++ = nextByte(pSrc, pLookup);
+ } else {
+ pDest += DEFAULT_WIDTH;
+ drawIndex -= _thickness;
+ for (int xCtr = 0; xCtr < _thickness; ++xCtr)
+ *--pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ if ((_ySize % 2) == 0) {
+ pDest += _thickness;
+ drawIndex += _thickness;
+ }
+
+ while (_xSize < (drawIndex + _thickness)) {
+ if (--_thickness == 0)
+ return;
+ }
+
+ // Loop
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr) {
+ if ((yCtr % 2) == 0) {
+ if (yCtr > 0)
+ pDest -= DEFAULT_WIDTH;
+
+ drawIndex += _thickness;
+
+ for (int xCtr = 0; xCtr < _thickness; ++xCtr)
+ *pDest++ = nextByte(pSrc, pLookup);
+ } else {
+ pDest -= DEFAULT_WIDTH;
+ drawIndex -= _thickness;
+
+ for (int xCtr = 0; xCtr < _thickness; ++xCtr)
+ *--pDest = nextByte(pSrc, pLookup);
+ }
+ }
+ if ((_ySize % 2) == 0) {
+ pDest += _thickness;
+ drawIndex += _thickness;
+ }
+ }
+}
+
+void GfxSurface::decom11(const byte *&pSrc, byte *&pDest, const byte *&pLookup) {
+ int yPos = 0, drawIndex = 0;
+ _yInc = DEFAULT_WIDTH;
+ _xInc = -1;
+ --_xSize;
+ --_ySize;
+
+ int areaNum = 0;
+ while (areaNum != -1) {
+ switch (areaNum) {
+ case 0:
+ *pDest = nextByte(pSrc, pLookup);
+ areaNum = 1;
+ break;
+
+ case 1:
+ nextDecompPtr(pDest);
+
+ if (!drawIndex) {
+ negXInc();
+ negYInc();
+
+ if (yPos == _ySize) {
+ nextDecompPtr(pDest);
+ ++drawIndex;
+ } else {
+ ++yPos;
+ }
+
+ *++pDest = nextByte(pSrc, pLookup);
+ areaNum = 2;
+ } else if (yPos != _ySize) {
+ ++yPos;
+ --drawIndex;
+ areaNum = 0;
+ } else {
+ negXInc();
+ negYInc();
+ nextDecompPtr(pDest);
+ ++drawIndex;
+
+ *++pDest = nextByte(pSrc, pLookup);
+
+ if (drawIndex == _xSize) {
+ areaNum = -1;
+ } else {
+ areaNum = 2;
+ }
+ }
+ break;
+
+ case 2:
+ nextDecompPtr(pDest);
+
+ if (!yPos) {
+ negXInc();
+ negYInc();
+
+ if (drawIndex == _xSize) {
+ nextDecompPtr(pDest);
+ ++yPos;
+ } else {
+ ++drawIndex;
+ }
+
+ pDest += DEFAULT_WIDTH;
+ areaNum = 0;
+ } else if (drawIndex != _xSize) {
+ ++drawIndex;
+ --yPos;
+
+ *pDest = nextByte(pSrc, pLookup);
+ areaNum = 2;
+ } else {
+ pDest += DEFAULT_WIDTH;
+ ++yPos;
+ negXInc();
+ negYInc();
+ nextDecompPtr(pDest);
+
+ *pDest = nextByte(pSrc, pLookup);
+
+ if (yPos == _ySize)
+ areaNum = -1;
+ else
+ areaNum = 1;
+ }
+ break;
+ }
+ }
+}
+
+void GfxSurface::diag(const byte *&pSrc, byte *&pDest, const byte *&pLookup) {
+ int diagIndex = 0, drawIndex = 0;
+ --_xEnd;
+
+ while (!TFP(diagIndex)) {
+ for (;;) {
+ negXInc();
+ for (int idx = 0; idx <= _thickness; ++idx) {
+ *pDest = nextByte(pSrc, pLookup);
+ negXInc();
+ nextDecompPtr(pDest);
+ }
+
+ negYInc();
+ pDest += _yInc;
+
+ for (int idx = 0; idx <= _thickness; ++idx) {
+ *pDest = nextByte(pSrc, pLookup);
+ negXInc();
+ nextDecompPtr(pDest);
+ }
+
+ negXInc();
+ negYInc();
+ nextDecompPtr(pDest);
+
+ ++drawIndex;
+ if (_xEnd < (drawIndex + 1)) {
+ TF1(pDest, diagIndex);
+ break;
+ }
+
+ pDest += _xInc;
+ ++drawIndex;
+ if (_xEnd < (drawIndex + 1)) {
+ TF2(pSrc, pDest, pLookup, diagIndex);
+ break;
+ }
+ }
+
+ if (TFP(diagIndex))
+ break;
+
+ for (;;) {
+ for (int idx = 0; idx <= _thickness; ++idx) {
+ *pDest = nextByte(pSrc, pLookup);
+ negXInc();
+ nextDecompPtr(pDest);
+ }
+
+ negYInc();
+ pDest += _yInc;
+
+ for (int idx = 0; idx <= _thickness; ++idx) {
+ *pDest = nextByte(pSrc, pLookup);
+ negXInc();
+ nextDecompPtr(pDest);
+ }
+
+ negXInc();
+ negYInc();
+ nextDecompPtr(pDest);
+
+ if (--drawIndex == 0) {
+ TF1(pDest, diagIndex);
+ negXInc();
+ break;
+ } else {
+ pDest += _xInc;
+
+ if (--drawIndex == 0) {
+ TF2(pSrc, pDest, pLookup, diagIndex);
+ negXInc();
+ break;
+ }
+ }
+
+ negXInc();
+ }
+ }
+}
+
+/**
+ * Decompression Function - Move pDest ptr to next value to uncompress
+ * @remarks Originally called 'increments'
+ */
+void GfxSurface::nextDecompPtr(byte *&pDest) {
+ pDest += _xInc + _yInc;
+}
+
+/**
+ * Decompression Function - set xInc to its opposite value
+ * @remarks Originally called 'NIH'
+ */
+void GfxSurface::negXInc() {
+ _xInc = -_xInc;
+}
+
+/**
+ * Decompression Function - set yInc to its opposite value
+ * @remarks Originally called 'NIV'
+ */
+void GfxSurface::negYInc() {
+ _yInc = -_yInc;
+}
+
+bool GfxSurface::TFP(int v) {
+ int diff = _yEnd - v;
+ if (!diff)
+ // Time to finish loop in outer method
+ return true;
+
+ if (diff < (_thickness + 1))
+ _thickness = diff - 1;
+
+ return false;
+}
+
+void GfxSurface::TF1(byte *&pDest, int &v) {
+ v += _thickness + 1;
+ pDest += (_thickness + 1) * _yInc;
+}
+
+void GfxSurface::TF2(const byte *&pSrc, byte *&pDest, const byte *&pLookup, int &v) {
+ v += _thickness + 1;
+
+ for (int idx = 0; idx <= _thickness; ++idx) {
+ *pDest = nextByte(pSrc, pLookup);
+ pDest += _yInc;
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+GfxSurface::~GfxSurface() {
+ free();
+}
+
+/*-------------------------------------------------------------------------*
+ * Screen surface
+ *-------------------------------------------------------------------------*/
+
+/**
+ * Called to populate the font data from the passed file
+ */
+void ScreenSurface::readFontData(Common::File &f, int dataSize) {
+ assert(dataSize == (FONT_NUM_CHARS * FONT_HEIGHT));
+ f.read(_fontData, FONT_NUM_CHARS * FONT_HEIGHT);
+}
+
+/**
+ * Returns a graphics surface representing a subset of the screen. The affected area
+ * is also marked as dirty
+ */
+Graphics::Surface ScreenSurface::lockArea(const Common::Rect &bounds) {
+ _dirtyRects.push_back(bounds);
+
+ Graphics::Surface s;
+ s.init(bounds.width(), bounds.height(), pitch, getBasePtr(bounds.left, bounds.top), format);
+ return s;
+}
+
+/**
+ * Updates the affected areas of the surface to the underlying physical screen
+ */
+void ScreenSurface::updateScreen() {
+ // Iterate through copying dirty areas to the screen
+ for (Common::List<Common::Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) {
+ Common::Rect r = *i;
+ g_system->copyRectToScreen((const byte *)getBasePtr(r.left, r.top), pitch,
+ r.left, r.top, r.width(), r.height());
+ }
+ _dirtyRects.clear();
+
+ // Update the screen
+ g_system->updateScreen();
+}
+
+/**
+ * Draws a decoded picture on the screen
+ * @remarks - Because the ScummVM surface is using a double height 640x400 surface to
+ * simulate the original 640x400 surface, all Y values have to be doubled.
+ * - Image resources are stored at 320x200, so when drawn onto the screen a single pixel
+ * from the source image is drawn using the two pixels at the given index in the palette map
+ * - Because the original game supported 320 width resolutions, the X coordinate
+ * also needs to be doubled for EGA mode
+ */
+void ScreenSurface::drawPicture(GfxSurface &surface, int x, int y) {
+ // Adjust the draw position by the draw offset
+ x += surface._offset.x;
+ y += surface._offset.y;
+
+ // Lock the affected area of the surface to write to
+ Graphics::Surface destSurface = lockArea(Common::Rect(x * 2, y * 2,
+ (x + surface.w) * 2, (y + surface.h) * 2));
+
+ // Get a lookup for the palette mapping
+ const byte *paletteMap = &_vm->_curPict[2];
+
+ // Loop through writing
+ for (int yp = 0; yp < surface.h; ++yp) {
+ if (((y + yp) < 0) || ((y + yp) >= 200))
+ continue;
+
+ const byte *pSrc = (const byte *)surface.getBasePtr(0, yp);
+ byte *pDest = (byte *)destSurface.getBasePtr(0, yp * 2);
+
+ for (int xp = 0; xp < surface.w; ++xp, ++pSrc) {
+ if (*pSrc == surface._transparency) {
+ // Transparent point, so skip pixels
+ pDest += 2;
+ } else {
+ // Draw the pixel using the specified index in the palette map
+ *pDest = paletteMap[*pSrc * 2];
+ *(pDest + SCREEN_WIDTH) = paletteMap[*pSrc * 2];
+ ++pDest;
+
+ // Use the secondary mapping value to draw the secondary column pixel
+ *pDest = paletteMap[*pSrc * 2 + 1];
+ *(pDest + SCREEN_WIDTH) = paletteMap[*pSrc * 2 + 1];
+ ++pDest;
+ }
+ }
+ }
+}
+
+/**
+ * Copys a given surface to the given position
+ */
+void ScreenSurface::copyFrom(Graphics::Surface &src, int x, int y) {
+ lockArea(Common::Rect(x, y, x + src.w, y + src.h));
+
+ // Loop through writing
+ for (int yp = 0; yp < src.h; ++yp) {
+ if (((y + yp) < 0) || ((y + yp) >= SCREEN_HEIGHT))
+ continue;
+
+ const byte *pSrc = (const byte *)src.getBasePtr(0, yp);
+ byte *pDest = (byte *)getBasePtr(0, yp);
+ Common::copy(pSrc, pSrc + src.w, pDest);
+ }
+}
+
+/**
+ * Draws a character at the specified co-ordinates
+ * @remarks Because the ScummVM surface is using a double height 640x400 surface to
+ * simulate the original 640x400 surface, all Y values have to be doubled
+ */
+void ScreenSurface::writeCharacter(const Common::Point &pt, unsigned char ch, int palIndex) {
+ Graphics::Surface destSurface = lockArea(Common::Rect(pt.x, pt.y * 2,
+ pt.x + FONT_WIDTH, (pt.y + FONT_HEIGHT) * 2));
+
+ // Get the start of the character to use
+ assert((ch >= ' ') && (ch <= (unsigned char)(32 + FONT_NUM_CHARS)));
+ const byte *charData = &_fontData[((int)ch - 32) * FONT_HEIGHT];
+
+ // Loop through decoding each character's data
+ for (int yp = 0; yp < FONT_HEIGHT; ++yp) {
+ byte *lineP = (byte *)destSurface.getBasePtr(0, yp * 2);
+ byte byteVal = *charData++;
+
+ for (int xp = 0; xp < FONT_WIDTH; ++xp, ++lineP, byteVal <<= 1) {
+ if (byteVal & 0x80) {
+ *lineP = palIndex;
+ *(lineP + SCREEN_WIDTH) = palIndex;
+ }
+ }
+ }
+}
+
+/**
+ * Draws a box at the specified position and size
+ * @remarks Because the ScummVM surface is using a double height 640x400 surface to
+ * simulate the original 640x400 surface, all Y values have to be doubled
+ */
+void ScreenSurface::drawBox(int x, int y, int dx, int dy, int col) {
+ Graphics::Surface destSurface = lockArea(Common::Rect(x, y * 2, x + dx, (y + dy) * 2));
+
+ destSurface.hLine(0, 0, dx, col);
+ destSurface.hLine(0, 1, dx, col);
+ destSurface.hLine(0, destSurface.h - 1, dx, col);
+ destSurface.hLine(0, destSurface.h - 2, dx, col);
+ destSurface.vLine(0, 2, destSurface.h - 3, col);
+ destSurface.vLine(1, 2, destSurface.h - 3, col);
+ destSurface.vLine(dx - 1, 2, destSurface.h - 3, col);
+ destSurface.vLine(dx - 2, 2, destSurface.h - 3, col);
+}
+
+/**
+ * Fills an area with the specified color
+ * @remarks Because the ScummVM surface is using a double height 640x400 surface to
+ * simulate the original 640x400 surface, all Y values have to be doubled
+ */
+void ScreenSurface::fillRect(int color, const Common::Rect &bounds) {
+ Graphics::Surface destSurface = lockArea(Common::Rect(bounds.left, bounds.top * 2,
+ bounds.right, bounds.bottom * 2));
+
+ // Fill the area
+ destSurface.fillRect(Common::Rect(0, 0, destSurface.w, destSurface.h), color);
+}
+
+/**
+ * Clears the screen
+ */
+void ScreenSurface::clearScreen() {
+ Graphics::Surface destSurface = lockArea(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ destSurface.fillRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+}
+
+/**
+ * Sets a single pixel at the specified co-ordinates
+ * @remarks Because the ScummVM surface is using a double height 640x400 surface to
+ * simulate the original 640x400 surface, all Y values have to be doubled
+ */
+void ScreenSurface::setPixel(const Common::Point &pt, int palIndex) {
+ assert((pt.x >= 0) && (pt.y >= 0) && (pt.x <= SCREEN_WIDTH) && (pt.y <= SCREEN_ORIG_HEIGHT));
+ Graphics::Surface destSurface = lockArea(Common::Rect(pt.x, pt.y * 2, pt.x + 1, (pt.y + 1) * 2));
+
+ byte *destP = (byte *)destSurface.getPixels();
+ *destP = palIndex;
+ *(destP + SCREEN_WIDTH) = palIndex;
+}
+
+/**
+ * Write out a string
+ * @remarks Originally called 'writeg'
+ */
+void ScreenSurface::drawString(const Common::String &l, int command) {
+ if (l == "")
+ return;
+
+ _vm->_mouse.hideMouse();
+ Common::Point pt = _textPos;
+
+ int charWidth = 6;
+
+ int x = pt.x + charWidth * l.size();
+ int color = 0;
+
+ switch (command) {
+ case 0:
+ case 2:
+ color = 15;
+ _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));
+ break;
+ case 5:
+ color = 15;
+ break;
+ default:
+ // Default: Color set to zero (already done)
+ break;
+ }
+
+ 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);
+ pt.x += charWidth;
+ }
+ _vm->_mouse.showMouse();
+}
+
+/**
+ * Gets the width in pixels of the specified string
+ */
+int ScreenSurface::getStringWidth(const Common::String &s) {
+ int charWidth = 6;
+
+ return s.size() * charWidth;
+}
+
+void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
+ int step, i;
+ float a, b;
+ float xr, yr, xro, yro;
+
+ xr = x;
+ yr = y;
+ xro = xx;
+ yro = yy;
+
+ if (abs(y - yy) > abs(x - xx)) {
+ a = (float)((x - xx)) / (y - yy);
+ b = (yr * xro - yro * xr) / (y - yy);
+ i = y;
+ if (y > yy)
+ step = -1;
+ else
+ step = 1;
+ do {
+ _vm->_screenSurface.setPixel(Common::Point(abs((int)(a * i + b)), i), coul);
+ i += step;
+ } while (i != yy);
+ } else {
+ a = (float)((y - yy)) / (x - xx);
+ b = ((yro * xr) - (yr * xro)) / (x - xx);
+ i = x;
+ if (x > xx)
+ step = -1;
+ else
+ step = 1;
+ do {
+ _vm->_screenSurface.setPixel(Common::Point(i, abs((int)(a * i + b))), coul);
+ i = i + step;
+ } while (i != xx);
+ }
+}
+
+/**
+ * Draw plain rectangle
+ * @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));
+}
+
+void ScreenSurface::setParent(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/graphics.h b/engines/mortevielle/graphics.h
new file mode 100644
index 0000000000..e31f5da29a
--- /dev/null
+++ b/engines/mortevielle/graphics.h
@@ -0,0 +1,117 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_GRAPHICS_H
+#define MORTEVIELLE_GRAPHICS_H
+
+#include "common/file.h"
+#include "common/list.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+class PaletteManager {
+private:
+ void setPalette(const int *palette, uint idx, uint size);
+
+public:
+ void setDefaultPalette();
+};
+
+#define FONT_WIDTH 8
+#define FONT_HEIGHT 6
+#define FONT_NUM_CHARS 121
+
+class GfxSurface : public Graphics::Surface {
+private:
+ int _xp, _yp;
+ int _xSize, _ySize;
+ int _lookupIndex, _lookupValue;
+ bool _nibbleFlag;
+ int _thickness;
+ int _yInc, _yEnd, _xInc, _xEnd;
+
+ byte nextNibble(const byte *&pSrc);
+ byte nextByte(const byte *&pSrc, const byte *&pLookup);
+
+ void majTtxTty();
+ int desanalyse(const byte *&pSrc);
+ void horizontal(const byte *&pSrc, byte *&pDest, const byte *&pLookup);
+ void vertical(const byte *&pSrc, byte *&pDest, const byte *&pLookup);
+ void decom11(const byte *&pSrc, byte *&pDest, const byte *&pLookup);
+ void diag(const byte *&pSrc, byte *&pDest, const byte *&pLookup);
+ void nextDecompPtr(byte *&pDest);
+ void negXInc();
+ void negYInc();
+ bool TFP(int v);
+ void TF1(byte *&pDest, int &v);
+ void TF2(const byte *&pSrc, byte *&pDest, const byte *&pLookup, int &v);
+public:
+ // Specifies offset when drawing the image
+ Common::Point _offset;
+ // Transparency palette index
+ int _transparency;
+
+ ~GfxSurface();
+
+ void decode(const byte *pSrc);
+};
+
+class ScreenSurface: public Graphics::Surface {
+private:
+ MortevielleEngine *_vm;
+
+ Common::List<Common::Rect> _dirtyRects;
+ byte _fontData[FONT_NUM_CHARS * FONT_HEIGHT];
+
+public:
+ Common::Point _textPos; // Original called xwhere/ywhere
+ void readFontData(Common::File &f, int dataSize);
+ Graphics::Surface lockArea(const Common::Rect &bounds);
+ void updateScreen();
+ void drawPicture(GfxSurface &surface, int x, int y);
+ void copyFrom(Graphics::Surface &src, int x, int y);
+ void writeCharacter(const Common::Point &pt, unsigned char ch, int palIndex);
+ void drawBox(int x, int y, int dx, int dy, int col);
+ void fillRect(int color, const Common::Rect &bounds);
+ void clearScreen();
+ void putxy(int x, int y) { _textPos = Common::Point(x, y); }
+ void drawString(const Common::String &l, int command);
+ 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);
+};
+
+} // End of namespace Mortevielle
+
+#endif
diff --git a/engines/mortevielle/menu.cpp b/engines/mortevielle/menu.cpp
new file mode 100644
index 0000000000..641a527c98
--- /dev/null
+++ b/engines/mortevielle/menu.cpp
@@ -0,0 +1,792 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file _distributed with this source _distribution.
+ *
+ * This program is free software; you can re_distribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is _distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+
+#include "mortevielle/menu.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/textconsole.h"
+
+namespace Mortevielle {
+
+const byte menuConstants[8][4] = {
+ { 7, 37, 23, 8},
+ {19, 33, 23, 7},
+ {31, 89, 10, 21},
+ {43, 25, 11, 5},
+ {55, 37, 5, 8},
+ {64, 13, 11, 2},
+ {62, 42, 13, 9},
+ {62, 46, 13, 10}
+};
+
+Menu::Menu() {
+ _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;
+}
+
+void Menu::readVerbNums(Common::File &f, int dataSize) {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ return;
+ }
+
+ assert(dataSize == 52);
+ _opcodeAttach = f.readUint16LE();
+ _opcodeWait = f.readUint16LE();
+ _opcodeForce = f.readUint16LE();
+ _opcodeSleep = f.readUint16LE();
+ _opcodeListen = f.readUint16LE();
+ _opcodeEnter = f.readUint16LE();
+ _opcodeClose = f.readUint16LE();
+ _opcodeSearch = f.readUint16LE();
+ _opcodeKnock = f.readUint16LE();
+ _opcodeScratch = f.readUint16LE();
+ _opcodeRead = f.readUint16LE();
+ _opcodeEat = f.readUint16LE();
+ _opcodePlace = f.readUint16LE();
+ _opcodeOpen = f.readUint16LE();
+ _opcodeTake = f.readUint16LE();
+ _opcodeLook = f.readUint16LE();
+ _opcodeSmell = f.readUint16LE();
+ _opcodeSound = f.readUint16LE();
+ _opcodeLeave = f.readUint16LE();
+ _opcodeLift = f.readUint16LE();
+ _opcodeTurn = f.readUint16LE();
+ _opcodeSHide = f.readUint16LE();
+ _opcodeSSearch = f.readUint16LE();
+ _opcodeSRead = f.readUint16LE();
+ _opcodeSPut = f.readUint16LE();
+ _opcodeSLook = f.readUint16LE();
+
+ _actionMenu[0]._menuId = OPCODE_NONE >> 8;
+ _actionMenu[0]._actionId = OPCODE_NONE & 0xFF;
+
+ _actionMenu[1]._menuId = _opcodeSHide >> 8;
+ _actionMenu[1]._actionId = _opcodeSHide & 0xFF;
+
+ _actionMenu[2]._menuId = _opcodeAttach >> 8;
+ _actionMenu[2]._actionId = _opcodeAttach & 0xFF;
+
+ _actionMenu[3]._menuId = _opcodeForce >> 8;
+ _actionMenu[3]._actionId = _opcodeForce & 0xFF;
+
+ _actionMenu[4]._menuId = _opcodeSleep >> 8;
+ _actionMenu[4]._actionId = _opcodeSleep & 0xFF;
+
+ _actionMenu[5]._menuId = _opcodeEnter >> 8;
+ _actionMenu[5]._actionId = _opcodeEnter & 0xFF;
+
+ _actionMenu[6]._menuId = _opcodeClose >> 8;
+ _actionMenu[6]._actionId = _opcodeClose & 0xFF;
+
+ _actionMenu[7]._menuId = _opcodeKnock >> 8;
+ _actionMenu[7]._actionId = _opcodeKnock & 0xFF;
+
+ _actionMenu[8]._menuId = _opcodeEat >> 8;
+ _actionMenu[8]._actionId = _opcodeEat & 0xFF;
+
+ _actionMenu[9]._menuId = _opcodePlace >> 8;
+ _actionMenu[9]._actionId = _opcodePlace & 0xFF;
+
+ _actionMenu[10]._menuId = _opcodeOpen >> 8;
+ _actionMenu[10]._actionId = _opcodeOpen & 0xFF;
+
+ _actionMenu[11]._menuId = _opcodeLeave >> 8;
+ _actionMenu[11]._actionId = _opcodeLeave & 0xFF;
+}
+
+/**
+ * Setup a menu's contents
+ * @remarks Originally called 'menut'
+ */
+void Menu::setText(MenuItem item, Common::String name) {
+ Common::String s = name;
+
+ switch (item._menuId) {
+ case MENU_INVENTORY:
+ if (item._actionId != 7) {
+ while (s.size() < 22)
+ s += ' ';
+
+ _inventoryStringArray[item._actionId] = s;
+ _inventoryStringArray[item._actionId].insertChar(' ', 0);
+ }
+ break;
+ case MENU_MOVE: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 22)
+ s += ' ';
+
+ _moveStringArray[item._actionId] = s;
+ }
+ break;
+ case MENU_ACTION: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _actionStringArray[item._actionId] = s;
+ }
+ break;
+ case MENU_SELF: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _selfStringArray[item._actionId] = s;
+ }
+ break;
+ case MENU_DISCUSS:
+ _discussStringArray[item._actionId] = s;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Init destination menu
+ * @remarks Originally called 'tmlieu'
+ */
+void Menu::setDestinationText(int roomId) {
+ Common::String nomp;
+
+ if (roomId == ROOM26)
+ roomId = LANDING;
+
+ int destinationId = 0;
+ for (; (destinationId < 7) && (_vm->_destinationArray[destinationId][roomId]); ++destinationId) {
+ nomp = _vm->getString(_vm->_destinationArray[destinationId][roomId] + kMenuPlaceStringIndex);
+ while (nomp.size() < 20)
+ nomp += ' ';
+ setText(_moveMenu[destinationId + 1], nomp);
+ }
+ nomp = "* ";
+ for (int i = 7; i >= destinationId + 1; --i)
+ setText(_moveMenu[i], nomp);
+}
+
+/**
+ * _disable a menu item
+ * @param menuId Menu number
+ * @param actionId Item index
+ */
+void Menu::disableMenuItem(MenuItem item) {
+ switch (item._menuId) {
+ case MENU_INVENTORY:
+ if (item._actionId > 6) {
+ _inventoryStringArray[item._actionId].setChar('<', 0);
+ _inventoryStringArray[item._actionId].setChar('>', 21);
+ } else
+ _inventoryStringArray[item._actionId].setChar('*', 0);
+ break;
+ case MENU_MOVE:
+ _moveStringArray[item._actionId].setChar('*', 0);
+ break;
+ case MENU_ACTION:
+ _actionStringArray[item._actionId].setChar('*', 0);
+ break;
+ case MENU_SELF:
+ _selfStringArray[item._actionId].setChar('*', 0);
+ break;
+ case MENU_DISCUSS:
+ _discussStringArray[item._actionId].setChar('*', 0);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Enable a menu item
+ * @param menuId Menu number
+ * @param actionId Item index
+ * @remarks Originally called menu_enable
+ */
+void Menu::enableMenuItem(MenuItem item) {
+ switch (item._menuId) {
+ case MENU_INVENTORY:
+ _inventoryStringArray[item._actionId].setChar(' ', 0);
+ _inventoryStringArray[item._actionId].setChar(' ', 21);
+ break;
+ case MENU_MOVE:
+ _moveStringArray[item._actionId].setChar(' ', 0);
+ break;
+ case MENU_ACTION:
+ _actionStringArray[item._actionId].setChar(' ', 0);
+ break;
+ case MENU_SELF:
+ _selfStringArray[item._actionId].setChar(' ', 0);
+ break;
+ case MENU_DISCUSS:
+ _discussStringArray[item._actionId].setChar(' ', 0);
+ break;
+ default:
+ break;
+ }
+}
+
+void Menu::displayMenu() {
+ _vm->_mouse.hideMouse();
+ _vm->_screenSurface.fillRect(7, Common::Rect(0, 0, 639, 10));
+
+ int col = 28 * kResolutionScaler;
+ for (int charNum = 0; charNum < 6; charNum++) {
+ // One character after the other
+ int idx = 0;
+ for (int y = 1; y < 9; ++y) {
+ // One column after the other
+ int x = col;
+ for (int k = 0; k < 3; ++k) {
+ // One line after the other
+ 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);
+ }
+ msk >>= 1;
+ ++x;
+ }
+ ++idx;
+ }
+ }
+ col += 48 * kResolutionScaler;
+ }
+ _vm->_mouse.showMouse();
+}
+
+/**
+ * Show the menu
+ */
+void Menu::drawMenu() {
+ displayMenu();
+ _menuActive = true;
+ _msg4 = OPCODE_NONE;
+ _msg3 = OPCODE_NONE;
+ _menuSelected = false;
+ _vm->setMouseClick(false);
+ _multiTitle = false;
+}
+
+/**
+ * Menu function - Invert a menu entry
+ * @remarks Originally called 'invers'
+ */
+void Menu::invert(int indx) {
+ if (_msg4 == OPCODE_NONE)
+ return;
+
+ int menuIndex = _msg4 & 0xFF;
+
+ _vm->_screenSurface.putxy(menuConstants[_msg3 - 1][0] << 3, (menuIndex + 1) << 3);
+
+ Common::String str;
+ switch (_msg3) {
+ case MENU_INVENTORY:
+ str = _inventoryStringArray[menuIndex];
+ break;
+ case MENU_MOVE:
+ str = _moveStringArray[menuIndex];
+ break;
+ case MENU_ACTION:
+ str = _actionStringArray[menuIndex];
+ break;
+ case MENU_SELF:
+ str = _selfStringArray[menuIndex];
+ break;
+ case MENU_DISCUSS:
+ str = _discussStringArray[menuIndex];
+ break;
+ case MENU_FILE:
+ str = _vm->getEngineString(S_SAVE_LOAD + menuIndex);
+ break;
+ case MENU_SAVE:
+ str = _vm->getEngineString(S_SAVE_LOAD + 1);
+ str += ' ';
+ str += (char)(48 + menuIndex);
+ break;
+ case MENU_LOAD:
+ if (menuIndex == 1) {
+ str = _vm->getEngineString(S_RESTART);
+ } else {
+ str = _vm->getEngineString(S_SAVE_LOAD + 2);
+ str += ' ';
+ str += (char)(47 + menuIndex);
+ }
+ break;
+ default:
+ break;
+ }
+ if ((str[0] != '*') && (str[0] != '<'))
+ _vm->_screenSurface.drawString(str, indx);
+ else
+ _msg4 = OPCODE_NONE;
+}
+
+void Menu::util(Common::Point pos) {
+
+ int ymx = (menuConstants[_msg3 - 1][3] << 3) + 16;
+ int dxcar = menuConstants[_msg3 - 1][2];
+ int xmn = (menuConstants[_msg3 - 1][0] << 2) * kResolutionScaler;
+
+ int charWidth = 6;
+ int xmx = dxcar * charWidth + xmn + 2;
+ if ((pos.x > xmn) && (pos.x < xmx) && (pos.y < ymx) && (pos.y > 15)) {
+ int ix = (((uint)pos.y >> 3) - 1) + (_msg3 << 8);
+ if (ix != _msg4) {
+ invert(1);
+ _msg4 = ix;
+ invert(0);
+ }
+ } else if (_msg4 != OPCODE_NONE) {
+ invert(1);
+ _msg4 = OPCODE_NONE;
+ }
+}
+
+/**
+ * Draw a menu
+ */
+void Menu::menuDown(int ii) {
+ // Make a copy of the current screen surface for later restore
+ _vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
+
+ // Draw the menu
+ int minX = menuConstants[ii - 1][0] << 3;
+ int lineNum = menuConstants[ii - 1][3];
+ _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);
+ for (int i = 1; i <= lineNum; i++) {
+ switch (ii) {
+ case 1:
+ if (_inventoryStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_inventoryStringArray[i], 4);
+ break;
+ case 2:
+ if (_moveStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_moveStringArray[i], 4);
+ break;
+ case 3:
+ if (_actionStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_actionStringArray[i], 4);
+ break;
+ case 4:
+ if (_selfStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_selfStringArray[i], 4);
+ break;
+ case 5:
+ if (_discussStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_discussStringArray[i], 4);
+ break;
+ case 6:
+ _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);
+ }
+ break;
+ case 8:
+ if (i == 1)
+ _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);
+ }
+ break;
+ default:
+ break;
+ }
+ _vm->_screenSurface.putxy(minX, _vm->_screenSurface._textPos.y + 8);
+ }
+ _multiTitle = true;
+ _vm->_mouse.showMouse();
+}
+
+/**
+ * Menu is being removed, so restore the previous background area.
+ */
+void Menu::menuUp(int msgId) {
+ if (_multiTitle) {
+ /* Restore the background area */
+ 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));
+ byte *pDest = (byte *)destArea.getPixels();
+
+ // Copy the data
+ Common::copy(pSrc, pSrc + (400 - 10) * SCREEN_WIDTH, pDest);
+
+ _multiTitle = false;
+ }
+}
+
+/**
+ * Erase the menu
+ */
+void Menu::eraseMenu() {
+ _menuActive = false;
+ _vm->setMouseClick(false);
+ menuUp(_msg3);
+}
+
+/**
+ * Handle updates to the menu
+ * @remarks Originally called 'mdn'
+ */
+void Menu::updateMenu() {
+ if (!_menuActive)
+ return;
+
+ Common::Point curPos = _vm->_mouse._pos;
+ if (!_vm->getMouseClick()) {
+ if (curPos == _vm->_prevPos)
+ return;
+ else
+ _vm->_prevPos = curPos;
+
+ bool tes = (curPos.y < 11)
+ && ((curPos.x >= (28 * kResolutionScaler) && curPos.x <= (28 * kResolutionScaler + 24))
+ || (curPos.x >= (76 * kResolutionScaler) && curPos.x <= (76 * kResolutionScaler + 24))
+ || ((curPos.x > 124 * kResolutionScaler) && (curPos.x < 124 * kResolutionScaler + 24))
+ || ((curPos.x > 172 * kResolutionScaler) && (curPos.x < 172 * kResolutionScaler + 24))
+ || ((curPos.x > 220 * kResolutionScaler) && (curPos.x < 220 * kResolutionScaler + 24))
+ || ((curPos.x > 268 * kResolutionScaler) && (curPos.x < 268 * kResolutionScaler + 24)));
+ if (tes) {
+ int ix;
+
+ if (curPos.x < 76 * kResolutionScaler)
+ ix = MENU_INVENTORY;
+ else if (curPos.x < 124 * kResolutionScaler)
+ ix = MENU_MOVE;
+ else if (curPos.x < 172 * kResolutionScaler)
+ ix = MENU_ACTION;
+ else if (curPos.x < 220 * kResolutionScaler)
+ ix = MENU_SELF;
+ else if (curPos.x < 268 * kResolutionScaler)
+ ix = MENU_DISCUSS;
+ else
+ ix = MENU_FILE;
+
+ if ((ix != _msg3) || (!_multiTitle))
+ if (!((ix == MENU_FILE) && ((_msg3 == MENU_SAVE) || (_msg3 == MENU_LOAD)))) {
+ menuUp(_msg3);
+ menuDown(ix);
+ _msg3 = ix;
+ _msg4 = OPCODE_NONE;
+ }
+ } else { // Not in the MenuTitle line
+ if ((curPos.y > 11) && (_multiTitle))
+ util(curPos);
+ }
+ } else { // There was a click
+ if ((_msg3 == MENU_FILE) && (_msg4 != OPCODE_NONE)) {
+ // Another menu to be _displayed
+ _vm->setMouseClick(false);
+ menuUp(_msg3);
+ if ((_msg4 & 0xFF) == 1)
+ _msg3 = MENU_SAVE;
+ else
+ _msg3 = MENU_LOAD;
+ menuDown(_msg3);
+
+ _vm->setMouseClick(false);
+ } else {
+ // A menu was clicked on
+ _menuSelected = (_multiTitle) && (_msg4 != OPCODE_NONE);
+ menuUp(_msg3);
+ _vm->_currAction = _msg4;
+ _vm->_currMenu = _msg3;
+ _msg3 = OPCODE_NONE;
+ _msg4 = OPCODE_NONE;
+
+ _vm->setMouseClick(false);
+ }
+ }
+}
+
+void Menu::setParent(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
+void Menu::initMenu() {
+ Common::File f;
+
+ bool menuLoaded = false;
+ // First try to read it from mort.dat if useOriginalData() is false
+ if (!_vm->useOriginalData()) {
+ if (!f.open(MORT_DAT))
+ warning("File %s not found. Using default menu from game data", MORT_DAT);
+ else {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+
+ // Validate the data file header
+ char fileId[4];
+ f.read(fileId, 4);
+ // Do not display warnings here. They would already have been displayed in MortevielleEngine::loadMortDat().
+ if (strncmp(fileId, "MORT", 4) == 0 && f.readByte() >= MORT_DAT_REQUIRED_VERSION) {
+ f.readByte(); // Minor version
+ // Loop to load resources from the data file
+ while (f.pos() < f.size()) {
+ // Get the Id and size of the next resource
+ char dataType[4];
+ int dataSize;
+ f.read(dataType, 4);
+ dataSize = f.readUint16LE();
+ if (!strncmp(dataType, "MENU", 4)) {
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ continue;
+ }
+ if (dataSize == 6 * 24) {
+ f.read(_charArr, dataSize);
+ menuLoaded = true;
+ } else
+ warning("Wrong size %d for menu data. Expected %d or less", dataSize, 6 * 24);
+ break;
+ } else {
+ // Other sections
+ f.skip(dataSize);
+ }
+ }
+ }
+ // Close the file
+ f.close();
+ if (!menuLoaded)
+ warning("Failed to load menu from mort.dat. Will use default menu from game data instead.");
+ }
+ }
+
+ if (!menuLoaded) {
+ // Load menu from game data using the original language
+ if (_vm->getOriginalLanguage() == Common::FR_FRA) {
+ if (!f.open("menufr.mor"))
+ error("Missing file - menufr.mor");
+ } else { // Common::DE_DEU
+ if (!f.open("menual.mor"))
+ error("Missing file - menual.mor");
+ }
+ f.read(_charArr, 6 * 24);
+ f.close();
+ }
+
+ // Skipped: dialog asking to swap floppy
+
+ for (int i = 1; i <= 8; ++i)
+ _inventoryStringArray[i] = "* ";
+ _inventoryStringArray[7] = "< -*-*-*-*-*-*-*-*-*- ";
+ for (int i = 1; i <= 7; ++i)
+ _moveStringArray[i] = "* ";
+ for (int i = 1; i < 22; i++) {
+ _actionStringArray[i] = _vm->getString(i + kMenuActionStringIndex);
+ if ((_actionStringArray[i][0] != '*') && (_actionStringArray[i][0] != ' '))
+ _actionStringArray[i].insertChar(' ', 0);
+ while (_actionStringArray[i].size() < 10)
+ _actionStringArray[i] += ' ';
+
+ if (i < 9) {
+ if (i < 6) {
+ _selfStringArray[i] = _vm->getString(i + kMenuSelfStringIndex);
+ if ((_selfStringArray[i][0] != '*') && (_selfStringArray[i][0] != ' '))
+ _selfStringArray[i].insertChar(' ', 0);
+ while (_selfStringArray[i].size() < 10)
+ _selfStringArray[i] += ' ';
+ }
+ _discussStringArray[i] = _vm->getString(i + kMenuSayStringIndex) + ' ';
+ }
+ }
+ for (int i = 1; i <= 8; ++i) {
+ _discussMenu[i]._menuId = MENU_DISCUSS;
+ _discussMenu[i]._actionId = i;
+ if (i < 8) {
+ _moveMenu[i]._menuId = MENU_MOVE;
+ _moveMenu[i]._actionId = i;
+ }
+ _inventoryMenu[i]._menuId = MENU_INVENTORY;
+ _inventoryMenu[i]._actionId = i;
+ if (i > 6)
+ disableMenuItem(_inventoryMenu[i]);
+ }
+ _msg3 = OPCODE_NONE;
+ _msg4 = OPCODE_NONE;
+ _vm->_currMenu = OPCODE_NONE;
+ _vm->_currAction = OPCODE_NONE;
+ _vm->setMouseClick(false);
+}
+
+/**
+ * Engine function - Switch action menu to "Search" mode
+ * @remarks Originally called 'mfoudi'
+ */
+void Menu::setSearchMenu() {
+ for (int i = 1; i <= 7; ++i)
+ disableMenuItem(_moveMenu[i]);
+
+ for (int i = 1; i <= 11; ++i)
+ disableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
+
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
+
+ setText(miSound, _vm->getEngineString(S_SUITE));
+ setText(miLift, _vm->getEngineString(S_STOP));
+}
+
+/**
+ * Engine function - Switch action menu from "Search" mode back to normal mode
+ * @remarks Originally called 'mfouen'
+ */
+void Menu::unsetSearchMenu() {
+ setDestinationText(_vm->_coreVar._currPlace);
+ for (int i = 1; i <= 11; ++i)
+ enableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
+
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
+
+ setText(miSound, _vm->getEngineString(S_PROBE));
+ setText(miLift, _vm->getEngineString(S_RAISE));
+}
+
+/**
+ * Set Inventory menu texts
+ * @remarks Originally called 'modinv'
+ */
+void Menu::setInventoryText() {
+ Common::String nomp;
+
+ int cy = 0;
+ for (int i = 1; i <= 6; ++i) {
+ if (_vm->_coreVar._inventory[i] != 0) {
+ ++cy;
+ int r = _vm->_coreVar._inventory[i] + 400;
+ nomp = _vm->getString(r - 501 + kInventoryStringIndex);
+ setText(_inventoryMenu[cy], nomp);
+ enableMenuItem(_inventoryMenu[i]);
+ }
+ }
+
+ if (cy < 6) {
+ for (int i = cy + 1; i <= 6; ++i) {
+ setText(_inventoryMenu[i], " ");
+ disableMenuItem(_inventoryMenu[i]);
+ }
+ }
+}
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/menu.h b/engines/mortevielle/menu.h
new file mode 100644
index 0000000000..debf5b09b6
--- /dev/null
+++ b/engines/mortevielle/menu.h
@@ -0,0 +1,125 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_MENU_H
+#define MORTEVIELLE_MENU_H
+
+#include "common/rect.h"
+#include "common/str.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+enum {
+ MENU_NONE = 0, MENU_INVENTORY = 1, MENU_MOVE = 2, MENU_ACTION = 3,
+ MENU_SELF = 4, MENU_DISCUSS = 5, MENU_FILE = 6, MENU_SAVE = 7,
+ MENU_LOAD = 8
+};
+
+const int OPCODE_NONE = 0;
+
+struct MenuItem {
+ int _menuId;
+ int _actionId;
+};
+
+class Menu {
+private:
+ MortevielleEngine *_vm;
+
+ byte _charArr[6][24];
+ int _msg3;
+ int _msg4;
+
+ void util(Common::Point pos);
+ void invert(int indx);
+ void menuDown(int ii);
+
+public:
+ Menu();
+
+ bool _menuActive;
+ bool _menuSelected;
+ bool _multiTitle;
+ bool _menuDisplayed;
+ Common::String _inventoryStringArray[9];
+ Common::String _moveStringArray[8];
+ Common::String _actionStringArray[22];
+ Common::String _selfStringArray[7];
+ Common::String _discussStringArray[9];
+ MenuItem _discussMenu[9];
+ MenuItem _inventoryMenu[9];
+ MenuItem _moveMenu[8];
+
+ int _opcodeAttach;
+ int _opcodeWait;
+ int _opcodeForce;
+ int _opcodeSleep;
+ int _opcodeListen;
+ int _opcodeEnter;
+ int _opcodeClose;
+ int _opcodeSearch;
+ int _opcodeKnock;
+ int _opcodeScratch;
+ int _opcodeRead;
+ int _opcodeEat;
+ int _opcodePlace;
+ int _opcodeOpen;
+ int _opcodeTake;
+ int _opcodeLook;
+ int _opcodeSmell;
+ int _opcodeSound;
+ int _opcodeLeave;
+ int _opcodeLift;
+ int _opcodeTurn;
+ int _opcodeSHide;
+ int _opcodeSSearch;
+ int _opcodeSRead;
+ int _opcodeSPut;
+ 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);
+ void setInventoryText();
+ void disableMenuItem(MenuItem item);
+ void enableMenuItem(MenuItem item);
+ void displayMenu();
+ void drawMenu();
+ void menuUp(int msgId);
+ void eraseMenu();
+ void updateMenu();
+ void initMenu();
+
+ void setSearchMenu();
+ void unsetSearchMenu();
+};
+
+} // End of namespace Mortevielle
+#endif
diff --git a/engines/mortevielle/module.mk b/engines/mortevielle/module.mk
new file mode 100644
index 0000000000..a9f02c2a67
--- /dev/null
+++ b/engines/mortevielle/module.mk
@@ -0,0 +1,23 @@
+MODULE := engines/mortevielle
+
+MODULE_OBJS := \
+ actions.o \
+ debugger.o \
+ detection.o \
+ dialogs.o \
+ graphics.o \
+ menu.o \
+ mortevielle.o \
+ mouse.o \
+ outtext.o \
+ saveload.o \
+ sound.o \
+ utils.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_MORTEVIELLE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
new file mode 100644
index 0000000000..d434150977
--- /dev/null
+++ b/engines/mortevielle/mortevielle.cpp
@@ -0,0 +1,458 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+
+#include "mortevielle/dialogs.h"
+#include "mortevielle/menu.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+#include "mortevielle/saveload.h"
+#include "mortevielle/outtext.h"
+
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+#include "engines/util.h"
+#include "engines/engine.h"
+#include "graphics/palette.h"
+#include "graphics/pixelformat.h"
+
+namespace Mortevielle {
+
+MortevielleEngine *g_vm;
+
+MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc):
+ Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle"),
+ _soundManager(_mixer) {
+ 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);
+
+ _lastGameFrame = 0;
+ _mouseClick = false;
+ _inMainGameLoop = false;
+ _quitGame = false;
+ _pauseStartTime = -1;
+
+ _roomPresenceLuc = false;
+ _roomPresenceIda = false;
+ _purpleRoomPresenceLeo = false;
+ _roomPresenceGuy = false;
+ _roomPresenceEva = false;
+ _roomPresenceMax = false;
+ _roomPresenceBob = false;
+ _roomPresencePat = false;
+ _toiletsPresenceBobMax = false;
+ _bathRoomPresenceBobMax = false;
+ _juliaRoomPresenceLeo = false;
+
+ _soundOff = false;
+ _largestClearScreen = false;
+ _hiddenHero = false;
+ _heroSearching = false;
+ _keyPressedEsc = false;
+ _reloadCFIEC = false;
+
+ _blo = false;
+ _col = false;
+ _syn = false;
+ _obpart = false;
+ _destinationOk = false;
+ _anyone = false;
+ _uptodatePresence = false;
+
+ _textColor = 0;
+ _place = -1;
+
+ _x26KeyCount = -1;
+ _caff = -1;
+ _day = 0;
+
+ _curPict = nullptr;
+ _curAnim = nullptr;
+ _rightFramePict = nullptr;
+}
+
+MortevielleEngine::~MortevielleEngine() {
+ free(_curPict);
+ free(_curAnim);
+ free(_rightFramePict);
+}
+
+/**
+ * Specifies whether the engine supports given features
+ */
+bool MortevielleEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+/**
+ * Return true if a game can currently be loaded
+ */
+bool MortevielleEngine::canLoadGameStateCurrently() {
+ // Saving is only allowed in the main game event loop
+ return _inMainGameLoop;
+}
+
+/**
+ * Return true if a game can currently be saved
+ */
+bool MortevielleEngine::canSaveGameStateCurrently() {
+ // Loading is only allowed in the main game event loop
+ return _inMainGameLoop;
+}
+
+/**
+ * Load in a savegame at the specified slot number
+ */
+Common::Error MortevielleEngine::loadGameState(int slot) {
+ return _savegameManager.loadGame(slot);
+}
+
+/**
+ * Save the current game
+ */
+Common::Error MortevielleEngine::saveGameState(int slot, const Common::String &desc) {
+ if (slot == 0)
+ return Common::kWritingFailed;
+
+ return _savegameManager.saveGame(slot, desc);
+}
+
+/**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+Common::String MortevielleEngine::generateSaveFilename(const Common::String &target, int slot) {
+ if (slot == 0)
+ // Initial game state loaded when the game starts
+ return "sav0.mor";
+
+ return Common::String::format("%s.%03d", target.c_str(), slot);
+}
+
+/**
+ * Pause the game.
+ */
+void MortevielleEngine::pauseEngineIntern(bool pause) {
+ Engine::pauseEngineIntern(pause);
+ if (pause) {
+ if (_pauseStartTime == -1)
+ _pauseStartTime = readclock();
+ } else {
+ if (_pauseStartTime != -1) {
+ int pauseEndTime = readclock();
+ _currentTime += (pauseEndTime - _pauseStartTime);
+ if (_uptodatePresence)
+ _startTime += (pauseEndTime - _pauseStartTime);
+ }
+ _pauseStartTime = -1;
+ }
+}
+
+/**
+ * Initialize the game state
+ */
+Common::ErrorCode MortevielleEngine::initialize() {
+ // Initialize graphics mode
+ initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, true);
+
+ // Set debug channels
+ DebugMan.addDebugChannel(kMortevielleCore, "core", "Core debugging");
+ DebugMan.addDebugChannel(kMortevielleGraphics, "graphics", "Graphics debugging");
+
+ // Set up an intermediate screen surface
+ _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+
+ _txxFileFl = false;
+ // Load texts from TXX files
+ loadTexts();
+
+ // Load the mort.dat resource
+ Common::ErrorCode result = loadMortDat();
+ if (result != Common::kNoError) {
+ _screenSurface.free();
+ return result;
+ }
+
+ // Load some error messages (was previously in chartex())
+ _hintPctMessage = getString(580); // You should have noticed %d hints
+
+ // Set default EGA palette
+ _paletteManager.setDefaultPalette();
+
+ // Setup the mouse cursor
+ initMouse();
+
+ loadPalette();
+ loadCFIPH();
+ loadCFIEC();
+ decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
+ _x26KeyCount = 1;
+ initMaxAnswer();
+ initMouse();
+
+ loadPlaces();
+ _soundOff = false;
+ _largestClearScreen = false;
+
+ testKeyboard();
+ showConfigScreen();
+ testKeyboard();
+ clearScreen();
+
+ _soundManager.loadNoise();
+ _soundManager.loadAmbiantSounds();
+
+ return Common::kNoError;
+}
+
+/**
+ * Loads the contents of the mort.dat data file
+ */
+Common::ErrorCode MortevielleEngine::loadMortDat() {
+ Common::File f;
+
+ // Open the mort.dat file
+ if (!f.open(MORT_DAT)) {
+ GUIErrorMessage("Could not locate 'mort.dat'.");
+ return Common::kReadingFailed;
+ }
+
+ // Validate the data file header
+ char fileId[4];
+ f.read(fileId, 4);
+ if (strncmp(fileId, "MORT", 4) != 0) {
+ GUIErrorMessage("The located mort.dat data file is invalid");
+ return Common::kReadingFailed;
+ }
+
+ // Check the version
+ if (f.readByte() < MORT_DAT_REQUIRED_VERSION) {
+ GUIErrorMessage("The located mort.dat data file is too old, please download an updated version on scummvm.org");
+ return Common::kReadingFailed;
+ }
+ f.readByte(); // Minor version
+
+ // Loop to load resources from the data file
+ while (f.pos() < f.size()) {
+ // Get the Id and size of the next resource
+ char dataType[4];
+ int dataSize;
+ f.read(dataType, 4);
+ dataSize = f.readUint16LE();
+
+ if (!strncmp(dataType, "FONT", 4)) {
+ // Font resource
+ _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);
+ } else {
+ // Unknown section
+ f.skip(dataSize);
+ }
+ }
+
+ // Close the file
+ f.close();
+
+ assert(_engineStrings.size() > 0);
+ return Common::kNoError;
+}
+
+
+/**
+ * Read in a static strings block, and if the language matches, load up the static strings
+ */
+void MortevielleEngine::readStaticStrings(Common::File &f, int dataSize, DataType dataType) {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ return;
+ }
+
+ // Load in each of the strings
+ while (dataSize > 0) {
+ Common::String s;
+ char ch;
+ while ((ch = (char)f.readByte()) != '\0')
+ s += ch;
+
+ if (dataType == kStaticStrings)
+ _engineStrings.push_back(s);
+ else if (dataType == kGameStrings)
+ _gameStrings.push_back(s);
+
+ dataSize -= s.size() + 1;
+ }
+ assert(dataSize == 0);
+}
+
+/*-------------------------------------------------------------------------*/
+
+Common::Error MortevielleEngine::run() {
+ // Initialize the game
+ Common::ErrorCode err = initialize();
+ if (err != Common::kNoError)
+ return err;
+
+ // Check for a savegame
+ int loadSlot = 0;
+ if (ConfMan.hasKey("save_slot")) {
+ int gameToLoad = ConfMan.getInt("save_slot");
+ if ((gameToLoad >= 1) && (gameToLoad <= 999))
+ loadSlot = gameToLoad;
+ }
+
+ if (loadSlot == 0)
+ // Show the game introduction
+ showIntroduction();
+ else {
+ _caff = 51;
+ _text.taffich();
+ }
+
+ // Either load the initial game state savegame, or the specified savegame number
+ adzon();
+ resetVariables();
+ if (loadSlot != 0)
+ _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
+
+ // Run the main game loop
+ mainGame();
+
+ // Cleanup (allocated in initialize())
+ _screenSurface.free();
+ free(_soundManager._cfiphBuffer);
+ free(_cfiecBuffer);
+
+ return Common::kNoError;
+}
+
+/**
+ * Show the game introduction
+ */
+void MortevielleEngine::showIntroduction() {
+ _dialogManager.displayIntroScreen(false);
+ _dialogManager.checkForF8(142, false);
+ if (shouldQuit())
+ return;
+
+ _dialogManager.displayIntroFrame2();
+ _dialogManager.checkForF8(143, true);
+ if (shouldQuit())
+ return;
+
+ showTitleScreen();
+ music();
+ _mixer->stopAll();
+}
+
+/**
+ * Main game loop. Handles potentially playing the game multiple times, such as if the player
+ * loses, and chooses to start playing the game again.
+ */
+void MortevielleEngine::mainGame() {
+ if (_reloadCFIEC)
+ loadCFIEC();
+
+ for (_crep = 1; _crep <= _x26KeyCount; ++_crep)
+ decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
+
+ _menu.initMenu();
+
+ charToHour();
+ initGame();
+ clearScreen();
+ drawRightFrame();
+ _mouse.showMouse();
+
+ // Loop to play the game
+ do {
+ playGame();
+ if (shouldQuit())
+ return;
+ } while (!_quitGame);
+}
+
+/**
+ * This method handles playing a loaded game
+ * @remarks Originally called tjouer
+ */
+void MortevielleEngine::playGame() {
+ gameLoaded();
+
+ // Loop handling actions until the game has to be quit, or show the lose or end sequence
+ do {
+ handleAction();
+ if (shouldQuit())
+ return;
+ } while (!((_quitGame) || (_endGame) || (_loseGame)));
+
+ if (_endGame)
+ endGame();
+ else if (_loseGame)
+ askRestart();
+}
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
new file mode 100644
index 0000000000..5ae94987a0
--- /dev/null
+++ b/engines/mortevielle/mortevielle.h
@@ -0,0 +1,494 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_MORTEVIELLE_H
+#define MORTEVIELLE_MORTEVIELLE_H
+
+#include "common/events.h"
+#include "common/file.h"
+#include "common/random.h"
+#include "common/rect.h"
+#include "common/stack.h"
+#include "engines/advancedDetector.h"
+#include "engines/engine.h"
+#include "common/error.h"
+#include "graphics/surface.h"
+#include "mortevielle/debugger.h"
+#include "mortevielle/dialogs.h"
+#include "mortevielle/graphics.h"
+#include "mortevielle/menu.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/saveload.h"
+#include "mortevielle/sound.h"
+#include "mortevielle/outtext.h"
+
+namespace Mortevielle {
+
+// Debug channels
+enum {
+ kMortevielleCore = 1 << 0,
+ kMortevielleGraphics = 1 << 1,
+ kMortevielleSounds = 1 << 2
+};
+
+// Game languages
+enum {
+ MORTDAT_LANG_FRENCH = 0,
+ MORTDAT_LANG_ENGLISH = 1,
+ MORTDAT_LANG_GERMAN = 2
+};
+
+enum {
+ kUseOriginalData = 0,
+ kUseEngineDataFile = 1
+};
+
+// Static string list
+enum {
+ S_YES_NO = 0, S_GO_TO = 1, S_SOMEONE_ENTERS = 2, S_COOL = 3, S_LOURDE = 4,
+ S_MALSAINE = 5, S_IDEM = 6, S_YOU = 7, S_ARE = 8, S_ALONE = 9,
+ S_HEAR_NOISE = 10, S_SHOULD_HAVE_NOTICED = 11, S_NUMBER_OF_HINTS = 12,
+ S_WANT_TO_WAKE_UP = 13, S_OKAY = 14, S_SAVE_LOAD = 15, S_RESTART = 18, S_F3 = 19,
+ S_F8 = 20, S_HIDE_SELF = 21, S_TAKE = 22, S_PROBE = 23, S_RAISE = 24, S_SUITE = 25,
+ S_STOP = 26, S_USE_DEP_MENU = 27, S_LIFT = 28, S_READ = 29,
+ S_LOOK = 30, S_SEARCH = 31, S_OPEN = 32, S_PUT = 33, S_TURN = 34, S_TIE = 35, S_CLOSE = 36,
+ S_HIT = 37, S_POSE = 38, S_SMASH = 39,
+
+ S_SMELL = 40, S_SCRATCH = 41, S_PROBE2 = 42, S_BEFORE_USE_DEP_MENU = 43, S_DAY = 44
+};
+
+enum DataType {
+ kStaticStrings = 0,
+ kGameStrings = 1
+};
+
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 400
+#define SCREEN_ORIG_HEIGHT 200
+#define MORT_DAT_REQUIRED_VERSION 1
+#define MORT_DAT "mort.dat"
+#define GAME_FRAME_DELAY (1000 / 50)
+
+const int kTime1 = 410;
+const int kTime2 = 250;
+
+const int kAcha = 492;
+const int kFleche = 1758;
+
+const int kAsoul = 154;
+const int kAouvr = 282;
+const int kAsearch = 387;
+const int kArcf = 1272;
+const int kArep = 1314;
+const int kAmzon = 1650;
+const int kArega = 0;
+
+const int kMaxDialogIndex = 9000;
+const int kMaxDialogHint = 600;
+
+const int kDescriptionStringIndex = 0; // Unused
+const int kInventoryStringIndex = 186;
+const int kQuestionStringIndex = 247;
+const int kDialogStringIndex = 292;
+const int kMenuPlaceStringIndex = 435;
+const int kMenuActionStringIndex = 476;
+const int kMenuSelfStringIndex = 497;
+const int kMenuSayStringIndex = 502;
+const int kMaxPatt = 20;
+
+const int kResolutionScaler = 2;
+/*
+9 "A glance at the forbidden$",
+18 "It's already open$",
+26 "A photograph$"
+*/
+enum Places {
+ OWN_ROOM = 0, GREEN_ROOM = 1, PURPLE_ROOM = 2, TOILETS = 3, DARKBLUE_ROOM = 4,
+ BLUE_ROOM = 5, RED_ROOM = 6, BATHROOM = 7, GREEN_ROOM2 = 8, JULIA_ROOM = 9,
+ DINING_ROOM = 10, BUREAU = 11, KITCHEN = 12, ATTIC = 13, CELLAR = 14,
+ LANDING = 15, CRYPT = 16, SECRET_PASSAGE = 17, ROOM18 = 18, MOUNTAIN = 19,
+ CHAPEL = 20, MANOR_FRONT = 21, MANOR_BACK = 22, INSIDE_WELL = 23, WELL = 24,
+ 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];
+ byte _availableQuestion[43];
+ byte _inventory[31];
+ int _currPlace;
+ int _atticBallHoleObjectId;
+ int _atticRodHoleObjectId;
+ int _cellarObjectId;
+ int _secretPassageObjectId;
+ int _wellObjectId;
+ int _selectedObjectId;
+ int _purpleRoomObjectId;
+ int _cryptObjectId;
+ bool _alreadyEnteredManor;
+ byte _fullHour;
+};
+
+struct Hint {
+ int _hintId;
+ byte _point;
+};
+
+struct MortevielleGameDescription;
+
+class MortevielleEngine : public Engine {
+private:
+ const MortevielleGameDescription *_gameDescription;
+ Common::Stack<int> _keypresses;
+ uint32 _lastGameFrame;
+ Common::Point _mousePos;
+ Common::StringArray _engineStrings;
+ Common::StringArray _gameStrings;
+
+ int _menuOpcode;
+
+ bool _inMainGameLoop; // Flag when the main game loop is active
+ bool _quitGame; // Quit game flag. Originally called 'arret'
+ bool _endGame; // End game flag. Originally called 'solu'
+ bool _loseGame; // Lose game flag. Originally called 'perdu'
+ bool _txxFileFl; // Flag used to determine if texts are from the original files or from a DAT file
+ bool _roomPresenceLuc;
+ bool _roomPresenceIda;
+ bool _purpleRoomPresenceLeo;
+ bool _roomPresenceGuy;
+ bool _roomPresenceEva;
+ bool _roomPresenceMax;
+ bool _roomPresenceBob;
+ bool _roomPresencePat;
+ bool _toiletsPresenceBobMax;
+ bool _bathRoomPresenceBobMax;
+ bool _juliaRoomPresenceLeo;
+ bool _hiddenHero;
+ bool _heroSearching;
+ bool _keyPressedEsc;
+ bool _reloadCFIEC;
+ bool _col;
+ bool _syn;
+ bool _obpart;
+ bool _anyone;
+ bool _uptodatePresence;
+
+ int _textColor;
+ int _place;
+ int _manorDistance;
+ int _currBitIndex;
+ int _currDay;
+ int _currHour;
+ int _currHalfHour;
+ int _day;
+ int _hour;
+ int _minute;
+ int _curSearchObjId;
+ int _controlMenu;
+ int _startTime;
+ int _endTime;
+ Common::Point _stdPal[91][17];
+
+ int _x26KeyCount;
+ int _roomDoorId;
+ int _openObjCount;
+ int _takeObjCount;
+ int _num;
+ int _searchCount;
+ bool _introSpeechPlayed;
+ int _inGameHourDuration;
+ int _x;
+ int _y;
+ int _currentHourCount;
+ int _currentTime;
+ int _pauseStartTime;
+
+ Common::String _hintPctMessage;
+ byte *_cfiecBuffer;
+ int _cfiecBufferSize;
+ int _openObjects[7];
+ uint16 _dialogIndexArray[kMaxDialogIndex + 1];
+ Hint _dialogHintArray[kMaxDialogHint + 1];
+
+ Common::ErrorCode initialize();
+ Common::ErrorCode loadMortDat();
+ void readStaticStrings(Common::File &f, int dataSize, DataType dataType);
+ void loadFont(Common::File &f);
+ bool handleEvents();
+ void addKeypress(Common::Event &evt);
+ void initMouse();
+ void showIntroduction();
+ void mainGame();
+ void playGame();
+ void handleAction();
+ void loadPalette();
+ void loadTexts();
+ void loadCFIEC();
+ void loadCFIPH();
+ void showTitleScreen();
+ int readclock();
+ void palette(int v1);
+ int checkLeoMaxRandomPresence();
+ void interactNPC();
+ void initCaveOrCellar();
+ void displayControlMenu();
+ void displayItemInHand(int objId);
+ void resetRoomVariables(int roomId);
+ int getPresenceStats(int &rand, int faithScore, int roomId);
+ void setPresenceFlags(int roomId);
+ void testKey(bool d);
+ void exitRoom();
+ void getReadDescription(int objId);
+ void getSearchDescription(int objId);
+ int checkLeaveSecretPassage();
+ void startDialog(int16 rep);
+ void endSearch();
+ int convertCharacterIndexToBitIndex(int characterIndex);
+ int convertBitIndexToCharacterIndex(int bitIndex);
+ void clearUpperLeftPart();
+ void clearDescriptionBar();
+ void clearVerbBar();
+ void clearUpperRightPart();
+ int getRandomNumber(int minval, int maxval);
+ void showMoveMenuAlert();
+ void showConfigScreen();
+ void decodeNumber(byte *pStart, int count);
+ void resetVariables();
+ void music();
+ void drawRightFrame();
+ void prepareRoom();
+ void drawClock();
+ void checkManorDistance();
+ void gotoManorFront();
+ void gotoManorBack();
+ void gotoDiningRoom();
+ bool checkInventory(int objectId);
+ void loseGame();
+ void floodedInWell();
+ void displayDiningRoom();
+ void startMusicOrSpeech(int so);
+ void setTextColor(int col);
+ void prepareScreenType1();
+ void prepareScreenType2();
+ void prepareScreenType3();
+ void updateHour(int &day, int &hour, int &minute);
+ void getKnockAnswer();
+ int getPresenceStatsGreenRoom();
+ int getPresenceStatsPurpleRoom();
+ int getPresenceStatsToilets();
+ int getPresenceStatsBlueRoom();
+ int getPresenceStatsRedRoom();
+ int getPresenceStatsDiningRoom(int &hour);
+ int getPresenceStatsBureau(int &hour);
+ int getPresenceStatsKitchen();
+ int getPresenceStatsAttic();
+ int getPresenceStatsLanding();
+ int getPresenceStatsChapel(int &hour);
+ int getPresenceBitIndex(int roomId);
+ void setPresenceGreenRoom(int roomId);
+ void setPresencePurpleRoom();
+ void setPresenceBlueRoom();
+ void setPresenceRedRoom(int roomId);
+ int setPresenceDiningRoom(int hour);
+ int setPresenceBureau(int hour);
+ int setPresenceKitchen();
+ int setPresenceLanding();
+ int setPresenceChapel(int hour);
+ void setRandomPresenceGreenRoom(int faithScore);
+ void setRandomPresencePurpleRoom(int faithScore);
+ void setRandomPresenceBlueRoom(int faithScore);
+ void setRandomPresenceRedRoom(int faithScore);
+ void setRandomPresenceJuliaRoom(int faithScore);
+ void setRandomPresenceDiningRoom(int faithScore);
+ void setRandomPresenceBureau(int faithScore);
+ void setRandomPresenceKitchen(int faithScore);
+ void setRandomPresenceAttic(int faithScore);
+ void setRandomPresenceLanding(int faithScore);
+ void setRandomPresenceChapel(int faithScore);
+ void loadPlaces();
+ void resetPresenceInRooms(int roomId);
+ void showPeoplePresent(int bitIndex);
+ int selectCharacters(int min, int max);
+ void fctMove();
+ void fctTake();
+ void fctInventoryTake();
+ void fctLift();
+ void fctRead();
+ void fctSelfRead();
+ void fctLook();
+ void fctSelftLook();
+ void fctSearch();
+ void fctSelfSearch();
+ void fctOpen();
+ void fctPlace();
+ void fctTurn();
+ void fctSelfHide();
+ void fctAttach();
+ void fctClose();
+ void fctKnock();
+ void fctSelfPut();
+ void fctListen();
+ void fctEat();
+ void fctEnter();
+ void fctSleep();
+ void fctForce();
+ void fctLeave();
+ void fctWait();
+ void fctSound();
+ void fctDiscuss();
+ void fctSmell();
+ void fctScratch();
+ void endGame();
+ void askRestart();
+ void handleOpcode();
+ void prepareDisplayText();
+ bool decryptNextChar(char &c, int &idx, byte &pt);
+ void displayStatusArrow();
+ void displayStatusInDescriptionBar(char stat);
+ void displayQuestionText(Common::String s, int cmd);
+ void displayTextInDescriptionBar(int x, int y, int nb, int mesgId);
+ void displayTextInVerbBar(Common::String text);
+ void displayTextBlock(Common::String text);
+ void mapMessageId(int &mesgId);
+ void resetOpenObjects();
+ void setCoordinates(int sx);
+ void drawPicture();
+ void drawPictureWithText();
+ void addObjectToInventory(int objectId);
+ void putInHand(int &objId);
+ void initMaxAnswer();
+ void displayAnimFrame(int frameNum, int animId);
+ int getFirstObject();
+ void prepareNextObject();
+ void putObject();
+ void resetObjectPlace();
+ void drawDiscussionBox();
+ void displayNarrativePicture(int af, int ob);
+ void menuUp();
+ void displayLookScreen(int objId);
+
+ void adzon();
+
+public:
+ Common::Point _prevPos;
+ int _currMenu;
+ int _currAction;
+ int _drawingSizeArr[108];
+ int _charAnswerCount[9];
+ int _charAnswerMax[9];
+ byte _tabdon[4001];
+ bool _soundOff;
+ bool _blo;
+ bool _destinationOk;
+ bool _largestClearScreen;
+ float _addFix;
+ int _savedBitIndex;
+ int _numpal;
+ int _key;
+ bool _mouseClick;
+ SaveStruct _coreVar, _saveStruct;
+
+ int _maff;
+ int _caff;
+ int _crep;
+
+ byte _destinationArray[7][25];
+
+ byte *_curPict;
+ 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;
+
+ MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc);
+ ~MortevielleEngine();
+ virtual bool hasFeature(EngineFeature f) const;
+ virtual bool canLoadGameStateCurrently();
+ virtual bool canSaveGameStateCurrently();
+ virtual Common::Error loadGameState(int slot);
+ 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;}
+ uint32 getGameFlags() const;
+ Common::Language getLanguage() const;
+ Common::Language getOriginalLanguage() const;
+ bool useOriginalData() const;
+ static Common::String generateSaveFilename(const Common::String &target, int slot);
+ Common::String generateSaveFilename(int slot) { return generateSaveFilename(_targetName, slot); }
+
+ int getChar();
+ bool keyPressed();
+ Common::Point getMousePos() const { return _mousePos; }
+ void setMousePos(const Common::Point &pt);
+ bool getMouseClick() const { return _mouseClick; }
+ void setMouseClick(bool v) { _mouseClick = v; }
+ Common::String getEngineString(int idx) const { return _engineStrings[idx]; }
+ Common::String getGameString(int idx) const { return _gameStrings[idx]; }
+
+ void delay(int amount);
+ void gameLoaded();
+ void initGame();
+ void displayAloneText();
+ void draw(int x, int y);
+ void charToHour();
+ void hourToChar();
+ Common::String getString(int num);
+ void setPal(int n);
+ Common::String copy(const Common::String &s, int idx, size_t size);
+ void testKeyboard();
+ int getPresence(int roomId);
+ void displayEmptyHand();
+ void displayPicture(const byte *pic, int x, int y);
+
+ int gettKeyPressed();
+ void handleDescriptionText(int f, int mesgId);
+ int getAnimOffset(int frameNum, int animNum);
+
+ void clearScreen();
+};
+
+extern MortevielleEngine *g_vm;
+
+} // End of namespace Mortevielle
+
+#endif
diff --git a/engines/mortevielle/mouse.cpp b/engines/mortevielle/mouse.cpp
new file mode 100644
index 0000000000..9eb4e129c0
--- /dev/null
+++ b/engines/mortevielle/mouse.cpp
@@ -0,0 +1,273 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/mouse.h"
+
+#include "common/endian.h"
+#include "common/rect.h"
+
+namespace Mortevielle {
+
+/**
+ * Initialize the mouse
+ * @remarks Originally called 'init_mouse'
+ */
+void MouseHandler::initMouse() {
+ _counter = 0;
+ _pos = Common::Point(0, 0);
+
+ _vm->setMouseClick(false);
+}
+
+/**
+ * Backs up the area behind where the mouse cursor is to be drawn
+ * @remarks Originally called 'hide_mouse'
+ */
+void MouseHandler::hideMouse() {
+ // No implementation needed in ScummVM
+}
+
+/**
+ * Draws the mouse cursor
+ * @remarks Originally called 'show_mouse'
+ */
+void MouseHandler::showMouse() {
+ // ScummVM implementation uses CursorMan for drawing the cursor
+}
+
+/**
+ * Set mouse position
+ * @remarks Originally called 'pos_mouse'
+ */
+void MouseHandler::setMousePosition(Common::Point newPos) {
+ if (newPos.x > 314 * kResolutionScaler)
+ newPos.x = 314 * kResolutionScaler;
+ else if (newPos.x < 0)
+ newPos.x = 0;
+ if (newPos.y > 199)
+ newPos.y = 199;
+ else if (newPos.y < 0)
+ newPos.y = 0;
+ if (newPos == _pos)
+ return;
+
+ // Set the new position
+ _vm->setMousePos(newPos);
+}
+
+/**
+ * Get mouse poisition
+ * @remarks Originally called 'read_pos_mouse'
+ */
+void MouseHandler::getMousePosition(int &x, int &y, bool &click) {
+ x = _vm->getMousePos().x;
+ y = _vm->getMousePos().y;
+ click = _vm->getMouseClick();
+}
+
+/**
+ * Move mouse
+ * @remarks Originally called 'mov_mouse'
+ */
+void MouseHandler::moveMouse(bool &funct, char &key) {
+ bool p_key;
+ char in1, in2;
+ int cx, cy;
+ bool click;
+
+ // Set defaults and check pending events
+ funct = false;
+ key = '\377';
+ p_key = _vm->keyPressed();
+
+ // If mouse button clicked, return it
+ if (_vm->getMouseClick())
+ return;
+
+ // Handle any pending keypresses
+ while (p_key) {
+ if (_vm->shouldQuit())
+ return;
+
+ in1 = _vm->getChar();
+ getMousePosition(cx, cy, click);
+ switch (toupper(in1)) {
+ case '4':
+ cx -= 8;
+ break;
+ case '2':
+ cy += 8;
+ break;
+ case '6':
+ cx += 8;
+ break;
+ case '8':
+ cy -= 8;
+ break;
+ case '7':
+ cy = 1;
+ cx = 1;
+ break;
+ case '1':
+ cx = 1;
+ cy = 190;
+ break;
+ case '9':
+ cx = 315 * kResolutionScaler;
+ cy = 1;
+ break;
+ case '3':
+ cy = 190;
+ cx = 315 * kResolutionScaler;
+ break;
+ case '5':
+ cy = 100;
+ cx = 155 * kResolutionScaler;
+ break;
+ case ' ':
+ case '\15':
+ _vm->setMouseClick(true);
+ return;
+ break;
+ case '\33':
+ p_key = _vm->keyPressed();
+
+ if (p_key) {
+ in2 = _vm->getChar();
+
+ if ((in2 >= ';') && (in2 <= 'D')) {
+ funct = true;
+ key = in2;
+ return;
+ } else {
+ switch (in2) {
+ case 'K':
+ --cx;
+ break;
+ case 'P':
+ ++cy;
+ break;
+ case 'M':
+ cx += 2;
+ break;
+ case 'H':
+ --cy;
+ break;
+ case 'G':
+ --cx;
+ --cy;
+ break;
+ case 'I':
+ ++cx;
+ --cy;
+ break;
+ case 'O':
+ --cx;
+ ++cy;
+ break;
+ case 'Q':
+ ++cx;
+ ++cy;
+ break;
+ default:
+ break;
+ } // case
+ }
+ }
+ break;
+ case 'I':
+ cx = kResolutionScaler * 32;
+ cy = 8;
+ break;
+ case 'D':
+ cx = 80 * kResolutionScaler;
+ cy = 8;
+ break;
+ case 'A':
+ cx = 126 * kResolutionScaler;
+ cy = 8;
+ break;
+ case 'S':
+ cx = 174 * kResolutionScaler;
+ cy = 8;
+ break;
+ case 'P':
+ cx = 222 * kResolutionScaler;
+ cy = 8;
+ break;
+ case 'F':
+ cx = kResolutionScaler * 270;
+ cy = 8;
+ break;
+ case '\23':
+ _vm->_soundOff = !_vm->_soundOff;
+ return;
+ break;
+ case '\24': // ^T => mode tandy
+ funct = true;
+ key = '\11';
+ break;
+ case '\10': // ^H => mode Hercule
+ funct = true;
+ key = '\7';
+ break;
+ case '\1':
+ case '\3':
+ case '\5':
+ funct = true;
+ key = in1;
+ break;
+ default:
+ break;
+ }
+
+ setMousePosition(Common::Point(cx, cy));
+ p_key = _vm->keyPressed();
+ }
+}
+
+/**
+ * Mouse function : Is mouse in a given rect?
+ * @remarks Originally called 'dans_rect'
+ */
+bool MouseHandler::isMouseIn(Common::Rect r) {
+ int x, y;
+ bool click;
+
+ getMousePosition(x, y, click);
+ if ((x > r.left) && (x < r.right) && (y > r.top) && (y < r.bottom))
+ return true;
+
+ 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
new file mode 100644
index 0000000000..1b9856e2c4
--- /dev/null
+++ b/engines/mortevielle/mouse.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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_MOUSE_H
+#define MORTEVIELLE_MOUSE_H
+
+#include "common/rect.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+class MouseHandler {
+private:
+ MortevielleEngine *_vm;
+
+ int s_s[12][6];
+ int _counter;
+public:
+ Common::Point _pos;
+
+ void setParent(MortevielleEngine *vm);
+ void initMouse();
+ void hideMouse();
+ void showMouse();
+ void setMousePosition(Common::Point newPos);
+ void getMousePosition(int &x, int &y, bool &click);
+ void moveMouse(bool &funct, char &key);
+ bool isMouseIn(Common::Rect r);
+};
+
+} // End of namespace Mortevielle
+#endif
diff --git a/engines/mortevielle/outtext.cpp b/engines/mortevielle/outtext.cpp
new file mode 100644
index 0000000000..d50f4005de
--- /dev/null
+++ b/engines/mortevielle/outtext.cpp
@@ -0,0 +1,308 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+#include "mortevielle/graphics.h"
+
+#include "common/file.h"
+#include "common/str.h"
+
+namespace Mortevielle {
+
+/**
+ * Next word
+ * @remarks Originally called 'l_motsuiv'
+ */
+int TextHandler::nextWord(int p, const char *ch, int &tab) {
+ int c = p;
+
+ while ((ch[p] != ' ') && (ch[p] != '$') && (ch[p] != '@'))
+ ++p;
+
+ return tab * (p - c);
+}
+
+/**
+ * Engine function - Display Text
+ * @remarks Originally called 'afftex'
+ */
+void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int dy, int typ) {
+ Common::String s;
+ int i, j;
+
+ // Safeguard: add $ just in case
+ inputStr += '$';
+
+ _vm->_screenSurface.putxy(x, y);
+ int tab = 6;
+ dx *= 6;
+ dy *= 6;
+ int xc = x;
+ int yc = y;
+ int xf = x + dx;
+ int yf = y + dy;
+ int p = 0;
+ bool stringParsed = (inputStr[p] == '$');
+ s = "";
+ while (!stringParsed) {
+ switch (inputStr[p]) {
+ case '@':
+ _vm->_screenSurface.drawString(s, typ);
+ s = "";
+ ++p;
+ xc = x;
+ yc += 6;
+ _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);
+ s = "";
+ xc = x;
+ yc += 6;
+ if (yc > yf) {
+ while (!_vm->keyPressed())
+ ;
+ i = y;
+ do {
+ j = x;
+ do {
+ _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);
+ }
+ break;
+ case '$':
+ stringParsed = true;
+ _vm->_screenSurface.drawString(s, typ);
+ break;
+ default:
+ s += inputStr[p];
+ ++p;
+ xc += tab;
+ break;
+ }
+ }
+}
+
+/**
+ * Load DES (picture container) file
+ * @remarks Originally called 'chardes'
+ */
+void TextHandler::loadPictureFile(Common::String filename, Common::String altFilename, int32 skipSize, int length) {
+ Common::File f;
+ if (!f.open(filename)) {
+ if (!f.open(altFilename))
+ error("Missing file: Either %s or %s", filename.c_str(), altFilename.c_str());
+ }
+ // HACK: The original game contains a bug in the 2nd intro screen, in German DOS version.
+ // The size specified in the fxx array is wrong (too short). In order to fix it, we are using
+ // the value -1 to force a variable read length.
+ if (length == -1)
+ length = f.size() - skipSize;
+
+ assert(skipSize + length <= f.size());
+
+ free(_vm->_curPict);
+ _vm->_curPict = (byte *)malloc(sizeof(byte) * length);
+ f.seek(skipSize);
+ f.read(_vm->_curPict, length);
+ f.close();
+}
+
+/**
+ * Load ANI file
+ * @remarks Originally called 'charani'
+ */
+void TextHandler::loadAniFile(Common::String filename, int32 skipSize, int length) {
+ Common::File f;
+ if (!f.open(filename))
+ error("Missing file - %s", filename.c_str());
+
+ assert(skipSize + length <= f.size());
+
+ free(_vm->_curAnim);
+ _vm->_curAnim = (byte *)malloc(sizeof(byte) * length);
+ f.seek(skipSize);
+ f.read(_vm->_curAnim, length);
+ f.close();
+}
+
+void TextHandler::taffich() {
+ static const byte tran1[] = { 121, 121, 138, 139, 120 };
+ static const byte tran2[] = { 150, 150, 152, 152, 100, 110, 159, 100, 100 };
+
+ int cx, drawingSize, npal;
+ int32 drawingStartPos;
+
+ int a = _vm->_caff;
+ if ((a >= 153) && (a <= 161))
+ a = tran2[a - 153];
+ else if ((a >= 136) && (a <= 140))
+ a = tran1[a - 136];
+ int b = a;
+ if (_vm->_maff == a)
+ return;
+
+ switch (a) {
+ case 16:
+ _vm->_coreVar._pctHintFound[9] = '*';
+ _vm->_coreVar._availableQuestion[42] = '*';
+ break;
+ case 20:
+ _vm->_coreVar._availableQuestion[39] = '*';
+ if (_vm->_coreVar._availableQuestion[36] == '*') {
+ _vm->_coreVar._pctHintFound[3] = '*';
+ _vm->_coreVar._availableQuestion[38] = '*';
+ }
+ break;
+ case 24:
+ _vm->_coreVar._availableQuestion[37] = '*';
+ break;
+ case 30:
+ _vm->_coreVar._availableQuestion[9] = '*';
+ break;
+ case 31: // Coat of arms
+ _vm->_coreVar._pctHintFound[4] = '*';
+ _vm->_coreVar._availableQuestion[35] = '*';
+ break;
+ case 118:
+ _vm->_coreVar._availableQuestion[41] = '*';
+ break;
+ case 143:
+ _vm->_coreVar._pctHintFound[1] = '*';
+ break;
+ case 150:
+ _vm->_coreVar._availableQuestion[34] = '*';
+ break;
+ case 151:
+ _vm->_coreVar._pctHintFound[2] = '*';
+ break;
+ default:
+ break;
+ }
+
+ _vm->_destinationOk = true;
+ _vm->_mouse.hideMouse();
+ drawingStartPos = 0;
+ Common::String filename, altFilename;
+
+ if ((a != 50) && (a != 51)) {
+ _vm->_maff = a;
+ if (a == 159)
+ a = 86;
+ else if (a > 140)
+ a -= 67;
+ else if (a > 137)
+ a -= 66;
+ else if (a > 99)
+ a -= 64;
+ else if (a > 69)
+ a -= 42;
+ else if (a > 29)
+ a -= 5;
+ else if (a == 26)
+ a = 24;
+ else if (a > 18)
+ --a;
+ npal = a;
+
+ for (cx = 0; cx <= (a - 1); ++cx)
+ drawingStartPos += _vm->_drawingSizeArr[cx];
+ drawingSize = _vm->_drawingSizeArr[a];
+
+ altFilename = filename = "DXX.mor";
+ } else {
+ filename = "DZZ.mor";
+ altFilename = "DZZALL";
+
+ if (a == 50) {
+ // First intro screen
+ drawingStartPos = 0;
+ drawingSize = _vm->_drawingSizeArr[87];
+ } else { // a == 51
+ // Second intro screen
+ drawingStartPos = _vm->_drawingSizeArr[87];
+ // HACK: Force a variable size in order to fix the wrong size used by the German version
+ drawingSize = -1;
+ }
+ _vm->_maff = a;
+ npal = a + 37;
+ }
+ loadPictureFile(filename, altFilename, drawingStartPos, drawingSize);
+ _vm->_numpal = npal;
+ _vm->setPal(npal);
+
+ if ((b < 15) || (b == 16) || (b == 17) || (b == 24) || (b == 26) || (b == 50)) {
+ drawingStartPos = 0;
+ if ((b < 15) || (b == 16) || (b == 17) || (b == 24) || (b == 26)) {
+ if (b == 26)
+ b = 18;
+ else if (b == 24)
+ b = 17;
+ else if (b > 15)
+ --b;
+ for (cx = 0; cx <= (b - 1); ++cx)
+ drawingStartPos += _vm->_drawingSizeArr[cx + 89];
+ drawingSize = _vm->_drawingSizeArr[b + 89];
+ filename = "AXX.mor";
+ } else { // b == 50
+ // CHECKME: the size of AZZ.mor is 1280 for the DOS version
+ // and 1260 for the Amiga version. Maybe the 20 bytes
+ // are a filler (to get 10 blocks of 128 bytes),
+ // or the size should be variable.
+ drawingSize = 1260;
+ filename = "AZZ.mor";
+ }
+ loadAniFile(filename, drawingStartPos, drawingSize);
+ }
+ _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)
+ _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
new file mode 100644
index 0000000000..44868036d5
--- /dev/null
+++ b/engines/mortevielle/outtext.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_OUTTEXT_H
+#define MORTEVIELLE_OUTTEXT_H
+
+#include "common/str.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+class TextHandler {
+private:
+ MortevielleEngine *_vm;
+ int nextWord(int p, const char *ch, int &tab);
+public:
+ void setParent(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);
+ void taffich();
+};
+
+} // End of namespace Mortevielle
+#endif
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
new file mode 100644
index 0000000000..c14a03cd60
--- /dev/null
+++ b/engines/mortevielle/saveload.cpp
@@ -0,0 +1,332 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/dialogs.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/saveload.h"
+
+#include "common/file.h"
+#include "common/system.h"
+
+namespace Mortevielle {
+
+static const char SAVEGAME_ID[4] = { 'M', 'O', 'R', 'T' };
+
+void SavegameManager::setParent(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
+/**
+ * Handle saving or loading savegame data
+ */
+void SavegameManager::sync_save(Common::Serializer &sz) {
+ sz.syncAsSint16LE(g_vm->_saveStruct._faithScore);
+ for (int i = 0; i < 11; ++i)
+ sz.syncAsByte(g_vm->_saveStruct._pctHintFound[i]);
+ for (int i = 0; i < 43; ++i)
+ sz.syncAsByte(g_vm->_saveStruct._availableQuestion[i]);
+ for (int i = 0; i < 31; ++i)
+ sz.syncAsByte(g_vm->_saveStruct._inventory[i]);
+
+ sz.syncAsSint16LE(g_vm->_saveStruct._currPlace);
+ sz.syncAsSint16LE(g_vm->_saveStruct._atticBallHoleObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._atticRodHoleObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._cellarObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._secretPassageObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._wellObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._selectedObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._purpleRoomObjectId);
+ sz.syncAsSint16LE(g_vm->_saveStruct._cryptObjectId);
+ sz.syncAsByte(g_vm->_saveStruct._alreadyEnteredManor);
+ sz.syncAsByte(g_vm->_saveStruct._fullHour);
+
+ sz.syncBytes(_tabdonSaveBuffer, 391);
+}
+
+/**
+ * Inner code for loading a saved game
+ * @remarks Originally called 'takesav'
+ */
+bool SavegameManager::loadSavegame(const Common::String &filename) {
+ // Try loading first from the save area
+ Common::SeekableReadStream *stream = g_system->getSavefileManager()->openForLoading(filename);
+
+ Common::File f;
+ if (stream == NULL) {
+ if (!f.open(filename)) {
+ warning("Unable to open save file '%s'", filename.c_str());
+ return false;
+ }
+ stream = f.readStream(f.size());
+ f.close();
+ }
+
+ // Check whether it's a ScummVM saved game
+ char buffer[4];
+ stream->read(buffer, 4);
+ if (!strncmp(&buffer[0], &SAVEGAME_ID[0], 4)) {
+ // Yes, it is, so skip over the savegame header
+ SavegameHeader header;
+ readSavegameHeader(stream, header);
+ delete header.thumbnail;
+ } else {
+ stream->seek(0);
+ }
+
+ // Read the game contents
+ Common::Serializer sz(stream, NULL);
+ sync_save(sz);
+
+ g_vm->_coreVar = g_vm->_saveStruct;
+ for (int i = 0; i <= 389; ++i)
+ g_vm->_tabdon[i + kAcha] = _tabdonSaveBuffer[i];
+
+ // Close the stream
+ delete stream;
+
+ return true;
+}
+
+/**
+ * Load a saved game
+ */
+Common::Error SavegameManager::loadGame(const Common::String &filename) {
+ g_vm->_mouse.hideMouse();
+ g_vm->displayEmptyHand();
+ if (loadSavegame(filename)) {
+ /* Initialization */
+ g_vm->charToHour();
+ g_vm->initGame();
+ g_vm->gameLoaded();
+ g_vm->_mouse.showMouse();
+ return Common::kNoError;
+ } else
+ return Common::kUnknownError;
+}
+
+/**
+ * Save the game
+ */
+Common::Error SavegameManager::saveGame(int n, const Common::String &saveName) {
+ Common::OutSaveFile *f;
+ int i;
+
+ g_vm->_mouse.hideMouse();
+ g_vm->hourToChar();
+
+ for (i = 0; i <= 389; ++i)
+ _tabdonSaveBuffer[i] = g_vm->_tabdon[i + kAcha];
+ g_vm->_saveStruct = g_vm->_coreVar;
+ if (g_vm->_saveStruct._currPlace == ROOM26)
+ g_vm->_saveStruct._currPlace = LANDING;
+
+ Common::String filename = _vm->generateSaveFilename(n);
+ f = g_system->getSavefileManager()->openForSaving(filename);
+
+ // Write out the savegame header
+ f->write(&SAVEGAME_ID[0], 4);
+
+ // Write out the header
+ SavegameHeader header;
+ writeSavegameHeader(f, saveName);
+
+ // Write out the savegame contents
+ Common::Serializer sz(NULL, f);
+ sync_save(sz);
+
+ // Close the save file
+ f->finalize();
+ delete f;
+
+ // Skipped: dialog asking to swap floppy
+
+ g_vm->_mouse.showMouse();
+ return Common::kNoError;
+}
+
+Common::Error SavegameManager::loadGame(int slot) {
+ return loadGame(_vm->generateSaveFilename(slot));
+}
+
+Common::Error SavegameManager::saveGame(int slot) {
+ return saveGame(slot, _vm->generateSaveFilename(slot));
+}
+
+void SavegameManager::writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName) {
+ // Write out a savegame header
+ out->writeByte(SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->writeString(saveName);
+ out->writeByte(0);
+
+ // Get the active palette
+ uint8 thumbPalette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
+
+ // 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));
+
+ ::createThumbnail(thumb, (const byte *)s.getPixels(), SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
+ Graphics::saveThumbnail(*out, *thumb);
+ thumb->free();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+}
+
+bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
+ header.thumbnail = NULL;
+
+ // Get the savegame version
+ header.version = in->readByte();
+
+ // 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;
+}
+
+SaveStateList SavegameManager::listSaves(const Common::String &target) {
+ Common::String pattern = target;
+ pattern += ".???";
+
+ Common::StringArray files = g_system->getSavefileManager()->listSavefiles(pattern);
+ sort(files.begin(), files.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = files.begin(); file != files.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ const Common::String &fname = *file;
+ int slotNumber = atoi(fname.c_str() + fname.size() - 3);
+
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fname);
+ if (in) {
+ // There can be two types of savegames: original interpreter savegames, and ScummVM savegames.
+ // Original interpreter savegames are 497 bytes, and still need to be supported because the
+ // initial game state is stored as a savegame
+ bool validFlag = false;
+ Common::String saveDescription;
+
+ char buffer[4];
+ in->read(buffer, 4);
+ if (!strncmp(&buffer[0], &SAVEGAME_ID[0], 4)) {
+ // ScummVm savegame. Read in the header to get the savegame name
+ SavegameHeader header;
+ validFlag = readSavegameHeader(in, header);
+
+ if (validFlag) {
+ delete header.thumbnail;
+ saveDescription = header.saveName;
+ }
+ } else if (file->size() == 497) {
+ // Form an appropriate savegame name
+ saveDescription = (slotNumber == 0) ? "Initial game state" :
+ Common::String::format("Savegame #%d", slotNumber);
+ validFlag = true;
+ }
+
+ if (validFlag)
+ // Got a valid savegame
+ saveList.push_back(SaveStateDescriptor(slotNumber, saveDescription));
+
+ delete in;
+ }
+ }
+
+ return saveList;
+}
+
+SaveStateDescriptor SavegameManager::querySaveMetaInfos(const Common::String &fileName) {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+
+ if (f) {
+ // Get the slot number
+ int slot = 1;
+ if (fileName.size() > 4 && fileName[fileName.size() - 4] == '.')
+ slot = atoi(fileName.c_str() + fileName.size() - 3);
+
+ // Check to see if it's a ScummVM savegame or not
+ char buffer[4];
+ f->read(buffer, 4);
+
+ bool hasHeader = !strncmp(&buffer[0], &SAVEGAME_ID[0], 4);
+
+ if (!hasHeader) {
+ // Original savegame perhaps?
+ delete f;
+
+ SaveStateDescriptor desc(slot, Common::String::format("Savegame - %03d", slot));
+ desc.setDeletableFlag(slot != 0);
+ desc.setWriteProtectedFlag(slot == 0);
+ return desc;
+ } else {
+ // Get the savegame header information
+ SavegameHeader header;
+ readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header.saveName);
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+ desc.setThumbnail(header.thumbnail);
+ desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
+ desc.setSaveTime(header.saveHour, header.saveMinutes);
+
+ return desc;
+ }
+ }
+
+ return SaveStateDescriptor();
+}
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
new file mode 100644
index 0000000000..79747e6889
--- /dev/null
+++ b/engines/mortevielle/saveload.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_SAVELOAD_H
+#define MORTEVIELLE_SAVELOAD_H
+
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "graphics/palette.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+
+#define SAVEGAME_VERSION 1
+
+namespace Mortevielle {
+
+struct SavegameHeader {
+ uint8 version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+ int saveYear, saveMonth, saveDay;
+ int saveHour, saveMinutes;
+ int totalFrames;
+};
+
+class MortevielleEngine;
+
+class SavegameManager {
+private:
+ MortevielleEngine *_vm;
+ byte _tabdonSaveBuffer[391];
+
+ void sync_save(Common::Serializer &sz);
+public:
+ void setParent(MortevielleEngine *vm);
+ bool loadSavegame(const Common::String &filename);
+ Common::Error loadGame(const Common::String &filename);
+ Common::Error saveGame(int n, const Common::String &saveName);
+ Common::Error loadGame(int slot);
+ Common::Error saveGame(int slot);
+
+ void writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName);
+ static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ static SaveStateList listSaves(const Common::String &target);
+ static SaveStateDescriptor querySaveMetaInfos(const Common::String &fileName);
+};
+
+} // End of namespace Mortevielle
+#endif
diff --git a/engines/mortevielle/sound.cpp b/engines/mortevielle/sound.cpp
new file mode 100644
index 0000000000..b670246726
--- /dev/null
+++ b/engines/mortevielle/sound.cpp
@@ -0,0 +1,800 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/sound.h"
+
+#include "audio/decoders/raw.h"
+#include "common/scummsys.h"
+
+namespace Mortevielle {
+
+ const byte _tnocon[364] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ const byte _intcon[26] = {1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0};
+ const byte _typcon[26] = {0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
+ 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) {
+ _mixer = mixer;
+ _audioStream = nullptr;
+ _ambiantNoiseBuf = nullptr;
+ _noiseBuf = nullptr;
+
+ _soundType = 0;
+ _phonemeNumb = 0;
+
+ for (int i = 0; i < 3; i++) {
+ _queue[i]._val = 0;
+ _queue[i]._code = 0;
+ _queue[i]._acc = 0;
+ _queue[i]._freq = 0;
+ _queue[i]._rep = 0;
+ }
+ _buildingSentence = false;
+}
+
+SoundManager::~SoundManager() {
+ if (_audioStream)
+ _audioStream->finish();
+ free(_ambiantNoiseBuf);
+ free(_noiseBuf);
+}
+
+/**
+ * Decode music data
+ */
+int SoundManager::decodeMusic(const byte *PSrc, byte *PDest, int size) {
+ static const int tab[16] = { -96, -72, -48, -32, -20, -12, -8, -4, 0, 4, 8, 12, 20, 32, 48, 72 };
+
+ uint seed = 128;
+ int v;
+ int decompSize = 0;
+ int skipSize = 0;
+
+ for (int idx1 = 0; idx1 < size; ++idx1) {
+ byte srcByte = *PSrc++;
+ v = tab[srcByte >> 4];
+ seed += v;
+ *PDest++ = seed & 0xff;
+
+ v = tab[srcByte & 0xf];
+ seed += v;
+ *PDest++ = seed & 0xff;
+
+ if (srcByte == 0)
+ skipSize += 2;
+ else {
+ decompSize += skipSize + 2;
+ skipSize = 0;
+ }
+ }
+ return decompSize;
+}
+
+/**
+ * Load sonmus.mor file
+ * @remarks Originally called 'charge_son'
+ */
+void SoundManager::loadAmbiantSounds() {
+ Common::File f;
+ if (!f.open("sonmus.mor"))
+ error("Missing file - sonmus.mor");
+
+ free(_ambiantNoiseBuf);
+ int size = f.size();
+ byte *compMusicBuf1 = (byte *)malloc(sizeof(byte) * size);
+ _ambiantNoiseBuf = (byte *)malloc(sizeof(byte) * size * 2);
+ f.read(compMusicBuf1, size);
+ f.close();
+
+ decodeMusic(compMusicBuf1, _ambiantNoiseBuf, size);
+ free(compMusicBuf1);
+}
+
+/**
+ * Speech function - Load Noise files
+ * @remarks Originally called 'charge_bruit' and 'charge_bruit5'
+ */
+void SoundManager::loadNoise() {
+ Common::File f1, f2;
+
+ if (!f1.open("bruits")) //Translation: "noise"
+ error("Missing file - bruits");
+ if (!f2.open("bruit5"))
+ error("Missing file - bruit5");
+
+ _noiseBuf = (byte *)malloc(sizeof(byte) * (f1.size() + f2.size()));
+ assert(f1.size() > 32000);
+
+ f1.read(_noiseBuf, 32000); // 250 * 128
+ f2.read(&_noiseBuf[32000], f2.size());
+ f1.read(&_noiseBuf[32000 + f2.size()], f1.size() - 32000); // 19072
+
+ f1.close();
+ f2.close();
+}
+
+void SoundManager::regenbruit() {
+ int i = 69876;
+ for (int j = 0; j < 100; j++) {
+ _cfiphBuffer[j] = READ_BE_UINT16(&_noiseBuf[i]);
+ i += 2;
+ }
+}
+
+void SoundManager::litph(tablint &t, int typ, int tempo) {
+ // Skip speech
+ if (_soundType == 0)
+ return;
+
+ if (!_buildingSentence) {
+ if (_mixer->isSoundHandleActive(_soundHandle))
+ _mixer->stopHandle(_soundHandle);
+ _buildingSentence = true;
+ }
+ int freq = tempo * 252; // 25.2 * 10
+ int i = 0;
+ while (i < _ptr_oct) {
+ int idx = _troctBuf[i];
+ i++;
+ switch(idx) {
+ case 0: {
+ int val = _troctBuf[i];
+ i++;
+ if (_soundType == 0)
+ warning("TODO: vclas");
+ else if (_soundType == 1) {
+ debugC(5, kMortevielleSounds, "litph - duson");
+ const static int noiseAdr[] = {0, 17224,
+ 17224, 33676,
+ 33676, 51014,
+ 51014, 59396,
+ 59396, 61286,
+ 61286, 69875};
+ if (val > 5) {
+ warning("unhandled index %d", val);
+ } else {
+ if (!_audioStream)
+ _audioStream = Audio::makeQueuingAudioStream(freq, false);
+ _audioStream->queueBuffer(&_noiseBuf[noiseAdr[val * 2]], noiseAdr[(val * 2) + 1] - noiseAdr[(val * 2)], DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ }
+ } else { // 2
+ debugC(5, kMortevielleSounds, "litph - vadson");
+ const static int ambiantNoiseAdr[] = {0, 14020,
+ 14020, 18994,
+ 18994, 19630,
+ 19630, 22258,
+ 22258, 37322,
+ 37322, 44472,
+ 44472, 52324,
+ 52324, 59598,
+ 59598, 69748};
+ if (val > 8) {
+ warning("unhandled index %d", val);
+ } else {
+ if (!_audioStream)
+ _audioStream = Audio::makeQueuingAudioStream(freq, false);
+ _audioStream->queueBuffer(&_ambiantNoiseBuf[ambiantNoiseAdr[val * 2]], ambiantNoiseAdr[(val * 2) + 1] - ambiantNoiseAdr[(val * 2)], DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ }
+ }
+ i++;
+ break;
+ }
+ case 2: {
+ int val = _troctBuf[i];
+ i++;
+ int tmpidx = (val * 12) + 268;
+ val = _troctBuf[i];
+ i++;
+ warning("TODO: reech %d %d", tmpidx, val);
+ }
+ break;
+ case 4:
+ if (_soundType) {
+ i += 2;
+ } else {
+ // Speech
+ warning("TODO: Interphoneme: consonne:%d voyelle:%d", _troctBuf[i], _troctBuf[i + 1]);
+ i += 2;
+ }
+ break;
+ case 6:
+ warning("TODO: pari2");
+ i += 2;
+ break;
+ default:
+ static byte emptyBuf[19] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ if (idx == 62)
+ warning("TODO: blab");
+ else if (idx == 32) {
+ if (!_audioStream)
+ _audioStream = Audio::makeQueuingAudioStream(freq, false);
+ _audioStream->queueBuffer(emptyBuf, 19, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ } else if (idx == 35) {
+ if (i < _ptr_oct)
+ warning("unexpected 35 - stop the buffering");
+ i = _ptr_oct;
+ } else if (idx == 46) {
+ if (!_audioStream)
+ _audioStream = Audio::makeQueuingAudioStream(freq, false);
+ for (int j = 0; j < 10; j++)
+ _audioStream->queueBuffer(emptyBuf, 19, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ } else {
+ warning("Other code: %d - %d %d", idx, _troctBuf[i], _troctBuf[i + 1]);
+ }
+ break;
+ }
+ }
+}
+
+void SoundManager::playSong(const byte* buf, uint size, uint loops) {
+ int freq = kTempoMusic * 252; // 25.2 * 10
+ Audio::SeekableAudioStream *raw = Audio::makeRawStream(buf, size, freq, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(raw, loops);
+ Audio::SoundHandle songHandle;
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &songHandle, stream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES);
+
+ while (_mixer->isSoundHandleActive(songHandle) && !_vm->keyPressed() && !_vm->_mouseClick && !_vm->shouldQuit())
+ ;
+ // In case the handle is still active, stop it.
+ _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)) {
+ if (((_queue[2]._code > 4) && (_queue[2]._val != 20) && (_queue[2]._rep != 3) && (_queue[2]._rep != 6) && (_queue[2]._rep != 9)) ||
+ ((_queue[2]._code < 5) && ((_queue[2]._val != 19) && (_queue[2]._val != 22) && (_queue[2]._rep != 4) && (_queue[2]._rep != 9)))) {
+ ++_queue[2]._rep;
+ }
+ }
+
+ _queue[2]._freq = ((uint)wor >> 6) & 7;
+ _queue[2]._acc = ((uint)wor >> 9) & 7;
+}
+
+void SoundManager::charg_car(int &currWordNumb) {
+ assert(currWordNumb < 1712);
+ int wor = READ_BE_UINT16(&_wordBuf[currWordNumb]);
+ int int_ = wor & 0x3f; // 63
+
+ if ((int_ >= 0) && (int_ <= 13)) {
+ _queue[2]._val = int_;
+ _queue[2]._code = 5;
+ } else if ((int_ >= 14) && (int_ <= 21)) {
+ _queue[2]._val = int_;
+ _queue[2]._code = 6;
+ } else if ((int_ >= 22) && (int_ <= 47)) {
+ int_ -= 22;
+ _queue[2]._val = int_;
+ _queue[2]._code = _typcon[int_];
+ } else if ((int_ >= 48) && (int_ <= 56)) {
+ _queue[2]._val = int_ - 22;
+ _queue[2]._code = 4;
+ } else {
+ switch (int_) {
+ case 60:
+ _queue[2]._val = 32; /* " " */
+ _queue[2]._code = 9;
+ break;
+ case 61:
+ _queue[2]._val = 46; /* "." */
+ _queue[2]._code = 9;
+ break;
+ case 62:
+ _queue[2]._val = 35; /* "#" */
+ _queue[2]._code = 9;
+ default:
+ break;
+ }
+ }
+
+ spfrac(wor);
+ currWordNumb += 2;
+}
+
+
+void SoundManager::entroct(byte o) {
+ assert(_ptr_oct < 10576);
+ _troctBuf[_ptr_oct] = o;
+ ++_ptr_oct;
+}
+
+void SoundManager::cctable(tablint &t) {
+ float tb[257];
+
+ tb[0] = 0;
+ for (int k = 0; k <= 255; ++k) {
+ tb[k + 1] = _vm->_addFix + tb[k];
+ t[255 - k] = abs((int)tb[k] + 1);
+ }
+}
+
+/**
+ * Load phoneme sound file
+ * @remarks Originally called 'charge_phbruit'
+ */
+void SoundManager::loadPhonemeSounds() {
+ Common::File f;
+
+ if (!f.open("phbrui.mor"))
+ error("Missing file - phbrui.mor");
+
+ for (int i = 1; i <= f.size() / 2; ++i)
+ _cfiphBuffer[i] = f.readUint16BE();
+
+ f.close();
+}
+
+void SoundManager::trait_car() {
+ byte d3;
+ int d2, i;
+
+ switch (_queue[1]._code) {
+ case 9:
+ if (_queue[1]._val != (int)'#') {
+ for (i = 0; i <= _queue[1]._rep; ++i)
+ entroct(_queue[1]._val);
+ }
+ break;
+ case 5:
+ case 6:
+ if (_queue[1]._code == 6)
+ d3 = _tabdph[(_queue[1]._val - 14) << 1];
+ else
+ d3 = kNullValue;
+ if (_queue[0]._code >= 5) {
+ if (_queue[0]._code == 9) {
+ entroct(4);
+ if (d3 == kNullValue)
+ entroct(_queue[1]._val);
+ else
+ entroct(d3);
+ entroct(22);
+ }
+ }
+
+ switch (_queue[1]._rep) {
+ case 0:
+ entroct(0);
+ entroct(_queue[1]._val);
+ if (d3 == kNullValue)
+ if (_queue[2]._code == 9)
+ entroct(2);
+ else
+ entroct(4);
+ else if (_queue[2]._code == 9)
+ entroct(0);
+ else
+ entroct(1);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ if (_queue[1]._rep != 4) {
+ i = _queue[1]._rep - 5;
+ do {
+ --i;
+ entroct(0);
+ if (d3 == kNullValue)
+ entroct(_queue[1]._val);
+ else
+ entroct(d3);
+ entroct(3);
+ } while (i >= 0);
+ }
+ if (d3 == kNullValue) {
+ entroct(4);
+ entroct(_queue[1]._val);
+ entroct(0);
+ } else {
+ entroct(0);
+ entroct(_queue[1]._val);
+ entroct(3);
+ }
+
+ break;
+ case 7:
+ case 8:
+ case 9:
+ if (_queue[1]._rep != 7) {
+ i = _queue[1]._rep - 8;
+ do {
+ --i;
+ entroct(0);
+ if (d3 == kNullValue)
+ entroct(_queue[1]._val);
+ else
+ entroct(d3);
+ entroct(3);
+ } while (i >= 0);
+ }
+ if (d3 == kNullValue) {
+ entroct(0);
+ entroct(_queue[1]._val);
+ entroct(2);
+ } else {
+ entroct(0);
+ entroct(_queue[1]._val);
+ entroct(0);
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ if (_queue[1]._rep != 1) {
+ i = _queue[1]._rep - 2;
+ do {
+ --i;
+ entroct(0);
+ if (d3 == kNullValue)
+ entroct(_queue[1]._val);
+ else
+ entroct(d3);
+ entroct(3);
+ } while (i >= 0);
+ }
+ entroct(0);
+ entroct(_queue[1]._val);
+ if (_queue[2]._code == 9)
+ entroct(0);
+ else
+ entroct(1);
+
+ break;
+ default:
+ break;
+ } // switch c2.rep
+ break;
+
+ case 2:
+ case 3:
+ d3 = _queue[1]._code + 5; // 7 ou 8 => Corresponding vowel
+ if (_queue[0]._code > 4) {
+ if (_queue[0]._code == 9) {
+ entroct(4);
+ entroct(d3);
+ entroct(22);
+ }
+ }
+ i = _queue[1]._rep;
+ assert(i >= 0);
+ if (i != 0) {
+ do {
+ --i;
+ entroct(0);
+ entroct(d3);
+ entroct(3);
+ } while (i > 0);
+ }
+ if (_queue[2]._code == 6) {
+ entroct(4);
+ entroct(_tabdph[(_queue[2]._val - 14) << 1]);
+ entroct(_queue[1]._val);
+ } else {
+ entroct(4);
+ if (_queue[2]._val == 4)
+ entroct(3);
+ else
+ entroct(_queue[2]._val);
+ entroct(_queue[1]._val);
+ }
+ break;
+ case 0:
+ case 1:
+ switch (_queue[2]._code) {
+ case 2:
+ d2 = 7;
+ break;
+ case 3:
+ d2 = 8;
+ break;
+ case 6:
+ d2 = _tabdph[(_queue[2]._val - 14) << 1];
+ break;
+ case 5:
+ d2 = _queue[2]._val;
+ break;
+ default:
+ d2 = 10;
+ break;
+ } // switch c3._code
+ d2 = (d2 * 26) + _queue[1]._val;
+ if (_tnocon[d2] == 0)
+ d3 = 2;
+ else
+ d3 = 6;
+ if (_queue[1]._rep >= 5) {
+ _queue[1]._rep -= 5;
+ d3 = 8 - d3; // Swap 2 and 6
+ }
+ if (_queue[1]._code == 0) {
+ i = _queue[1]._rep;
+ if (i != 0) {
+ do {
+ --i;
+ entroct(d3);
+ entroct(_queue[1]._val);
+ entroct(3);
+ } while (i > 0);
+ }
+ entroct(d3);
+ entroct(_queue[1]._val);
+ entroct(4);
+ } else {
+ entroct(d3);
+ entroct(_queue[1]._val);
+ entroct(3);
+ i = _queue[1]._rep;
+ if (i != 0) {
+ do {
+ --i;
+ entroct(d3);
+ entroct(_queue[1]._val);
+ entroct(4);
+ } while (i > 0);
+ }
+ }
+ if (_queue[2]._code == 9) {
+ entroct(d3);
+ entroct(_queue[1]._val);
+ entroct(5);
+ } else if ((_queue[2]._code != 0) && (_queue[2]._code != 1) && (_queue[2]._code != 4)) {
+ switch (_queue[2]._code) {
+ case 3:
+ d2 = 8;
+ break;
+ case 6:
+ d2 = _tabdph[(_queue[2]._val - 14) << 1];
+ break;
+ case 5:
+ d2 = _queue[2]._val;
+ break;
+ default:
+ d2 = 7;
+ break;
+ } // switch c3._code
+ if (d2 == 4)
+ d2 = 3;
+
+ if (_intcon[_queue[1]._val] != 0)
+ ++_queue[1]._val;
+
+ if ((_queue[1]._val == 17) || (_queue[1]._val == 18))
+ _queue[1]._val = 16;
+
+ entroct(4);
+ entroct(d2);
+ entroct(_queue[1]._val);
+ }
+
+ break;
+ case 4:
+ i = _queue[1]._rep;
+ if (i != 0) {
+ do {
+ --i;
+ entroct(2);
+ entroct(_queue[1]._val);
+ entroct(3);
+ } while (i > 0);
+ }
+ entroct(2);
+ entroct(_queue[1]._val);
+ entroct(4);
+ if (_queue[2]._code == 9) {
+ entroct(2);
+ entroct(_queue[1]._val);
+ entroct(5);
+ } else if ((_queue[2]._code != 0) && (_queue[2]._code != 1) && (_queue[2]._code != 4)) {
+ switch (_queue[2]._code) {
+ case 3:
+ d2 = 8;
+ break;
+ case 6:
+ d2 = _tabdph[(_queue[2]._val - 14) << 1];
+ break;
+ case 5:
+ d2 = _queue[2]._val;
+ break;
+ default:
+ d2 = 7;
+ break;
+ } // switch c3._code
+
+ if (d2 == 4)
+ d2 = 3;
+
+ if (_intcon[_queue[1]._val] != 0)
+ ++_queue[1]._val;
+
+ entroct(4);
+ entroct(d2);
+ entroct(_tabdbc[((_queue[1]._val - 26) << 1) + 1]);
+ }
+
+ break;
+ default:
+ break;
+ } // switch c2.code
+}
+
+/**
+ * Make the queue evolve by 1 value
+ * @remarks Originally called 'rot_chariot'
+ */
+void SoundManager::moveQueue() {
+ _queue[0] = _queue[1];
+ _queue[1] = _queue[2];
+ _queue[2]._val = 32;
+ _queue[2]._code = 9;
+}
+
+/**
+ * initialize the queue
+ * @remarks Originally called 'init_chariot'
+ */
+void SoundManager::initQueue() {
+ _queue[2]._rep = 0;
+ _queue[2]._freq = 0;
+ _queue[2]._acc = 0;
+ moveQueue();
+ moveQueue();
+}
+
+/**
+ * Handle a phoneme
+ * @remarks Originally called 'trait_ph'
+ */
+void SoundManager::handlePhoneme() {
+ const uint16 deca[3] = {300, 30, 40};
+
+ uint16 startPos = _cfiphBuffer[_phonemeNumb - 1] + deca[_soundType];
+ uint16 endPos = _cfiphBuffer[_phonemeNumb] + deca[_soundType];
+ int wordCount = endPos - startPos;
+
+ startPos /= 2;
+ endPos /= 2;
+ assert((endPos - startPos) < 1711);
+ for (int i = startPos, currWord = 0; i < endPos; i++, currWord += 2)
+ WRITE_BE_UINT16(&_wordBuf[currWord], _cfiphBuffer[i]);
+
+ _ptr_oct = 0;
+ int currWord = 0;
+ initQueue();
+
+ do {
+ moveQueue();
+ charg_car(currWord);
+ trait_car();
+ } while (currWord < wordCount);
+
+ moveQueue();
+ trait_car();
+ entroct((int)'#');
+
+#ifdef DEBUG
+ warning("---");
+ for (int i = 0; i < _ptr_oct; ) {
+ if ((_troctBuf[i] == 32) || (_troctBuf[i] == 35) || (_troctBuf[i] == 46)) {
+ warning("%d", _troctBuf[i]);
+ i++;
+ } else {
+ warning("%d %d %d", _troctBuf[i], _troctBuf[i + 1], _troctBuf[i + 1]);
+ i += 3;
+ }
+ }
+ warning("---");
+#endif
+}
+
+/**
+ * Start speech
+ * @remarks Originally called 'parole'
+ */
+void SoundManager::startSpeech(int rep, int ht, int typ) {
+ uint16 savph[501];
+ int tempo;
+
+ // Hack to avoid a crash in the ending version. To be removed when the speech are implemented
+ if ((rep == 141) && (typ == 0))
+ return;
+
+ if (_vm->_soundOff)
+ return;
+
+ _phonemeNumb = rep;
+ int haut = ht;
+ _soundType = typ;
+ if (_soundType != 0) {
+ for (int i = 0; i <= 500; ++i)
+ savph[i] = _cfiphBuffer[i];
+ tempo = kTempoNoise;
+ } else if (haut > 5)
+ tempo = kTempoF;
+ else
+ tempo = kTempoM;
+ _vm->_addFix = (float)((tempo - 8)) / 256;
+ cctable(_tbi);
+ switch (typ) {
+ case 1:
+ regenbruit();
+ break;
+ case 2:
+ loadPhonemeSounds();
+ break;
+ default:
+ break;
+ }
+ handlePhoneme();
+ litph(_tbi, typ, tempo);
+
+ _buildingSentence = false;
+ if (typ != 0) {
+ _audioStream->finish();
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream);
+ _audioStream = nullptr;
+ }
+
+ if (_soundType != 0) {
+ for (int i = 0; i <= 500; ++i)
+ _cfiphBuffer[i] = savph[i];
+ }
+ _vm->setPal(_vm->_numpal);
+}
+
+void SoundManager::waitSpeech() {
+ while (_mixer->isSoundHandleActive(_soundHandle) && !_vm->keyPressed() && !_vm->_mouseClick && !_vm->shouldQuit())
+ ;
+ // In case the handle is still active, stop it.
+ _mixer->stopHandle(_soundHandle);
+
+ if (!_vm->keyPressed() && !_vm->_mouseClick && !_vm->shouldQuit())
+ g_system->delayMillis(600);
+}
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/sound.h b/engines/mortevielle/sound.h
new file mode 100644
index 0000000000..cc0567fd98
--- /dev/null
+++ b/engines/mortevielle/sound.h
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#ifndef MORTEVIELLE_SOUND_H
+#define MORTEVIELLE_SOUND_H
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "common/mutex.h"
+#include "common/queue.h"
+
+namespace Mortevielle {
+class MortevielleEngine;
+
+const int kNullValue = 255;
+const int kTempoMusic = 71;
+const int kTempoNoise = 78;
+const int kTempoF = 80;
+const int kTempoM = 89;
+
+struct SpeechQueue {
+ int _val;
+ int _code;
+ int _acc;
+ int _freq;
+ int _rep;
+};
+
+typedef int tablint[256];
+
+class SoundManager {
+private:
+ MortevielleEngine *_vm;
+
+ byte *_ambiantNoiseBuf;
+ byte *_noiseBuf;
+ int _phonemeNumb;
+ int _soundType;
+ SpeechQueue _queue[3];
+ byte _wordBuf[1712];
+ byte _troctBuf[10576];
+ bool _buildingSentence;
+ int _ptr_oct;
+ int _tbi[256];
+
+ Audio::QueuingAudioStream *_audioStream;
+
+ void loadPhonemeSounds();
+ void moveQueue();
+ void initQueue();
+ void handlePhoneme();
+
+ void spfrac(int wor);
+ void charg_car(int &currWordNumb);
+ void entroct(byte o);
+ void cctable(tablint &t);
+ void trait_car();
+
+ void regenbruit();
+ void litph(tablint &t, int typ, int tempo);
+
+public:
+ SoundManager(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();
+ void loadNoise();
+ void startSpeech(int rep, int ht, int typ);
+ void waitSpeech();
+};
+
+} // End of namespace Mortevielle
+
+#endif
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
new file mode 100644
index 0000000000..7809143176
--- /dev/null
+++ b/engines/mortevielle/utils.cpp
@@ -0,0 +1,3404 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "mortevielle/mortevielle.h"
+
+#include "mortevielle/dialogs.h"
+#include "mortevielle/menu.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+
+#include "common/scummsys.h"
+#include "graphics/cursorman.h"
+
+namespace Mortevielle {
+
+/**
+ * Check is a key was pressed
+ * It also delays the engine and check if the screen has to be updated
+ * @remarks Originally called 'keypressed'
+ */
+bool MortevielleEngine::keyPressed() {
+ // Check for any pending key presses
+ handleEvents();
+
+ // Check if it's time to draw the next frame
+ if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
+ _lastGameFrame = g_system->getMillis();
+
+ _screenSurface.updateScreen();
+
+ _debugger.onFrame();
+ }
+
+ // Delay briefly to keep CPU usage down
+ g_system->delayMillis(5);
+
+ // Return if there are any pending key presses
+ return !_keypresses.empty();
+}
+
+/**
+ * Wait for a keypress
+ * @remarks Originally called 'get_ch'
+ */
+int MortevielleEngine::getChar() {
+ bool end = false;
+ // If there isn't any pending keypress, wait until there is
+ while (!shouldQuit() && !end) {
+ end = keyPressed();
+ }
+
+ // Return the top keypress
+ return shouldQuit() ? 0 : _keypresses.pop();
+}
+
+/**
+ * Handle pending events
+ * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
+ * the mouse Y position is divided by 2 to keep the game thinking the Y goes from 0 - 199
+ */
+bool MortevielleEngine::handleEvents() {
+ Common::Event event;
+ if (!g_system->getEventManager()->pollEvent(event))
+ return false;
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ 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;
+
+ if (event.type == Common::EVENT_LBUTTONDOWN)
+ _mouseClick = true;
+ else if (event.type == Common::EVENT_LBUTTONUP)
+ _mouseClick = false;
+
+ break;
+ case Common::EVENT_KEYDOWN:
+ addKeypress(event);
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Add the specified key to the pending keypress stack
+ */
+void MortevielleEngine::addKeypress(Common::Event &evt) {
+ // Character to add
+ char ch = evt.kbd.ascii;
+
+ // Check for debugger
+ if ((evt.kbd.keycode == Common::KEYCODE_d) && (evt.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _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))
+ ch = evt.kbd.keycode - Common::KEYCODE_a + 1;
+ else
+ ch = evt.kbd.keycode - Common::KEYCODE_a + 'A';
+ } else if ((evt.kbd.keycode >= Common::KEYCODE_F1) && (evt.kbd.keycode <= Common::KEYCODE_F12)) {
+ // Handle function keys
+ ch = 59 + evt.kbd.keycode - Common::KEYCODE_F1;
+ } else {
+ // Series of special cases
+ switch (evt.kbd.keycode) {
+ case Common::KEYCODE_KP4:
+ case Common::KEYCODE_LEFT:
+ ch = '4';
+ break;
+ case Common::KEYCODE_KP2:
+ case Common::KEYCODE_DOWN:
+ ch = '2';
+ break;
+ case Common::KEYCODE_KP6:
+ case Common::KEYCODE_RIGHT:
+ ch = '6';
+ break;
+ case Common::KEYCODE_KP8:
+ case Common::KEYCODE_UP:
+ ch = '8';
+ break;
+ case Common::KEYCODE_KP7:
+ ch = '7';
+ break;
+ case Common::KEYCODE_KP1:
+ ch = '1';
+ break;
+ case Common::KEYCODE_KP9:
+ ch = '9';
+ break;
+ case Common::KEYCODE_KP3:
+ ch = '3';
+ break;
+ case Common::KEYCODE_KP5:
+ ch = '5';
+ break;
+ case Common::KEYCODE_RETURN:
+ ch = '\13';
+ break;
+ case Common::KEYCODE_ESCAPE:
+ ch = '\33';
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ch != 0)
+ _keypresses.push(ch);
+}
+
+
+static const byte CURSOR_ARROW_DATA[16 * 16] = {
+ 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/**
+ * Initialize the mouse
+ */
+void MortevielleEngine::initMouse() {
+ CursorMan.replaceCursor(CURSOR_ARROW_DATA, 16, 16, 0, 0, 0xff);
+ CursorMan.showMouse(true);
+
+ _mouse.initMouse();
+}
+
+/**
+ * Sets the mouse position
+ * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
+ * the mouse Y position is doubled to convert from 0-199 to 0-399
+ */
+void MortevielleEngine::setMousePos(const Common::Point &pt) {
+ // Adjust the passed position from simulated 640x200 to 640x400 co-ordinates
+ Common::Point newPoint(pt.x, (pt.y == 199) ? 399 : pt.y * 2);
+
+ if (newPoint != _mousePos)
+ // Warp the mouse to the new position
+ g_system->warpMouse(newPoint.x, newPoint.y);
+
+ // Save the new position
+ _mousePos = newPoint;
+}
+
+/**
+ * Delay by a given amount
+ */
+void MortevielleEngine::delay(int amount) {
+ uint32 endTime = g_system->getMillis() + amount;
+
+ while (g_system->getMillis() < endTime) {
+ if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
+ _lastGameFrame = g_system->getMillis();
+ _screenSurface.updateScreen();
+
+ _debugger.onFrame();
+ }
+
+ g_system->delayMillis(10);
+ }
+}
+
+/**
+ * Waits for the user to select an action, and then handles it
+ * @remarks Originally called tecran
+ */
+void MortevielleEngine::handleAction() {
+ const int lim = 20000;
+ int temps = 0;
+ char inkey = '\0';
+ bool funct = false;
+
+ clearVerbBar();
+
+ bool handledOpcodeFl = false;
+ _controlMenu = 0;
+ if (!_keyPressedEsc) {
+ _menu.drawMenu();
+ _menu._menuDisplayed = true;
+ temps = 0;
+ _key = 0;
+ funct = false;
+ inkey = '.';
+
+ _inMainGameLoop = true;
+ do {
+ _menu.updateMenu();
+ prepareRoom();
+ _mouse.moveMouse(funct, inkey);
+ if (shouldQuit())
+ return;
+ ++temps;
+ if (keyPressed() || _mouseClick) {
+ _soundManager._mixer->stopHandle(_soundManager._soundHandle);
+ }
+ } while (!((_menu._menuSelected) || (temps > lim) || (funct) || (_anyone)));
+ _inMainGameLoop = false;
+
+ _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);
+ }
+ if (_menu._menuSelected && (_currMenu == MENU_LOAD))
+ _savegameManager.loadGame((_currAction & 15) - 1);
+ if (inkey == '\103') { /* F9 */
+ temps = _dialogManager.show(_hintPctMessage);
+ return;
+ } else if (inkey == '\77') {
+ if ((_menuOpcode != OPCODE_NONE) && ((_currMenu == MENU_ACTION) || (_currMenu == MENU_SELF))) {
+ _currAction = _menuOpcode;
+ displayTextInVerbBar(getEngineString(S_IDEM));
+ } else
+ return;
+ } else if (inkey == '\104') {
+ if ((_x != 0) && (_y != 0))
+ _num = 9999;
+ return;
+ }
+ }
+ if (inkey == '\73') {
+ _quitGame = true;
+ hourToChar();
+ } else {
+ if ((funct) && (inkey != '\77'))
+ return;
+ if (temps > lim) {
+ handleDescriptionText(2, 141);
+ if (_num == 9999)
+ _num = 0;
+ } else {
+ _menuOpcode = _currMenu;
+ if ((_currMenu == MENU_ACTION) || (_currMenu == MENU_SELF))
+ _menuOpcode = _currAction;
+ if (!_anyone) {
+ if ((_heroSearching) || (_obpart)) {
+ if (_mouse._pos.y < 12)
+ return;
+
+ if ((_currAction == _menu._opcodeSound) || (_currAction == _menu._opcodeLift)) {
+ handledOpcodeFl = true;
+ if ((_currAction == _menu._opcodeLift) || (_obpart)) {
+ endSearch();
+ _caff = _coreVar._currPlace;
+ _crep = 998;
+ } else
+ prepareNextObject();
+ menuUp();
+ }
+ }
+ }
+ do {
+ if (!handledOpcodeFl)
+ handleOpcode();
+
+ if ((_controlMenu == 0) && (! _loseGame) && (! _endGame)) {
+ _text.taffich();
+ if (_destinationOk) {
+ _destinationOk = false;
+ drawPicture();
+ }
+ if ((!_syn) || (_col))
+ handleDescriptionText(2, _crep);
+ }
+ } while (_syn);
+ if (_controlMenu != 0)
+ displayControlMenu();
+ }
+ }
+}
+
+/**
+ * Engine function - Init Places
+ * @remarks Originally called 'init_lieu'
+ */
+void MortevielleEngine::loadPlaces() {
+ Common::File f;
+
+ if (!f.open("MXX.mor"))
+ if (!f.open("MFXX.mor"))
+ error("Missing file - MXX.mor");
+
+ for (int i = 0; i < 7; ++i) {
+ for (int j = 0; j < 25; ++j)
+ _destinationArray[i][j] = f.readByte();
+ }
+
+ f.close();
+}
+
+/**
+ * Set Text Color
+ * @remarks Originally called 'text_color'
+ */
+void MortevielleEngine::setTextColor(int col) {
+ _textColor = col;
+}
+
+/**
+ * Prepare screen - Type 1!
+ * @remarks Originally called 'ecrf1'
+ */
+void MortevielleEngine::prepareScreenType1() {
+ // Large drawing
+ _screenSurface.drawBox(0, 11, 512, 164, 15);
+}
+
+/**
+ * Prepare room - Type 2!
+ * @remarks Originally called 'ecrf2'
+ */
+void MortevielleEngine::prepareScreenType2() {
+ setTextColor(5);
+}
+
+/**
+ * Prepare room - Type 3!
+ * @remarks Originally called 'ecrf7'
+ */
+void MortevielleEngine::prepareScreenType3() {
+ setTextColor(4);
+}
+
+/**
+ * Engine function - Update hour
+ * @remarks Originally called 'calch'
+ */
+void MortevielleEngine::updateHour(int &day, int &hour, int &minute) {
+ int newTime = readclock();
+ int th = _currentHourCount + ((newTime - _currentTime) / _inGameHourDuration);
+ minute = ((th % 2) + _currHalfHour) * 30;
+ hour = ((uint)th >> 1) + _currHour;
+ if (minute == 60) {
+ minute = 0;
+ ++hour;
+ }
+ day = (hour / 24) + _currDay;
+ hour = hour - ((day - _currDay) * 24);
+}
+
+/**
+ * Engine function - Convert character index to bit index
+ * @remarks Originally called 'conv'
+ */
+int MortevielleEngine::convertCharacterIndexToBitIndex(int characterIndex) {
+ return 128 >> (characterIndex - 1);
+}
+
+/**
+ * Engine function - Convert bit index to character index
+ * @remarks Originally called 'tip'
+ */
+int MortevielleEngine::convertBitIndexToCharacterIndex(int bitIndex) {
+ int retVal = 0;
+
+ if (bitIndex == 128)
+ retVal = 1;
+ else if (bitIndex == 64)
+ retVal = 2;
+ else if (bitIndex == 32)
+ retVal = 3;
+ else if (bitIndex == 16)
+ retVal = 4;
+ else if (bitIndex == 8)
+ retVal = 5;
+ else if (bitIndex == 4)
+ retVal = 6;
+ else if (bitIndex == 2)
+ retVal = 7;
+ else if (bitIndex == 1)
+ retVal = 8;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Reset presence in other rooms
+ * @remarks Originally called 't5'
+ */
+void MortevielleEngine::resetPresenceInRooms(int roomId) {
+ if (roomId == DINING_ROOM)
+ _blo = false;
+
+ if (roomId != GREEN_ROOM) {
+ _roomPresenceLuc = false;
+ _roomPresenceIda = false;
+ }
+
+ if (roomId != PURPLE_ROOM)
+ _purpleRoomPresenceLeo = false;
+
+ if (roomId != DARKBLUE_ROOM) {
+ _roomPresenceGuy = false;
+ _roomPresenceEva = false;
+ }
+
+ if (roomId != BLUE_ROOM)
+ _roomPresenceMax = false;
+ if (roomId != RED_ROOM)
+ _roomPresenceBob = false;
+ if (roomId != GREEN_ROOM2)
+ _roomPresencePat = false;
+ if (roomId != TOILETS)
+ _toiletsPresenceBobMax = false;
+ if (roomId != BATHROOM)
+ _bathRoomPresenceBobMax = false;
+ if (roomId != JULIA_ROOM)
+ _juliaRoomPresenceLeo = false;
+}
+
+/**
+ * Engine function - Show the people present in the given room
+ * @remarks Originally called 'affper'
+ */
+void MortevielleEngine::showPeoplePresent(int bitIndex) {
+ int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
+
+ for (int i = 1; i <= 8; ++i)
+ _menu.disableMenuItem(_menu._discussMenu[i]);
+
+ clearUpperRightPart();
+ if ((bitIndex & 128) == 128) {
+ _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]);
+ }
+ if ((bitIndex & 32) == 32) {
+ _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]);
+ }
+ if ((bitIndex & 8) == 8) {
+ _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]);
+ }
+ if ((bitIndex & 2) == 2) {
+ _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]);
+ }
+ _currBitIndex = bitIndex;
+}
+
+/**
+ * Engine function - Select random characters
+ * @remarks Originally called 'choix'
+ */
+int MortevielleEngine::selectCharacters(int min, int max) {
+ bool invertSelection = false;
+ int rand = getRandomNumber(min, max);
+
+ if (rand > 4) {
+ rand = 8 - rand;
+ invertSelection = true;
+ }
+
+ int i = 0;
+ int retVal = 0;
+ while (i < rand) {
+ int charIndex = getRandomNumber(1, 8);
+ int charBitIndex = convertCharacterIndexToBitIndex(charIndex);
+ if ((retVal & charBitIndex) != charBitIndex) {
+ ++i;
+ retVal |= charBitIndex;
+ }
+ }
+ if (invertSelection)
+ retVal = 255 - retVal;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Green Room
+ * @remarks Originally called 'cpl1'
+ */
+int MortevielleEngine::getPresenceStatsGreenRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ // The original uses an || instead of an &&, resulting
+ // in an always true condition. Based on the other tests,
+ // and on other scenes, we use an && instead.
+ if ((hour > 7) && (hour < 11))
+ retVal = 25;
+ else if ((hour > 10) && (hour < 14))
+ retVal = 35;
+ else if ((hour > 13) && (hour < 16))
+ retVal = 50;
+ else if ((hour > 15) && (hour < 18))
+ retVal = 5;
+ else if ((hour > 17) && (hour < 22))
+ retVal = 35;
+ else if ((hour > 21) && (hour < 24))
+ retVal = 50;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 70;
+
+ _menu.updateMenu();
+
+ return retVal;
+}
+/**
+ * Engine function - Get Presence Statistics - Purple Room
+ * @remarks Originally called 'cpl2'
+ */
+int MortevielleEngine::getPresenceStatsPurpleRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 7) && (hour < 11))
+ retVal = -2;
+ else if (hour == 11)
+ retVal = 100;
+ else if ((hour > 11) && (hour < 23))
+ retVal = 10;
+ else if (hour == 23)
+ retVal = 20;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 50;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Toilets
+ * @remarks Originally called 'cpl3'
+ */
+int MortevielleEngine::getPresenceStatsToilets() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 10)) || ((hour > 19) && (hour < 24)))
+ retVal = 34;
+ else if (((hour > 9) && (hour < 20)) || ((hour >= 0) && (hour < 9)))
+ retVal = 0;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Blue Room
+ * @remarks Originally called 'cpl5'
+ */
+int MortevielleEngine::getPresenceStatsBlueRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 6) && (hour < 10))
+ retVal = 0;
+ else if (hour == 10)
+ retVal = 100;
+ else if ((hour > 10) && (hour < 24))
+ retVal = 15;
+ else if ((hour >= 0) && (hour < 7))
+ retVal = 50;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Red Room
+ * @remarks Originally called 'cpl6'
+ */
+int MortevielleEngine::getPresenceStatsRedRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 7) && (hour < 13)) || ((hour > 17) && (hour < 20)))
+ retVal = -2;
+ else if (((hour > 12) && (hour < 17)) || ((hour > 19) && (hour < 24)))
+ retVal = 35;
+ else if (hour == 17)
+ retVal = 100;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 60;
+
+ return retVal;
+}
+
+/**
+ * Shows the "you are alone" message in the status area
+ * on the right hand side of the screen
+ * @remarks Originally called 'person'
+ */
+void MortevielleEngine::displayAloneText() {
+ for (int i = 1; i <= 8; ++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);
+
+ _currBitIndex = 0;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Bureau
+ * @remarks Originally called 'cpl10'
+ */
+int MortevielleEngine::getPresenceStatsDiningRoom(int &hour) {
+ int day, minute;
+
+ int retVal = 0;
+ updateHour(day, hour, minute);
+ if (((hour > 7) && (hour < 11)) || ((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
+ retVal = 100;
+ else if ((hour == 11) || ((hour > 20) && (hour < 24)))
+ retVal = 45;
+ else if (((hour > 13) && (hour < 17)) || (hour == 18))
+ retVal = 35;
+ else if (hour == 17)
+ retVal = 60;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 5;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Bureau
+ * @remarks Originally called 'cpl11'
+ */
+int MortevielleEngine::getPresenceStatsBureau(int &hour) {
+ int day, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 12)) || ((hour > 20) && (hour < 24)))
+ retVal = 25;
+ else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
+ retVal = 5;
+ else if ((hour > 13) && (hour < 17))
+ retVal = 55;
+ else if ((hour > 16) && (hour < 19))
+ retVal = 45;
+ else if ((hour >= 0) && (hour < 9))
+ retVal = 0;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Kitchen
+ * @remarks Originally called 'cpl12'
+ */
+int MortevielleEngine::getPresenceStatsKitchen() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 15)) || ((hour > 16) && (hour < 22)))
+ retVal = 55;
+ else if (((hour > 14) && (hour < 17)) || ((hour > 21) && (hour < 24)))
+ retVal = 25;
+ else if ((hour >= 0) && (hour < 5))
+ retVal = 0;
+ else if ((hour > 4) && (hour < 9))
+ retVal = 15;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Attic
+ * @remarks Originally called 'cpl13'
+ */
+int MortevielleEngine::getPresenceStatsAttic() {
+ return 0;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Landing
+ * @remarks Originally called 'cpl15'
+ */
+int MortevielleEngine::getPresenceStatsLanding() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 7) && (hour < 12))
+ retVal = 25;
+ else if ((hour > 11) && (hour < 14))
+ retVal = 0;
+ else if ((hour > 13) && (hour < 18))
+ retVal = 10;
+ else if ((hour > 17) && (hour < 20))
+ retVal = 55;
+ else if ((hour > 19) && (hour < 22))
+ retVal = 5;
+ else if ((hour > 21) && (hour < 24))
+ retVal = 15;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = -15;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Chapel
+ * @remarks Originally called 'cpl20'
+ */
+int MortevielleEngine::getPresenceStatsChapel(int &hour) {
+ int day, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (hour == 10)
+ retVal = 65;
+ else if ((hour > 10) && (hour < 21))
+ retVal = 5;
+ else if ((hour > 20) && (hour < 24))
+ retVal = -15;
+ else if ((hour >= 0) && (hour < 5))
+ retVal = -300;
+ else if ((hour > 4) && (hour < 10))
+ retVal = -5;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Green Room
+ * @remarks Originally called 'quelq1'
+ */
+void MortevielleEngine::setPresenceGreenRoom(int roomId) {
+ int rand = getRandomNumber(1, 2);
+ if (roomId == GREEN_ROOM) {
+ if (rand == 1)
+ _roomPresenceLuc = true;
+ else
+ _roomPresenceIda = true;
+ } else if (roomId == DARKBLUE_ROOM) {
+ if (rand == 1)
+ _roomPresenceGuy = true;
+ else
+ _roomPresenceEva = true;
+ }
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Purple Room
+ * @remarks Originally called 'quelq2'
+ */
+void MortevielleEngine::setPresencePurpleRoom() {
+ if (_place == PURPLE_ROOM)
+ _purpleRoomPresenceLeo = true;
+ else
+ _juliaRoomPresenceLeo = true;
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Blue Room
+ * @remarks Originally called 'quelq5'
+ */
+void MortevielleEngine::setPresenceBlueRoom() {
+ _roomPresenceMax = true;
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Red Room
+ * @remarks Originally called 'quelq6'
+ */
+void MortevielleEngine::setPresenceRedRoom(int roomId) {
+ if (roomId == RED_ROOM)
+ _roomPresenceBob = true;
+ else if (roomId == GREEN_ROOM2)
+ _roomPresencePat = true;
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Dining Room
+ * @remarks Originally called 'quelq10'
+ */
+int MortevielleEngine::setPresenceDiningRoom(int hour) {
+ int retVal = 0;
+
+ if ((hour >= 0) && (hour < 8))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if ((hour > 7) && (hour < 10)) {
+ min = 5;
+ max = 7;
+ } else if ((hour > 9) && (hour < 12)) {
+ min = 1;
+ max = 4;
+ } else if (((hour > 11) && (hour < 15)) || ((hour > 18) && (hour < 21))) {
+ min = 6;
+ max = 8;
+ } else if (((hour > 14) && (hour < 19)) || ((hour > 20) && (hour < 24))) {
+ min = 1;
+ max = 5;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Bureau
+ * @remarks Originally called 'quelq11'
+ */
+int MortevielleEngine::setPresenceBureau(int hour) {
+ int retVal = 0;
+
+ if ((hour >= 0) && (hour < 8))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if (((hour > 7) && (hour < 10)) || ((hour > 20) && (hour < 24))) {
+ min = 1;
+ max = 3;
+ } else if (((hour > 9) && (hour < 12)) || ((hour > 13) && (hour < 19))) {
+ min = 1;
+ max = 4;
+ } else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21))) {
+ min = 1;
+ max = 2;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Kitchen
+ * @remarks Originally called 'quelq12'
+ */
+int MortevielleEngine::setPresenceKitchen() {
+ int retVal = checkLeoMaxRandomPresence();
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Landing
+ * @remarks Originally called 'quelq15'
+ */
+int MortevielleEngine::setPresenceLanding() {
+ bool test = false;
+ int rand = 0;
+ do {
+ rand = getRandomNumber(1, 8);
+ test = (((rand == 1) && (_purpleRoomPresenceLeo || _juliaRoomPresenceLeo)) ||
+ ((rand == 2) && _roomPresencePat) ||
+ ((rand == 3) && _roomPresenceGuy) ||
+ ((rand == 4) && _roomPresenceEva) ||
+ ((rand == 5) && _roomPresenceBob) ||
+ ((rand == 6) && _roomPresenceLuc) ||
+ ((rand == 7) && _roomPresenceIda) ||
+ ((rand == 8) && _roomPresenceMax));
+ } while (test);
+
+ int retVal = convertCharacterIndexToBitIndex(rand);
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the chapel
+ * @remarks Originally called 'quelq20'
+ */
+int MortevielleEngine::setPresenceChapel(int hour) {
+ int retVal = 0;
+
+ if (((hour >= 0) && (hour < 10)) || ((hour > 18) && (hour < 24)))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if ((hour > 9) && (hour < 12)) {
+ min = 3;
+ max = 7;
+ } else if ((hour > 11) && (hour < 18)) {
+ min = 1;
+ max = 2;
+ } else if (hour == 18) {
+ min = 2;
+ max = 4;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get the answer after you known a door
+ * @remarks Originally called 'frap'
+ */
+void MortevielleEngine::getKnockAnswer() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if ((hour >= 0) && (hour < 8))
+ _crep = 190;
+ else {
+ if (getRandomNumber(1, 100) > 70)
+ _crep = 190;
+ else
+ _crep = 147;
+ }
+}
+
+/**
+ * Engine function - Get Room Presence Bit Index
+ * @remarks Originally called 'nouvp'
+ */
+int MortevielleEngine::getPresenceBitIndex(int roomId) {
+ int bitIndex = 0;
+ if (roomId == GREEN_ROOM) {
+ if (_roomPresenceLuc)
+ bitIndex = 4; // LUC
+ if (_roomPresenceIda)
+ bitIndex = 2; // IDA
+ } else if ( ((roomId == PURPLE_ROOM) && (_purpleRoomPresenceLeo))
+ || ((roomId == JULIA_ROOM) && (_juliaRoomPresenceLeo)))
+ bitIndex = 128; // LEO
+ else if (roomId == DARKBLUE_ROOM) {
+ if (_roomPresenceGuy)
+ bitIndex = 32; // GUY
+ if (_roomPresenceEva)
+ bitIndex = 16; // EVA
+ } else if ((roomId == BLUE_ROOM) && (_roomPresenceMax))
+ bitIndex = 1; // MAX
+ else if ((roomId == RED_ROOM) && (_roomPresenceBob))
+ bitIndex = 8; // BOB
+ else if ((roomId == GREEN_ROOM2) && (_roomPresencePat))
+ bitIndex = 64; // PAT
+ else if ( ((roomId == TOILETS) && (_toiletsPresenceBobMax))
+ || ((roomId == BATHROOM) && (_bathRoomPresenceBobMax)) )
+ bitIndex = 9; // BOB + MAX
+
+ if (bitIndex != 9)
+ showPeoplePresent(bitIndex);
+
+ return bitIndex;
+}
+
+/**
+ * Engine function - initGame
+ * @remarks Originally called 'dprog'
+ */
+void MortevielleEngine::initGame() {
+ _place = MANOR_FRONT;
+ _currentHourCount = 0;
+ if (!_coreVar._alreadyEnteredManor)
+ _blo = true;
+ _inGameHourDuration = kTime1;
+ _currentTime = readclock();
+}
+
+/**
+ * Engine function - Set Random Presence - Green Room
+ * @remarks Originally called 'pl1'
+ */
+void MortevielleEngine::setRandomPresenceGreenRoom(int faithScore) {
+ if ( ((_place == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
+ || ((_place == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) ) {
+ int p = getPresenceStatsGreenRoom();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceGreenRoom(_place);
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Purple Room
+ * @remarks Originally called 'pl2'
+ */
+void MortevielleEngine::setRandomPresencePurpleRoom(int faithScore) {
+ if (!_purpleRoomPresenceLeo) {
+ int p = getPresenceStatsPurpleRoom();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresencePurpleRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Blue Room
+ * @remarks Originally called 'pl5'
+ */
+void MortevielleEngine::setRandomPresenceBlueRoom(int faithScore) {
+ if (!_roomPresenceMax) {
+ int p = getPresenceStatsBlueRoom();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceBlueRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Red Room
+ * @remarks Originally called 'pl6'
+ */
+void MortevielleEngine::setRandomPresenceRedRoom(int faithScore) {
+ if ( ((_place == RED_ROOM) && (!_roomPresenceBob))
+ || ((_place == GREEN_ROOM2) && (!_roomPresencePat)) ) {
+ int p = getPresenceStatsRedRoom();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceRedRoom(_place);
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Room 9
+ * @remarks Originally called 'pl9'
+ */
+void MortevielleEngine::setRandomPresenceJuliaRoom(int faithScore) {
+ if (!_juliaRoomPresenceLeo) {
+ faithScore = -10;
+ if (getRandomNumber(1, 100) > faithScore) // always true?
+ displayAloneText();
+ else
+ setPresencePurpleRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Dining Room
+ * @remarks Originally called 'pl10'
+ */
+void MortevielleEngine::setRandomPresenceDiningRoom(int faithScore) {
+ int h;
+ int p = getPresenceStatsDiningRoom(h);
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceDiningRoom(h);
+}
+
+/**
+ * Engine function - Set Random Presence - Bureau
+ * @remarks Originally called 'pl11'
+ */
+void MortevielleEngine::setRandomPresenceBureau(int faithScore) {
+ int h;
+
+ int p = getPresenceStatsBureau(h);
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceBureau(h);
+}
+
+/**
+ * Engine function - Set Random Presence - Kitchen
+ * @remarks Originally called 'pl12'
+ */
+void MortevielleEngine::setRandomPresenceKitchen(int faithScore) {
+
+ int p = getPresenceStatsKitchen();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceKitchen();
+}
+
+/**
+ * Engine function - Set Random Presence - Attic / Cellar
+ * @remarks Originally called 'pl13'
+ */
+void MortevielleEngine::setRandomPresenceAttic(int faithScore) {
+ int p = getPresenceStatsAttic();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceKitchen();
+}
+
+/**
+ * Engine function - Set Random Presence - Landing
+ * @remarks Originally called 'pl15'
+ */
+void MortevielleEngine::setRandomPresenceLanding(int faithScore) {
+ int p = getPresenceStatsLanding();
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceLanding();
+}
+
+/**
+ * Engine function - Set Random Presence - Chapel
+ * @remarks Originally called 'pl20'
+ */
+void MortevielleEngine::setRandomPresenceChapel(int faithScore) {
+ int h;
+
+ int p = getPresenceStatsChapel(h);
+ p += faithScore;
+ if (getRandomNumber(1, 100) > p)
+ displayAloneText();
+ else
+ setPresenceChapel(h);
+}
+
+/**
+ * Start music or speech
+ * @remarks Originally called 'musique'
+ */
+void MortevielleEngine::startMusicOrSpeech(int so) {
+ if (so == 0) {
+ /* musik(0) */
+ ;
+ } else if ((!_introSpeechPlayed) && (!_coreVar._alreadyEnteredManor)) {
+ // Type 1: Speech
+ _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);
+ else if ((_coreVar._currPlace == CHAPEL) && (getRandomNumber(1, 2) == 1))
+ // Type 1: Speech
+ _soundManager.startSpeech(8, 1, 1);
+ else if ((_coreVar._currPlace == WELL) && (getRandomNumber(1, 2) == 2))
+ // Type 1: Speech
+ _soundManager.startSpeech(12, 1, 1);
+ else if (_coreVar._currPlace == INSIDE_WELL)
+ // Type 1: Speech
+ _soundManager.startSpeech(13, 1, 1);
+ else
+ // Type 2 : music
+ _soundManager.startSpeech(getRandomNumber(1, 17), 1, 2);
+ }
+}
+
+/**
+ * Engine function - You lose!
+ * @remarks Originally called 'tperd'
+ */
+void MortevielleEngine::loseGame() {
+ resetOpenObjects();
+ _roomDoorId = OWN_ROOM;
+ _curSearchObjId = 0;
+ _menu.unsetSearchMenu();
+ if (!_blo)
+ getPresence(MANOR_FRONT);
+
+ _loseGame = true;
+ clearUpperLeftPart();
+ _screenSurface.drawBox(60, 35, 400, 50, 15);
+ handleDescriptionText(9, _crep);
+ clearDescriptionBar();
+ clearVerbBar();
+ _col = false;
+ _syn = false;
+ _destinationOk = false;
+}
+
+/**
+ * Engine function - Check inventory for a given object
+ * @remarks Originally called 'cherjer'
+ */
+bool MortevielleEngine::checkInventory(int objectId) {
+ bool retVal = false;
+ for (int i = 1; i <= 6; ++i)
+ retVal = (retVal || (_coreVar._inventory[i] == objectId));
+
+ if (_coreVar._selectedObjectId == objectId)
+ retVal = true;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Display Dining Room
+ * @remarks Originally called 'st1sama'
+ */
+void MortevielleEngine::displayDiningRoom() {
+ _coreVar._currPlace = DINING_ROOM;
+ prepareDisplayText();
+}
+
+/**
+ * Engine function - Start non interactive Dialog
+ * @remarks Originally called 'sparl'
+ */
+void MortevielleEngine::startDialog(int16 rep) {
+ const int haut[9] = { 0, 0, 1, -3, 6, -2, 2, 7, -1 };
+ int key;
+
+ assert(rep >= 0);
+
+ _mouse.hideMouse();
+ Common::String dialogStr = getString(rep + kDialogStringIndex);
+ _text.displayStr(dialogStr, 230, 4, 65, 26, 5);
+ _dialogManager.drawF3F8();
+
+ key = 0;
+ do {
+ _soundManager.startSpeech(rep, haut[_caff - 69], 0);
+ key = _dialogManager.waitForF3F8();
+ if (shouldQuit())
+ return;
+ } while (key != 66);
+ clearScreen();
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - End of Search: reset globals
+ * @remarks Originally called 'finfouill'
+ */
+void MortevielleEngine::endSearch() {
+ _heroSearching = false;
+ _obpart = false;
+ _searchCount = 0;
+ _menu.unsetSearchMenu();
+}
+
+/**
+ * Engine function - Go to Dining room
+ * @remarks Originally called 't1sama'
+ */
+void MortevielleEngine::gotoDiningRoom() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if ((hour < 5) && (_coreVar._currPlace > ROOM18)) {
+ if (!checkInventory(137)) { //You don't have the keys, and it's late
+ _crep = 1511;
+ loseGame();
+ } else
+ displayDiningRoom();
+ } else if (!_coreVar._alreadyEnteredManor) { //Is it your first time?
+ _currBitIndex = 255; // Everybody is present
+ showPeoplePresent(_currBitIndex);
+ _caff = 77;
+ drawPictureWithText();
+ _screenSurface.drawBox(223, 47, 155, 92, 15);
+ handleDescriptionText(2, 33);
+ testKey(false);
+ menuUp();
+ _mouse.hideMouse();
+ clearScreen();
+ drawDiscussionBox();
+ startDialog(140);
+ drawRightFrame();
+ drawClock();
+ _mouse.showMouse();
+ _coreVar._currPlace = OWN_ROOM;
+ prepareDisplayText();
+ resetPresenceInRooms(DINING_ROOM);
+ if (!_blo)
+ getPresence(OWN_ROOM);
+ _currBitIndex = 0;
+ _savedBitIndex = 0;
+ _coreVar._alreadyEnteredManor = true;
+ } else
+ displayDiningRoom();
+}
+
+/**
+ * Engine function - Check Manor distance (in the mountains)
+ * @remarks Originally called 't1neig'
+ */
+void MortevielleEngine::checkManorDistance() {
+ ++_manorDistance;
+ if (_manorDistance > 2) {
+ _crep = 1506;
+ loseGame();
+ } else {
+ _destinationOk = true;
+ _coreVar._currPlace = MOUNTAIN;
+ prepareDisplayText();
+ }
+}
+
+/**
+ * Engine function - Go to Manor front
+ * @remarks Originally called 't1deva'
+ */
+void MortevielleEngine::gotoManorFront() {
+ _manorDistance = 0;
+ _coreVar._currPlace = MANOR_FRONT;
+ prepareDisplayText();
+}
+
+/**
+ * Engine function - Go to Manor back
+ * @remarks Originally called 't1derr'
+ */
+void MortevielleEngine::gotoManorBack() {
+ _coreVar._currPlace = MANOR_BACK;
+ prepareDisplayText();
+}
+
+/**
+ * Engine function - Dead : Flooded in Well
+ * @remarks Originally called 't1deau'
+ */
+void MortevielleEngine::floodedInWell() {
+ _crep = 1503;
+ loseGame();
+}
+
+/**
+ * Called when a savegame has been loaded.
+ * @remarks Originally called 'antegame'
+ */
+void MortevielleEngine::gameLoaded() {
+ _mouse.hideMouse();
+ _menu._menuDisplayed = false;
+ _loseGame = true;
+ _anyone = false;
+ _destinationOk = true;
+ _col = false;
+ _hiddenHero = false;
+ _uptodatePresence = false;
+ _maff = 68;
+ _menuOpcode = OPCODE_NONE;
+ _introSpeechPlayed = false;
+ _x = 0;
+ _y = 0;
+ _num = 0;
+ _startTime = 0;
+ _endTime = 0;
+ _searchCount = 0;
+ _roomDoorId = OWN_ROOM;
+ _syn = true;
+ _heroSearching = true;
+ _curSearchObjId = 0;
+ _manorDistance = 0;
+ resetOpenObjects();
+ _takeObjCount = 0;
+ prepareDisplayText();
+ _hintPctMessage = getString(580);
+
+ _destinationOk = false;
+ _endGame = true;
+ _loseGame = false;
+ _heroSearching = false;
+
+ displayAloneText();
+ prepareRoom();
+ drawClock();
+ drawPictureWithText();
+ handleDescriptionText(2, _crep);
+ clearVerbBar();
+ _endGame = false;
+ _menu.setDestinationText(_coreVar._currPlace);
+ _menu.setInventoryText();
+ if (_coreVar._selectedObjectId != 0)
+ displayItemInHand(_coreVar._selectedObjectId + 400);
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Handle OpCodes
+ * @remarks Originally called 'tsitu'
+ */
+void MortevielleEngine::handleOpcode() {
+ if (!_col)
+ clearDescriptionBar();
+ _syn = false;
+ _keyPressedEsc = false;
+ if (!_anyone) {
+ if (_uptodatePresence) {
+ if ((_currMenu == MENU_MOVE) || (_currAction == _menu._opcodeLeave) || (_currAction == _menu._opcodeSleep) || (_currAction == _menu._opcodeEat)) {
+ _controlMenu = 4;
+ menuUp();
+ return;
+ }
+ }
+
+ if (_currMenu == MENU_MOVE)
+ fctMove();
+ else if (_currMenu == MENU_DISCUSS)
+ fctDiscuss();
+ else if (_currMenu == MENU_INVENTORY)
+ fctInventoryTake();
+ else if (_currAction == _menu._opcodeAttach)
+ fctAttach();
+ else if (_currAction == _menu._opcodeWait)
+ fctWait();
+ else if (_currAction == _menu._opcodeForce)
+ fctForce();
+ else if (_currAction == _menu._opcodeSleep)
+ fctSleep();
+ else if (_currAction == _menu._opcodeListen)
+ fctListen();
+ else if (_currAction == _menu._opcodeEnter)
+ fctEnter();
+ else if (_currAction == _menu._opcodeClose)
+ fctClose();
+ else if (_currAction == _menu._opcodeSearch)
+ fctSearch();
+ else if (_currAction == _menu._opcodeKnock)
+ fctKnock();
+ else if (_currAction == _menu._opcodeScratch)
+ fctScratch();
+ else if (_currAction == _menu._opcodeRead)
+ fctRead();
+ else if (_currAction == _menu._opcodeEat)
+ fctEat();
+ else if (_currAction == _menu._opcodePlace)
+ fctPlace();
+ else if (_currAction == _menu._opcodeOpen)
+ fctOpen();
+ else if (_currAction == _menu._opcodeTake)
+ fctTake();
+ else if (_currAction == _menu._opcodeLook)
+ fctLook();
+ else if (_currAction == _menu._opcodeSmell)
+ fctSmell();
+ else if (_currAction == _menu._opcodeSound)
+ fctSound();
+ else if (_currAction == _menu._opcodeLeave)
+ fctLeave();
+ else if (_currAction == _menu._opcodeLift)
+ fctLift();
+ else if (_currAction == _menu._opcodeTurn)
+ fctTurn();
+ else if (_currAction == _menu._opcodeSSearch)
+ fctSelfSearch();
+ else if (_currAction == _menu._opcodeSRead)
+ fctSelfRead();
+ else if (_currAction == _menu._opcodeSPut)
+ fctSelfPut();
+ else if (_currAction == _menu._opcodeSLook)
+ fctSelftLook();
+
+ _hiddenHero = false;
+
+ if (_currAction == _menu._opcodeSHide)
+ fctSelfHide();
+ } else if (_anyone) {
+ interactNPC();
+ _anyone = false;
+ menuUp();
+ return;
+ }
+ int hour, day, minute;
+ updateHour(day, hour, minute);
+ if ((((hour == 12) || (hour == 13) || (hour == 19)) && (_coreVar._currPlace != DINING_ROOM)) ||
+ ((hour > 0) && (hour < 6) && (_coreVar._currPlace != OWN_ROOM)))
+ ++_coreVar._faithScore;
+ if (((_coreVar._currPlace < CRYPT) || (_coreVar._currPlace > MOUNTAIN)) && (_coreVar._currPlace != INSIDE_WELL)
+ && (_coreVar._currPlace != OWN_ROOM) && (_coreVar._selectedObjectId != 152) && (!_loseGame)) {
+ if ((_coreVar._faithScore > 99) && (hour > 8) && (hour < 16)) {
+ _crep = 1501;
+ loseGame();
+ } else if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
+ _crep = 1508;
+ loseGame();
+ } else if ((day > 1) && (hour > 8) && (!_loseGame)) {
+ _crep = 1502;
+ loseGame();
+ }
+ }
+ menuUp();
+}
+
+/**
+ * Engine function - Transform time into a char
+ * @remarks Originally called 'tmaj3'
+ */
+void MortevielleEngine::hourToChar() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if (minute == 30)
+ minute = 1;
+ hour += day * 24;
+ minute += hour * 2;
+ _coreVar._fullHour = (unsigned char)minute;
+}
+
+/**
+ * Engine function - extract time from a char
+ * @remarks Originally called 'theure'
+ */
+void MortevielleEngine::charToHour() {
+ int fullHour = _coreVar._fullHour;
+ int tmpHour = fullHour % 48;
+ _currDay = fullHour / 48;
+ _currHalfHour = tmpHour % 2;
+ _currHour = tmpHour / 2;
+ _hour = _currHour;
+ if (_currHalfHour == 1)
+ _minute = 30;
+ else
+ _minute = 0;
+}
+
+/**
+ * Engine function - Clear upper left part of Screen - Type 1
+ * @remarks Originally called 'clsf1'
+ */
+void MortevielleEngine::clearUpperLeftPart() {
+ _mouse.hideMouse();
+ _screenSurface.fillRect(0, Common::Rect(0, 11, 514, 175));
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Clear low bar used by description
+ * @remarks Originally called 'clsf2'
+ */
+void MortevielleEngine::clearDescriptionBar() {
+ _mouse.hideMouse();
+ if (_largestClearScreen) {
+ _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);
+ }
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Clear lowest bar used by verbs
+ * @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();
+}
+
+/**
+ * Engine function - Clear upper right part of the screen
+ * @remarks Originally called 'clsf10'
+ */
+void MortevielleEngine::clearUpperRightPart() {
+ Common::String st;
+
+ _mouse.hideMouse();
+
+ // Clear ambiance description
+ _screenSurface.fillRect(15, Common::Rect(544, 93, 600, 98));
+ if (_coreVar._faithScore < 33)
+ st = getEngineString(S_COOL);
+ else if (_coreVar._faithScore < 66)
+ st = getEngineString(S_LOURDE);
+ else if (_coreVar._faithScore > 65)
+ st = getEngineString(S_MALSAINE);
+
+ 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();
+}
+
+/**
+ * Engine function - Get a random number between two values
+ * @remarks Originally called 'get_random_number' and 'hazard'
+ */
+int MortevielleEngine::getRandomNumber(int minval, int maxval) {
+ return _randomSource.getRandomNumber(maxval - minval) + minval;
+}
+
+/**
+ * Engine function - Show alert "use move menu"
+ * @remarks Originally called 'aldepl'
+ */
+void MortevielleEngine::showMoveMenuAlert() {
+ _dialogManager.show(getEngineString(S_USE_DEP_MENU));
+}
+
+/**
+ * The original engine used this method to display a starting text screen letting the player
+ * select the graphics mode to use
+ * @remarks Originally called 'dialpre'
+ */
+void MortevielleEngine::showConfigScreen() {
+ _crep = 998;
+}
+
+/**
+ * Decodes a number of 64 byte blocks
+ * @param pStart Start of data
+ * @param count Number of 64 byte blocks
+ * @remarks Originally called 'zzuul'
+ */
+void MortevielleEngine::decodeNumber(byte *pStart, int count) {
+ while (count-- > 0) {
+ for (int idx = 0; idx < 64; ++pStart, ++idx) {
+ uint16 v = ((*pStart - 0x80) << 1) + 0x80;
+
+ if (v & 0x8000)
+ *pStart = 0;
+ else if (v & 0xff00)
+ *pStart = 0xff;
+ else
+ *pStart = (byte)v;
+ }
+ }
+}
+
+const byte cryptoArrDefaultFr[32] = {
+ 32, 101, 115, 97, 114, 105, 110,
+ 117, 116, 111, 108, 13, 100, 99,
+ 112, 109, 46, 118, 130, 39, 102,
+ 98, 44, 113, 104, 103, 33, 76,
+ 85, 106, 30, 31
+};
+
+const byte cryptoArr30Fr[32] = {
+ 69, 67, 74, 138, 133, 120, 77, 122,
+ 121, 68, 65, 63, 73, 80, 83, 82,
+ 156, 45, 58, 79, 49, 86, 78, 84,
+ 71, 81, 64, 66, 135, 34, 136, 91
+};
+
+const byte cryptoArr31Fr[32]= {
+ 93, 47, 48, 53, 50, 70, 124, 75,
+ 72, 147, 140, 150, 151, 57, 56, 51,
+ 107, 139, 55, 89, 131, 37, 54, 88,
+ 119, 0, 0, 0, 0, 0, 0, 0
+};
+
+const byte cryptoArrDefaultDe[32] = {
+ 0x20, 0x65, 0x6E, 0x69, 0x73, 0x72, 0x74,
+ 0x68, 0x61, 0x75, 0x0D, 0x63, 0x6C, 0x64,
+ 0x6D, 0x6F, 0x67, 0x2E, 0x62, 0x66, 0x53,
+ 0x2C, 0x77, 0x45, 0x7A, 0x6B, 0x44, 0x76,
+ 0x9C, 0x47, 0x1E, 0x1F
+};
+
+const byte cryptoArr30De[32] = {
+ 0x49, 0x4D, 0x21, 0x42, 0x4C, 0x70, 0x41, 0x52,
+ 0x57, 0x4E, 0x48, 0x3F, 0x46, 0x50, 0x55, 0x4B,
+ 0x5A, 0x4A, 0x54, 0x31, 0x4F, 0x56, 0x79, 0x3A,
+ 0x6A, 0x5B, 0x5D, 0x40, 0x22, 0x2F, 0x30, 0x35
+};
+
+const byte cryptoArr31De[32]= {
+ 0x78, 0x2D, 0x32, 0x82, 0x43, 0x39, 0x33, 0x38,
+ 0x7C, 0x27, 0x37, 0x3B, 0x25, 0x28, 0x29, 0x36,
+ 0x51, 0x59, 0x71, 0x81, 0x87, 0x88, 0x93, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const byte *cryptoArrDefault, *cryptoArr30, *cryptoArr31;
+uint16 ctrlChar;
+
+/**
+ * Decrypt the next character
+ * @param c OUT, next decrypted char
+ * @param idx IN/OUT, current buffer index
+ * @param pt IN/OUT, current encryption point
+ * @return a boolean specifying if a stop character has been encountered
+ * @remarks Originally called 'cinq_huit'
+ */
+bool MortevielleEngine::decryptNextChar(char &c, int &idx, byte &pt) {
+ uint16 oct, ocd;
+
+ /* 5-8 */
+ oct = _dialogIndexArray[idx];
+ oct = ((uint16)(oct << (16 - pt))) >> (16 - pt);
+ if (pt < 6) {
+ ++idx;
+ oct = oct << (5 - pt);
+ pt += 11;
+ oct = oct | ((uint)_dialogIndexArray[idx] >> pt);
+ } else {
+ pt -= 5;
+ oct = (uint)oct >> pt;
+ }
+
+ if (oct == ctrlChar) {
+ c = '$';
+ return true;
+ } else if (oct == 30 || oct == 31) {
+ ocd = _dialogIndexArray[idx];
+ ocd = (uint16)(ocd << (16 - pt)) >> (16 - pt);
+ if (pt < 6) {
+ ++idx;
+ ocd = ocd << (5 - pt);
+ pt += 11;
+ ocd = ocd | ((uint)_dialogIndexArray[idx] >> pt);
+ } else {
+ pt -= 5;
+ ocd = (uint)ocd >> pt;
+ }
+
+ if (oct == 30)
+ c = (unsigned char)cryptoArr30[ocd];
+ else
+ c = (unsigned char)cryptoArr31[ocd];
+
+ if (c == '\0') {
+ c = '#';
+ return true;
+ }
+ } else {
+ c = (unsigned char)cryptoArrDefault[oct];
+ }
+ return false;
+}
+
+/**
+ * Decode and extract the line with the given Id
+ * @remarks Originally called 'deline'
+ */
+Common::String MortevielleEngine::getString(int num) {
+ Common::String wrkStr = "";
+
+ if (num < 0) {
+ warning("getString(%d): num < 0! Skipping", num);
+ } else if (!_txxFileFl) {
+ wrkStr = getGameString(num);
+ } else {
+ int hint = _dialogHintArray[num]._hintId;
+ byte point = _dialogHintArray[num]._point;
+ int length = 0;
+ bool endFl = false;
+ char let;
+ do {
+ endFl = decryptNextChar(let, hint, point);
+ wrkStr += let;
+ ++length;
+ } while (!endFl);
+ }
+
+ while (wrkStr.lastChar() == '$')
+ // Remove trailing '$'s
+ wrkStr.deleteLastChar();
+
+ return wrkStr;
+}
+
+/**
+ * Reset object place
+ * @remarks Originally called 'copcha'
+ */
+void MortevielleEngine::resetObjectPlace() {
+ for (int i = kAcha; i < kAcha + 390; i++)
+ _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;
+
+ for (int i = 2; i <= 6; ++i)
+ _coreVar._inventory[i] = 0;
+
+ // Only object in inventory: a gun
+ _coreVar._inventory[1] = 113;
+
+ _coreVar._fullHour = (unsigned char)20;
+
+ for (int i = 1; i <= 10; ++i)
+ _coreVar._pctHintFound[i] = ' ';
+
+ for (int i = 1; i <= 6; ++i)
+ _coreVar._availableQuestion[i] = '*';
+
+ for (int i = 7; i <= 9; ++i)
+ _coreVar._availableQuestion[i] = ' ';
+
+ for (int i = 10; i <= 28; ++i)
+ _coreVar._availableQuestion[i] = '*';
+
+ for (int i = 29; i <= 42; ++i)
+ _coreVar._availableQuestion[i] = ' ';
+
+ _coreVar._availableQuestion[33] = '*';
+
+ for (int i = 1; i <= 8; ++i)
+ _charAnswerCount[i] = 0;
+
+ initMaxAnswer();
+}
+
+/**
+ * Engine function - Set the palette
+ * @remarks Originally called 'writepal'
+ */
+void MortevielleEngine::setPal(int n) {
+ for (int i = 1; i <= 16; ++i) {
+ _curPict[(2 * i)] = _stdPal[n][i].x;
+ _curPict[(2 * i) + 1] = _stdPal[n][i].y;
+ }
+}
+
+/**
+ * Engine function - Load Palette from File
+ * @remarks Originally called 'charpal'
+ */
+void MortevielleEngine::loadPalette() {
+ Common::File f;
+
+ if (!f.open("fxx.mor")) {
+ if (f.open("mfxx.mor"))
+ f.seek(7 * 25);
+ else
+ error("Missing file - fxx.mor");
+ }
+
+ for (int i = 0; i < 108; ++i)
+ _drawingSizeArr[i] = f.readSint16LE();
+ f.close();
+
+ if (!f.open("plxx.mor"))
+ error("Missing file - plxx.mor");
+ for (int i = 0; i <= 90; ++i) {
+ for (int j = 1; j <= 16; ++j) {
+ _stdPal[i][j].x = f.readByte();
+ _stdPal[i][j].y = f.readByte();
+ }
+ }
+ f.close();
+
+ if (!f.open("cxx.mor"))
+ error("Missing file - cxx.mor");
+
+ // Skip CGA Palette and Patterns
+
+ f.close();
+}
+
+/**
+ * Engine function - Load Texts from File
+ * @remarks Originally called 'chartex'
+ */
+void MortevielleEngine::loadTexts() {
+ Common::File inpFile;
+ Common::File ntpFile;
+
+ _txxFileFl = false;
+ if (!useOriginalData()) {
+ warning("Using improved translation from DAT file");
+ return;
+ }
+
+ if (!inpFile.open("TXX.INP")) {
+ if (!inpFile.open("TXX.MOR")) {
+ warning("Missing file - TXX.INP or .MOR - Switching to DAT file");
+ return;
+ }
+ }
+ if (ntpFile.open("TXX.NTP")) {
+ cryptoArr30 = cryptoArr30Fr;
+ cryptoArr31 = cryptoArr31Fr;
+ cryptoArrDefault = cryptoArrDefaultFr;
+ ctrlChar = 11;
+ } else if (ntpFile.open("TXX.IND")) {
+ cryptoArr30 = cryptoArr30De;
+ cryptoArr31 = cryptoArr31De;
+ cryptoArrDefault = cryptoArrDefaultDe;
+ ctrlChar = 10;
+ } else {
+ warning("Missing file - TXX.NTP or .IND - Switching to DAT file");
+ return;
+ }
+
+ if ((inpFile.size() > (kMaxDialogIndex * 2)) || (ntpFile.size() > (kMaxDialogHint * 3))) {
+ warning("TXX file - Unexpected format - Switching to DAT file");
+ return;
+ }
+
+ for (int i = 0; i < inpFile.size() / 2; ++i)
+ _dialogIndexArray[i] = inpFile.readUint16LE();
+
+ inpFile.close();
+ _txxFileFl = true;
+
+ for (int i = 0; i < (ntpFile.size() / 3); ++i) {
+ _dialogHintArray[i]._hintId = ntpFile.readSint16LE();
+ _dialogHintArray[i]._point = ntpFile.readByte();
+ }
+
+ ntpFile.close();
+
+}
+
+void MortevielleEngine::loadCFIEC() {
+ Common::File f;
+
+ if (!f.open("cfiec.mor")) {
+ if (!f.open("alcfiec.mor"))
+ error("Missing file - *cfiec.mor");
+ }
+
+ _cfiecBufferSize = ((f.size() / 128) + 1) * 128;
+ int32 fileSize = f.size();
+
+ if (!_reloadCFIEC)
+ _cfiecBuffer = (byte *)malloc(sizeof(byte) * _cfiecBufferSize);
+
+ for (int32 i = 0; i < fileSize; ++i)
+ _cfiecBuffer[i] = f.readByte();
+
+ for (int i = fileSize; i < _cfiecBufferSize; i++)
+ _cfiecBuffer[i] = 0;
+
+ f.close();
+
+ _reloadCFIEC = false;
+}
+
+
+void MortevielleEngine::loadCFIPH() {
+ Common::File f;
+
+ if (!f.open("cfiph.mor")) {
+ if (!f.open("alcfiph.mor"))
+ error("Missing file - *cfiph.mor");
+ }
+
+ _soundManager._cfiphBuffer = (uint16 *)malloc(sizeof(uint16) * (f.size() / 2));
+
+ for (int i = 0; i < (f.size() / 2); ++i)
+ _soundManager._cfiphBuffer[i] = f.readUint16BE();
+
+ f.close();
+}
+
+/**
+ * Engine function - Play Music
+ * @remarks Originally called 'music'
+ */
+void MortevielleEngine::music() {
+ if (_soundOff)
+ return;
+
+ _reloadCFIEC = true;
+
+ Common::File f;
+ if (!f.open("mort.img"))
+ error("Missing file - mort.img");
+
+ int size = f.size();
+ byte *compMusicBuf = (byte *)malloc(sizeof(byte) * size);
+ byte *musicBuf = (byte *)malloc(sizeof(byte) * size * 2);
+ f.read(compMusicBuf, size);
+ f.close();
+
+ int musicSize = _soundManager.decodeMusic(compMusicBuf, musicBuf, size);
+ free(compMusicBuf);
+
+ _soundManager.playSong(musicBuf, musicSize, 5);
+ while (keyPressed())
+ getChar();
+
+ free(musicBuf);
+}
+
+/**
+ * Engine function - Show title screen
+ * @remarks Originally called 'suite'
+ */
+void MortevielleEngine::showTitleScreen() {
+ clearScreen();
+ handleDescriptionText(7, 2035);
+ _caff = 51;
+ _text.taffich();
+ testKeyboard();
+ clearScreen();
+ draw(0, 0);
+
+ Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
+ _screenSurface.putxy(104 + 72 * kResolutionScaler, 185);
+ _screenSurface.drawString(cpr, 0);
+}
+
+/**
+ * Draw picture
+ * @remarks Originally called 'dessine'
+ */
+void MortevielleEngine::draw(int x, int y) {
+ _mouse.hideMouse();
+ setPal(_numpal);
+ displayPicture(_curPict, x, y);
+ _mouse.showMouse();
+}
+
+/**
+ * Draw right frame
+ * @remarks Originally called 'dessine_rouleau'
+ */
+void MortevielleEngine::drawRightFrame() {
+ setPal(89);
+ _mouse.hideMouse();
+ displayPicture(_rightFramePict, 0, 0);
+ _mouse.showMouse();
+}
+
+/**
+ * Read the current system time
+ */
+int MortevielleEngine::readclock() {
+ return (int)(g_system->getMillis() / 1000);
+}
+
+/**
+ * Engine function - Prepare room and hint string
+ * @remarks Originally called 'tinke'
+ */
+void MortevielleEngine::prepareRoom() {
+ int day, hour, minute;
+
+ _anyone = false;
+ updateHour(day, hour, minute);
+ if (day != _day) {
+ _day = day;
+ for (int i = 0; i < 9; i++) {
+ if (_charAnswerMax[i] > 0)
+ --_charAnswerMax[i];
+ _charAnswerCount[i] = 0;
+ }
+ }
+ if ((hour > _hour) || ((hour == 0) && (_hour == 23))) {
+ _hour = hour;
+ _minute = 0;
+ drawClock();
+ int hintCount = 0;
+ for (int i = 1; i <= 10; ++i) {
+ if (_coreVar._pctHintFound[i] == '*')
+ ++hintCount;
+ }
+
+ Common::String pctStr;
+ if (hintCount == 10)
+ pctStr = "10";
+ else
+ pctStr = (unsigned char)(hintCount + 48);
+
+ _hintPctMessage = "[1][";
+ _hintPctMessage += getEngineString(S_SHOULD_HAVE_NOTICED);
+ _hintPctMessage += pctStr;
+ _hintPctMessage += '0';
+ _hintPctMessage += getEngineString(S_NUMBER_OF_HINTS);
+ _hintPctMessage += "][";
+ _hintPctMessage += getEngineString(S_OKAY);
+ _hintPctMessage += ']';
+ }
+ if (minute > _minute) {
+ _minute = 30;
+ drawClock();
+ }
+ if (_mouse._pos.y < 12)
+ return;
+
+ if (!_blo) {
+ if ((hour == 12) || ((hour > 18) && (hour < 21)) || ((hour >= 0) && (hour < 7)))
+ _inGameHourDuration = kTime2;
+ else
+ _inGameHourDuration = kTime1;
+ if ((_coreVar._faithScore > 33) && (_coreVar._faithScore < 66))
+ _inGameHourDuration -= (_inGameHourDuration / 3);
+
+ if (_coreVar._faithScore > 65)
+ _inGameHourDuration -= ((_inGameHourDuration / 3) * 2);
+
+ int newTime = readclock();
+ if ((newTime - _currentTime) > _inGameHourDuration) {
+ bool activeMenu = _menu._menuActive;
+ _menu.eraseMenu();
+ _currentHourCount += ((newTime - _currentTime) / _inGameHourDuration);
+ _currentTime = newTime;
+ switch (_place) {
+ case GREEN_ROOM:
+ case DARKBLUE_ROOM:
+ setRandomPresenceGreenRoom(_coreVar._faithScore);
+ break;
+ case PURPLE_ROOM:
+ setRandomPresencePurpleRoom(_coreVar._faithScore);
+ break;
+ case BLUE_ROOM:
+ setRandomPresenceBlueRoom(_coreVar._faithScore);
+ break;
+ case RED_ROOM:
+ case GREEN_ROOM2:
+ setRandomPresenceRedRoom(_coreVar._faithScore);
+ break;
+ case JULIA_ROOM:
+ setRandomPresenceJuliaRoom(_coreVar._faithScore);
+ break;
+ case DINING_ROOM:
+ setRandomPresenceDiningRoom(_coreVar._faithScore);
+ break;
+ case BUREAU:
+ setRandomPresenceBureau(_coreVar._faithScore);
+ break;
+ case KITCHEN:
+ setRandomPresenceKitchen(_coreVar._faithScore);
+ break;
+ case ATTIC:
+ case CELLAR:
+ setRandomPresenceAttic(_coreVar._faithScore);
+ break;
+ case LANDING:
+ case ROOM26:
+ setRandomPresenceLanding(_coreVar._faithScore);
+ break;
+ case CHAPEL:
+ setRandomPresenceChapel(_coreVar._faithScore);
+ break;
+ }
+ if ((_savedBitIndex != 0) && (_currBitIndex != 10))
+ _savedBitIndex = _currBitIndex;
+
+ if ((_savedBitIndex == 0) && (_currBitIndex > 0)) {
+ if ((_coreVar._currPlace == ATTIC) || (_coreVar._currPlace == CELLAR)) {
+ initCaveOrCellar();
+ } else if (_currBitIndex == 10) {
+ _currBitIndex = 0;
+ if (!_uptodatePresence) {
+ _uptodatePresence = true;
+ _startTime = readclock();
+ if (getRandomNumber(1, 5) < 5) {
+ clearVerbBar();
+ prepareScreenType2();
+ displayTextInVerbBar(getEngineString(S_HEAR_NOISE));
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _soundManager.startSpeech(1, rand, 1);
+ _soundManager.waitSpeech();
+ clearVerbBar();
+ }
+ }
+ }
+ }
+
+ if (activeMenu)
+ _menu.drawMenu();
+ }
+ }
+ _endTime = readclock();
+ if ((_uptodatePresence) && ((_endTime - _startTime) > 17)) {
+ getPresenceBitIndex(_place);
+ _uptodatePresence = false;
+ _startTime = 0;
+ if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
+ _anyone = true;
+ }
+}
+
+/**
+ * Engine function - Draw Clock
+ * @remarks Originally called 'pendule'
+ */
+void MortevielleEngine::drawClock() {
+ const int cv[2][12] = {
+ { 5, 8, 10, 8, 5, 0, -5, -8, -10, -8, -5, 0 },
+ { -5, -3, 0, 3, 5, 6, 5, 3, 0, -3, -5, -6 }
+ };
+ const int x = 580;
+ const int y = 123;
+ const int rg = 9;
+
+ _mouse.hideMouse();
+
+ _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);
+ else
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y + rg), 1);
+
+ int hour12 = _hour;
+ if (hour12 > 12)
+ hour12 -= 12;
+ 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);
+
+ if (_hour > 11)
+ _screenSurface.drawString("PM ", 1);
+ else
+ _screenSurface.drawString("AM ", 1);
+
+ _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);
+ }
+}
+
+void MortevielleEngine::palette(int v1) {
+ warning("TODO: palette");
+}
+
+/**
+ * Returns a substring of the given string
+ * @param s Source string
+ * @param idx Starting index (1 based)
+ * @param size Number of characters to return
+ */
+
+Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t size) {
+ assert(idx + size < s.size());
+
+ // 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::String result(tmp);
+ delete[] tmp;
+ return result;
+}
+
+/**
+ * Clear Screen
+ * @remarks Originally called 'hirs'
+ */
+void MortevielleEngine::clearScreen() {
+ _screenSurface.clearScreen();
+}
+
+/**
+ * Init room : Cave or Cellar
+ * @remarks Originally called 'cavegre'
+ */
+void MortevielleEngine::initCaveOrCellar() {
+ _coreVar._faithScore += 2;
+ if (_coreVar._faithScore > 69)
+ _coreVar._faithScore += (_coreVar._faithScore / 10);
+ clearVerbBar();
+ prepareScreenType2();
+ displayTextInVerbBar(getEngineString(S_SOMEONE_ENTERS));
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _soundManager.startSpeech(2, rand, 1);
+ _soundManager.waitSpeech();
+ // The original was doing here a useless loop.
+ // It has been removed
+
+ clearVerbBar();
+ displayAloneText();
+}
+
+/**
+ * Display control menu string
+ * @remarks Originally called 'tctrm'
+ */
+void MortevielleEngine::displayControlMenu() {
+ handleDescriptionText(2, (3000 + _controlMenu));
+ _controlMenu = 0;
+}
+
+/**
+ * Display picture at a given coordinate
+ * @remarks Originally called 'pictout'
+ */
+void MortevielleEngine::displayPicture(const byte *pic, int x, int y) {
+ GfxSurface surface;
+ surface.decode(pic);
+ _screenSurface.drawPicture(surface, x, y);
+}
+
+void MortevielleEngine::adzon() {
+ Common::File f;
+
+ if (!f.open("don.mor"))
+ error("Missing file - don.mor");
+
+ f.read(_tabdon, 7 * 256);
+ f.close();
+
+ if (!f.open("bmor.mor"))
+ error("Missing file - bmor.mor");
+
+ f.read(&_tabdon[kFleche], 1916);
+ f.close();
+
+ // Read Right Frame Drawing
+ if (!f.open("dec.mor"))
+ error("Missing file - dec.mor");
+
+ free(_rightFramePict);
+ _rightFramePict = (byte *)malloc(sizeof(byte) * f.size());
+ f.read(_rightFramePict, f.size());
+ f.close();
+}
+
+/**
+ * Returns the offset within the compressed image data resource of the desired image
+ * @remarks Originally called 'animof'
+ */
+int MortevielleEngine::getAnimOffset(int frameNum, int animNum) {
+ int animCount = _curAnim[1];
+ int aux = animNum;
+ if (frameNum != 1)
+ aux += animCount;
+
+ return (animCount << 2) + 2 + READ_BE_UINT16(&_curAnim[aux << 1]);
+}
+
+/**
+ * Display text in description bar
+ * @remarks Originally called 'text1'
+ */
+void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int mesgId) {
+ Common::String tmpStr = getString(mesgId);
+ if ((y == 182) && ((int) tmpStr.size() > nb))
+ y = 176;
+ _text.displayStr(tmpStr, x, y, nb, 20, _textColor);
+}
+
+/**
+ * Display description text
+ * @remarks Originally called 'repon'
+ */
+void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
+ if ((mesgId > 499) && (mesgId < 563)) {
+ Common::String tmpStr = getString(mesgId - 501 + kInventoryStringIndex);
+
+ if ((int) tmpStr.size() > ((58 + (kResolutionScaler - 1) * 37) << 1))
+ _largestClearScreen = true;
+ else
+ _largestClearScreen = false;
+
+ clearDescriptionBar();
+ _text.displayStr(tmpStr, 8, 176, 85, 3, 5);
+ } else {
+ mapMessageId(mesgId);
+ switch (f) {
+ case 2:
+ case 8:
+ clearDescriptionBar();
+ prepareScreenType2();
+ displayTextInDescriptionBar(8, 182, 103, mesgId);
+ if ((mesgId == 68) || (mesgId == 69))
+ _coreVar._availableQuestion[40] = '*';
+ else if ((mesgId == 104) && (_caff == CELLAR)) {
+ _coreVar._availableQuestion[36] = '*';
+ if (_coreVar._availableQuestion[39] == '*') {
+ _coreVar._pctHintFound[3] = '*';
+ _coreVar._availableQuestion[38] = '*';
+ }
+ }
+ break;
+ case 1:
+ case 6:
+ case 9: {
+ int i;
+ if ((f == 1) || (f == 6))
+ i = 4;
+ else
+ i = 5;
+
+ Common::String tmpStr = getString(mesgId);
+ _text.displayStr(tmpStr, 80, 40, 60, 25, i);
+
+ if (mesgId == 180)
+ _coreVar._pctHintFound[6] = '*';
+ else if (mesgId == 179)
+ _coreVar._pctHintFound[10] = '*';
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * Recompute message Id
+ * @remarks Originally called 'modif'
+ */
+void MortevielleEngine::mapMessageId(int &mesgId) {
+ if (mesgId == 26)
+ mesgId = 25;
+ else if ((mesgId > 29) && (mesgId < 36))
+ mesgId -= 4;
+ else if ((mesgId > 69) && (mesgId < 78))
+ mesgId -= 37;
+ else if ((mesgId > 99) && (mesgId < 194))
+ mesgId -= 59;
+ else if ((mesgId > 996) && (mesgId < 1000))
+ mesgId -= 862;
+ else if ((mesgId > 1500) && (mesgId < 1507))
+ mesgId -= 1363;
+ else if ((mesgId > 1507) && (mesgId < 1513))
+ mesgId -= 1364;
+ else if ((mesgId > 1999) && (mesgId < 2002))
+ mesgId -= 1851;
+ else if (mesgId == 2010)
+ mesgId = 151;
+ else if ((mesgId > 2011) && (mesgId < 2025))
+ mesgId -= 1860;
+ else if (mesgId == 2026)
+ mesgId = 165;
+ else if ((mesgId > 2029) && (mesgId < 2037))
+ mesgId -= 1864;
+ else if ((mesgId > 3000) && (mesgId < 3005))
+ mesgId -= 2828;
+ else if (mesgId == 4100)
+ mesgId = 177;
+ else if (mesgId == 4150)
+ mesgId = 178;
+ else if ((mesgId > 4151) && (mesgId < 4156))
+ mesgId -= 3973;
+ else if (mesgId == 4157)
+ mesgId = 183;
+ else if ((mesgId == 4160) || (mesgId == 4161))
+ mesgId -= 3976;
+}
+
+/**
+ * Initialize open objects array
+ * @remarks Originally called 'initouv'
+ */
+void MortevielleEngine::resetOpenObjects() {
+ for (int i = 1; i <= 6; ++i)
+ _openObjects[i] = 0;
+ _openObjCount = 0;
+}
+
+/**
+ * Display Text Block
+ * @remarks Originally called 'ecr2'
+ */
+void MortevielleEngine::displayTextBlock(Common::String text) {
+ // Some dead code was present in the original: removed
+ _screenSurface.putxy(8, 177);
+ int tlig = 59 + (kResolutionScaler - 1) * 36;
+
+ if ((int)text.size() < tlig)
+ _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);
+ } 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);
+ }
+}
+
+void MortevielleEngine::displayTextInVerbBar(Common::String text) {
+ clearVerbBar();
+ _screenSurface.putxy(8, 192);
+ _screenSurface.drawString(text, 5);
+}
+
+/**
+ * Display item in hand
+ * @remarks Originally called 'modobj'
+ */
+void MortevielleEngine::displayItemInHand(int objId) {
+ Common::String strp = Common::String(' ');
+
+ if (objId != 500)
+ strp = getString(objId - 501 + kInventoryStringIndex);
+
+ _menu.setText(_menu._inventoryMenu[8], strp);
+ _menu.disableMenuItem(_menu._inventoryMenu[8]);
+}
+
+/**
+ * Display empty hand
+ * @remarks Originally called 'maivid'
+ */
+void MortevielleEngine::displayEmptyHand() {
+ _coreVar._selectedObjectId = 0;
+ displayItemInHand(500);
+}
+
+/**
+ * Set a random presence: Leo or Max
+ * @remarks Originally called 'chlm'
+ */
+int MortevielleEngine::checkLeoMaxRandomPresence() {
+ int retval = getRandomNumber(1, 2);
+ if (retval == 2)
+ retval = 128;
+
+ return retval;
+}
+
+/**
+ * Reset room variables
+ * @remarks Originally called 'debloc'
+ */
+void MortevielleEngine::resetRoomVariables(int roomId) {
+ _num = 0;
+ _x = 0;
+ _y = 0;
+ if ((roomId != ROOM26) && (roomId != LANDING))
+ resetPresenceInRooms(roomId);
+ _savedBitIndex = _currBitIndex;
+}
+
+/**
+ * Compute presence stats
+ * @remarks Originally called 'ecfren'
+ */
+int MortevielleEngine::getPresenceStats(int &rand, int faithScore, int roomId) {
+ if (roomId == OWN_ROOM)
+ displayAloneText();
+ int retVal = -500;
+ rand = 0;
+ if ( ((roomId == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
+ || ((roomId == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) )
+ retVal = getPresenceStatsGreenRoom();
+ if ((roomId == PURPLE_ROOM) && (!_purpleRoomPresenceLeo) && (!_juliaRoomPresenceLeo))
+ retVal = getPresenceStatsPurpleRoom();
+ if ( ((roomId == TOILETS) && (!_toiletsPresenceBobMax))
+ || ((roomId == BATHROOM) && (!_bathRoomPresenceBobMax)) )
+ retVal = getPresenceStatsToilets();
+ if ((roomId == BLUE_ROOM) && (!_roomPresenceMax))
+ retVal = getPresenceStatsBlueRoom();
+ if ( ((roomId == RED_ROOM) && (!_roomPresenceBob))
+ || ((roomId == GREEN_ROOM2) && (!_roomPresencePat)))
+ retVal = getPresenceStatsRedRoom();
+ if ((roomId == JULIA_ROOM) && (!_juliaRoomPresenceLeo) && (!_purpleRoomPresenceLeo))
+ retVal = 10;
+ if ( ((roomId == PURPLE_ROOM) && (_juliaRoomPresenceLeo))
+ || ((roomId == JULIA_ROOM) && (_purpleRoomPresenceLeo)))
+ retVal = -400;
+ if (retVal != -500) {
+ retVal += faithScore;
+ rand = getRandomNumber(1, 100);
+ }
+
+ return retVal;
+}
+
+/**
+ * Set presence flags
+ * @remarks Originally called 'becfren'
+ */
+void MortevielleEngine::setPresenceFlags(int roomId) {
+ if ((roomId == GREEN_ROOM) || (roomId == DARKBLUE_ROOM)) {
+ int rand = getRandomNumber(1, 2);
+ if (roomId == GREEN_ROOM) {
+ if (rand == 1)
+ _roomPresenceLuc = true;
+ else
+ _roomPresenceIda = true;
+ } else { // roomId == DARKBLUE_ROOM
+ if (rand == 1)
+ _roomPresenceGuy = true;
+ else
+ _roomPresenceEva = true;
+ }
+ } else if (roomId == PURPLE_ROOM)
+ _purpleRoomPresenceLeo = true;
+ else if (roomId == TOILETS)
+ _toiletsPresenceBobMax = true;
+ else if (roomId == BLUE_ROOM)
+ _roomPresenceMax = true;
+ else if (roomId == RED_ROOM)
+ _roomPresenceBob = true;
+ else if (roomId == BATHROOM)
+ _bathRoomPresenceBobMax = true;
+ else if (roomId == GREEN_ROOM2)
+ _roomPresencePat = true;
+ else if (roomId == JULIA_ROOM)
+ _juliaRoomPresenceLeo = true;
+}
+
+/**
+ * Initialize max answers per character
+ * @remarks Originally called 'init_nbrepm'
+ */
+void MortevielleEngine::initMaxAnswer() {
+ static const byte maxAnswer[9] = { 0, 4, 5, 6, 7, 5, 6, 5, 8 };
+
+ for (int idx = 0; idx < 9; ++idx) {
+ _charAnswerMax[idx] = maxAnswer[idx];
+ _charAnswerCount[idx] = 0;
+ }
+}
+
+/**
+ * Get Presence
+ * @remarks Originally called 't11'
+ */
+int MortevielleEngine::getPresence(int roomId) {
+ int retVal = 0;
+ int rand;
+
+ int pres = getPresenceStats(rand, _coreVar._faithScore, roomId);
+ _place = roomId;
+ if ((roomId > OWN_ROOM) && (roomId < DINING_ROOM)) {
+ if (pres != -500) {
+ if (rand > pres) {
+ displayAloneText();
+ retVal = 0;
+ } else {
+ setPresenceFlags(_place);
+ retVal = getPresenceBitIndex(_place);
+ }
+ } else
+ retVal = getPresenceBitIndex(_place);
+ }
+
+ if (roomId > JULIA_ROOM) {
+ if ((roomId > LANDING) && (roomId != CHAPEL) && (roomId != ROOM26))
+ displayAloneText();
+ else {
+ int h = 0;
+ switch (roomId) {
+ case DINING_ROOM:
+ pres = getPresenceStatsDiningRoom(h);
+ break;
+ case BUREAU:
+ pres = getPresenceStatsBureau(h);
+ break;
+ case KITCHEN:
+ pres = getPresenceStatsKitchen();
+ break;
+ case ATTIC:
+ case CELLAR:
+ pres = getPresenceStatsAttic();
+ break;
+ case LANDING:
+ case ROOM26:
+ pres = getPresenceStatsLanding();
+ break;
+ case CHAPEL:
+ pres = getPresenceStatsChapel(h);
+ break;
+ }
+ pres += _coreVar._faithScore;
+ rand = getRandomNumber(1, 100);
+ if (rand > pres) {
+ displayAloneText();
+ retVal = 0;
+ } else {
+ switch (roomId) {
+ case DINING_ROOM:
+ pres = setPresenceDiningRoom(h);
+ break;
+ case BUREAU:
+ pres = setPresenceBureau(h);
+ break;
+ case KITCHEN:
+ case ATTIC:
+ case CELLAR:
+ pres = setPresenceKitchen();
+ break;
+ case LANDING:
+ case ROOM26:
+ pres = setPresenceLanding();
+ break;
+ case CHAPEL:
+ pres = setPresenceChapel(h);
+ break;
+ }
+ retVal = pres;
+ }
+ }
+ }
+
+ return retVal;
+}
+
+/**
+ * Display Question String
+ * @remarks Originally called 'writetp'
+ */
+void MortevielleEngine::displayQuestionText(Common::String s, int cmd) {
+ _screenSurface.drawString(s, cmd);
+}
+
+/**
+ * Display animation frame
+ * @remarks Originally called 'aniof'
+ */
+void MortevielleEngine::displayAnimFrame(int frameNum, int animId) {
+ if ((_caff == BATHROOM) && ((animId == 4) || (animId == 5)))
+ return;
+
+ if ((_caff == DINING_ROOM) && (animId == 7))
+ animId = 6;
+ else if (_caff == KITCHEN) {
+ if (animId == 3)
+ animId = 4;
+ else if (animId == 4)
+ animId = 3;
+ }
+
+ int offset = getAnimOffset(frameNum, animId);
+
+ GfxSurface surface;
+ surface.decode(&_curAnim[offset]);
+ _screenSurface.drawPicture(surface, 0, 12);
+
+ prepareScreenType1();
+}
+
+/**
+ * Draw Picture
+ * @remarks Originally called 'dessin'
+ */
+void MortevielleEngine::drawPicture() {
+ clearUpperLeftPart();
+ if (_caff > 99) {
+ draw(60, 33);
+ _screenSurface.drawBox(118, 32, 291, 122, 15); // Medium box
+ } else if (_caff > 69) {
+ draw(112, 48); // Heads
+ _screenSurface.drawBox(222, 47, 155, 92, 15);
+ } else {
+ draw(0, 12);
+ prepareScreenType1();
+ if ((_caff < 30) || (_caff > 32)) {
+ for (int i = 1; i <= 6; ++i) {
+ if (_openObjects[i] != 0)
+ displayAnimFrame(1, _openObjects[i]);
+ }
+
+ switch (_caff) {
+ case ATTIC:
+ if (_coreVar._atticBallHoleObjectId == 141)
+ displayAnimFrame(1, 7);
+
+ if (_coreVar._atticRodHoleObjectId == 159)
+ displayAnimFrame(1, 6);
+ break;
+ case CELLAR:
+ if (_coreVar._cellarObjectId == 151)
+ displayAnimFrame(1, 2);
+ break;
+ case SECRET_PASSAGE:
+ if (_coreVar._secretPassageObjectId == 143)
+ displayAnimFrame(1, 1);
+ break;
+ case WELL:
+ if (_coreVar._wellObjectId != 0)
+ displayAnimFrame(1, 1);
+ break;
+ }
+ }
+
+ if (_caff < ROOM26)
+ startMusicOrSpeech(1);
+ }
+}
+
+void MortevielleEngine::drawPictureWithText() {
+ _text.taffich();
+ drawPicture();
+ _destinationOk = false;
+}
+
+/**
+ * Engine function - Place
+ * @remarks Originally called 'tkey1'
+ */
+void MortevielleEngine::testKey(bool d) {
+ bool quest = false;
+ int x, y;
+ bool click;
+
+ _mouse.hideMouse();
+ displayStatusInDescriptionBar('K');
+
+ // Wait for release from any key or mouse button
+ while (keyPressed())
+ _key = gettKeyPressed();
+
+ do {
+ _mouse.getMousePosition(x, y, click);
+ keyPressed();
+ } while (click);
+
+ // Event loop
+ do {
+ if (d)
+ prepareRoom();
+ quest = keyPressed();
+ _mouse.getMousePosition(x, y, click);
+ if (shouldQuit())
+ return;
+ } while (!(quest || (click) || (d && _anyone)));
+ if (quest)
+ gettKeyPressed();
+ setMouseClick(false);
+ _mouse.showMouse();
+}
+
+/**
+ * Display Narrative Picture
+ * @remarks Originally called 'tlu'
+ */
+void MortevielleEngine::displayNarrativePicture(int af, int ob) {
+ _caff = 32;
+ drawPictureWithText();
+ handleDescriptionText(6, ob + 4000);
+ handleDescriptionText(2, 999);
+ testKey(true);
+ _caff = af;
+ _currMenu = OPCODE_NONE;
+ _crep = 998;
+}
+
+/**
+ * Prepare Display Text
+ * @remarks Originally called 'affrep'
+ */
+void MortevielleEngine::prepareDisplayText() {
+ _caff = _coreVar._currPlace;
+ _crep = _coreVar._currPlace;
+}
+
+/**
+ * Exit room
+ * @remarks Originally called 'tsort'
+ */
+void MortevielleEngine::exitRoom() {
+ if ((_openObjCount > 0) && (_coreVar._currPlace != OWN_ROOM)) {
+ if (_coreVar._faithScore < 50)
+ _coreVar._faithScore += 2;
+ else
+ _coreVar._faithScore += (_coreVar._faithScore / 10);
+ }
+
+ resetOpenObjects();
+
+ _roomDoorId = OWN_ROOM;
+ _curSearchObjId = 0;
+ resetRoomVariables(_coreVar._currPlace);
+}
+
+/**
+ * get 'read' description
+ * @remarks Originally called 'st4'
+ */
+void MortevielleEngine::getReadDescription(int objId) {
+ _crep = 997;
+
+ switch (objId) {
+ case 114 :
+ _crep = 109;
+ break;
+ case 110 :
+ _crep = 107;
+ break;
+ case 158 :
+ _crep = 113;
+ break;
+ case 152:
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 150:
+ case 100:
+ case 157:
+ case 160:
+ case 161 :
+ displayNarrativePicture(_caff, objId);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * get 'search' description
+ * @remarks Originally called 'st7'
+ */
+void MortevielleEngine::getSearchDescription(int objId) {
+ switch (objId) {
+ case 116:
+ case 144:
+ _crep = 104;
+ break;
+ case 126:
+ case 111:
+ _crep = 108;
+ break;
+ case 132:
+ _crep = 111;
+ break;
+ case 142:
+ _crep = 112;
+ break;
+ default:
+ _crep = 183;
+ getReadDescription(objId);
+ }
+}
+
+/**
+ * Menu up
+ * @remarks Originally called 'mennor'
+ */
+void MortevielleEngine::menuUp() {
+ _menu.menuUp(_currMenu);
+}
+
+/**
+ * Draw discussion box
+ * @remarks Originally called 'premtet'
+ */
+void MortevielleEngine::drawDiscussionBox() {
+ draw(10, 80);
+ _screenSurface.drawBox(18, 79, 155, 92, 15);
+}
+
+/**
+ * Try to put an object somewhere
+ * @remarks Originally called 'ajchai'
+ */
+void MortevielleEngine::putObject() {
+ int putId = kAcha + ((_curSearchObjId - 1) * 10) - 1;
+ int i;
+ for (i = 1; (i <= 9) && (_tabdon[putId + i] != 0); i++)
+ ;
+
+ if (_tabdon[putId + i] == 0)
+ _tabdon[putId + i] = _coreVar._selectedObjectId;
+ else
+ _crep = 192;
+}
+
+/**
+ * Check if inventory is full and, if not, add object in it.
+ * @remarks Originally called 'ajjer'
+ */
+void MortevielleEngine::addObjectToInventory(int objectId) {
+ int i;
+
+ for (i = 1; (i <= 5) && (_coreVar._inventory[i] != 0); i++)
+ ;
+
+ if (_coreVar._inventory[i] == 0) {
+ _coreVar._inventory[i] = objectId;
+ _menu.setInventoryText();
+ } else
+ // Inventory is full
+ _crep = 139;
+}
+
+/**
+ * Interact with NPC
+ * @remarks Originally called 'quelquun'
+ */
+void MortevielleEngine::interactNPC() {
+ if (_menu._menuDisplayed)
+ _menu.eraseMenu();
+
+ endSearch();
+ _crep = 997;
+L1:
+ if (!_hiddenHero) {
+ if (_crep == 997)
+ _crep = 138;
+ handleDescriptionText(2, _crep);
+ if (_crep == 138)
+ _soundManager.startSpeech(5, 2, 1);
+ else
+ _soundManager.startSpeech(4, 4, 1);
+
+ if (_openObjCount == 0)
+ _coreVar._faithScore += 2;
+ else if (_coreVar._faithScore < 50)
+ _coreVar._faithScore += 4;
+ else
+ _coreVar._faithScore += 3 * (_coreVar._faithScore / 10);
+ exitRoom();
+ _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;
+ _syn = true;
+ _col = true;
+ } else {
+ if (getRandomNumber(1, 3) == 2) {
+ _hiddenHero = false;
+ _crep = 137;
+ goto L1;
+ } else {
+ handleDescriptionText(2, 136);
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _soundManager.startSpeech(3, rand, 1);
+ clearDescriptionBar();
+ displayAloneText();
+ resetRoomVariables(MANOR_FRONT);
+ prepareDisplayText();
+ }
+ }
+ if (_menu._menuDisplayed)
+ _menu.drawMenu();
+}
+
+/**
+ * Search - Prepare next object
+ * @remarks Originally called 'tsuiv'
+ */
+void MortevielleEngine::prepareNextObject() {
+ int objId;
+ int tabIdx = kAcha + ((_curSearchObjId - 1) * 10) - 1;
+ int localSeearchCount = 0;
+ do {
+ ++localSeearchCount;
+ ++_searchCount;
+ objId = _tabdon[tabIdx + _searchCount];
+ } while ((objId == 0) && (_searchCount <= 9));
+
+ if ((objId != 0) && (_searchCount < 11)) {
+ _caff = objId;
+ _crep = _caff + 400;
+ if (_currBitIndex != 0)
+ // Someone is present in the room
+ _coreVar._faithScore += 2;
+ } else {
+ prepareDisplayText();
+ endSearch();
+ if (localSeearchCount > 9)
+ _crep = 131;
+ }
+}
+
+/**
+ * Display Arrow status
+ * @remarks Originally called 'tfleche'
+ */
+void MortevielleEngine::displayStatusArrow() {
+ bool qust;
+ char touch;
+
+ if (_num == 9999)
+ return;
+
+ displayStatusInDescriptionBar((unsigned char)152);
+ bool inRect = false;
+ do {
+ touch = '\0';
+
+ do {
+ _mouse.moveMouse(qust, touch);
+ if (shouldQuit())
+ return;
+
+ if (getMouseClick())
+ 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);
+ } 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;
+ }
+}
+
+/**
+ * Set coordinates
+ * @remarks Originally called 'tcoord'
+ */
+void MortevielleEngine::setCoordinates(int sx) {
+ int sy, ix, iy;
+ int ib;
+
+
+ _num = 0;
+ _crep = 999;
+ int a = 0;
+ int atdon = kAmzon + 3;
+ int cy = 0;
+ while (cy < _caff) {
+ a += _tabdon[atdon];
+ atdon += 4;
+ ++cy;
+ }
+
+ if (_tabdon[atdon] == 0) {
+ _crep = 997;
+ return;
+ }
+
+ a += kFleche;
+ int cb = 0;
+ for (cy = 0; cy <= (sx - 2); ++cy) {
+ ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
+ cb += (ib * 4) + 2;
+ }
+ ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
+ if (ib == 0) {
+ _crep = 997;
+ return;
+ }
+
+ cy = 1;
+ do {
+ cb += 2;
+ sx = _tabdon[a + cb] * kResolutionScaler;
+ sy = _tabdon[(a + cb + 1)];
+ cb += 2;
+ ix = _tabdon[a + cb] * kResolutionScaler;
+ iy = _tabdon[(a + cb + 1)];
+ ++cy;
+ } while (!(((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) || (cy > ib)));
+
+ if ((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) {
+ _num = cy - 1;
+ return;
+ }
+
+ _crep = 997;
+}
+
+/**
+ * Display LOOK Screen
+ * @remarks Originally called 'treg'
+ */
+void MortevielleEngine::displayLookScreen(int objId) {
+ int mdes = _caff;
+ _caff = objId;
+
+ if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == _menu._opcodeSLook)) {
+ drawPictureWithText();
+ if ((_caff > 29) && (_caff < 33))
+ handleDescriptionText(2, _caff);
+ else
+ handleDescriptionText(2, _caff + 400);
+ testKey(true);
+ _caff = mdes;
+ _currMenu = MENU_NONE;
+ _crep = 998;
+ } else {
+ _obpart = true;
+ _crep = _caff + 400;
+ _menu.setSearchMenu();
+ }
+}
+
+/**
+ * Engine function - Put in hand
+ * @remarks Originally called 'avpoing'
+ */
+void MortevielleEngine::putInHand(int &objId) {
+ _crep = 999;
+ if (_coreVar._selectedObjectId != 0)
+ addObjectToInventory(_coreVar._selectedObjectId);
+
+ // If inventory wasn't full
+ if (_crep != 139) {
+ displayItemInHand(objId + 400);
+ _coreVar._selectedObjectId = objId;
+ objId = 0;
+ }
+}
+
+/**
+ * Search - Get the first object
+ * @remarks Originally called 'rechai'
+ */
+int MortevielleEngine::getFirstObject() {
+ int tmpPlace = _coreVar._currPlace;
+
+ if (_coreVar._currPlace == CRYPT)
+ tmpPlace = CELLAR;
+
+ return _tabdon[kAsearch + (tmpPlace * 7) + _num - 1];
+}
+
+/**
+ * Check before leaving the secret passage
+ * @remarks Originally called 't23coul'
+ */
+int MortevielleEngine::checkLeaveSecretPassage() {
+ if (!checkInventory(143)) {
+ _crep = 1512;
+ loseGame();
+ }
+
+ return CELLAR;
+}
+
+/**
+ * Display status character in description bar
+ * @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();
+}
+
+/**
+ * Test Keyboard
+ * @remarks Originally called 'teskbd'
+ */
+void MortevielleEngine::testKeyboard() {
+ if (keyPressed())
+ gettKeyPressed();
+}
+
+/**
+ * Test Key Pressed
+ * @remarks Originally called 'testou'
+ */
+int MortevielleEngine::gettKeyPressed() {
+ char ch = getChar();
+
+ switch (ch) {
+ case '\23' :
+ _soundOff = !_soundOff;
+ break;
+ case '\26' :
+ if ((_x26KeyCount == 1) || (_x26KeyCount == 2)) {
+ decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
+ ++_x26KeyCount;
+
+ return 61;
+ }
+ break;
+ case '\33' :
+ if (keyPressed())
+ ch = getChar();
+ break;
+ default:
+ break;
+ }
+
+ return (int)ch;
+}
+
+} // End of namespace Mortevielle
diff --git a/engines/neverhood/background.cpp b/engines/neverhood/background.cpp
index e9e5325e77..d6a9900d38 100644
--- a/engines/neverhood/background.cpp
+++ b/engines/neverhood/background.cpp
@@ -33,11 +33,11 @@ Background::Background(NeverhoodEngine *vm, int objectPriority)
Background::Background(NeverhoodEngine *vm, uint32 fileHash, int objectPriority, int surfacePriority)
: Entity(vm, objectPriority), _surface(NULL), _spriteResource(vm) {
-
+
_spriteResource.load(fileHash);
createSurface(surfacePriority, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
_surface->drawSpriteResource(_spriteResource);
-
+
}
Background::~Background() {
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index 9f5f46487c..d730d75718 100644
--- a/engines/neverhood/blbarchive.cpp
+++ b/engines/neverhood/blbarchive.cpp
@@ -58,8 +58,8 @@ BlbArchive::~BlbArchive() {
void BlbArchive::open(const Common::String &filename) {
BlbHeader header;
uint16 *extDataOffsets;
-
- _entries.clear();
+
+ _entries.clear();
if (!_fd.open(filename))
error("BlbArchive::open() Could not open %s", filename.c_str());
@@ -83,16 +83,16 @@ void BlbArchive::open(const Common::String &filename) {
entry.fileHash = _fd.readUint32LE();
_entries.push_back(entry);
}
-
+
extDataOffsets = new uint16[header.fileCount];
-
+
// Load file records
for (uint i = 0; i < header.fileCount; i++) {
BlbArchiveEntry &entry = _entries[i];
entry.type = _fd.readByte();
entry.comprType = _fd.readByte();
entry.extData = NULL;
- extDataOffsets[i] = _fd.readUint16LE();
+ extDataOffsets[i] = _fd.readUint16LE();
entry.timeStamp = _fd.readUint32LE();
entry.offset = _fd.readUint32LE();
entry.diskSize = _fd.readUint32LE();
@@ -101,7 +101,7 @@ void BlbArchive::open(const Common::String &filename) {
entry.fileHash, entry.type, entry.comprType, extDataOffsets[i], entry.timeStamp,
entry.offset, entry.diskSize, entry.size);
}
-
+
// Load ext data
if (header.extDataSize > 0) {
_extData = new byte[header.extDataSize];
@@ -120,9 +120,9 @@ void BlbArchive::load(uint index, byte *buffer, uint32 size) {
void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) {
Common::StackLock lock(_mutex);
-
+
_fd.seek(entry->offset);
-
+
switch (entry->comprType) {
case 1: // Uncompressed
if (size == 0)
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
index e676da3727..733d7dd8a4 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -81,7 +81,7 @@ bool Console::Cmd_Cheat(int argc, const char **argv) {
DebugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n");
DebugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n");
DebugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n");
- DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n");
+ DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n");
return true;
}
diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp
index 94a68a7526..ef2b856b2f 100644
--- a/engines/neverhood/diskplayerscene.cpp
+++ b/engines/neverhood/diskplayerscene.cpp
@@ -61,7 +61,7 @@ static const uint32 kDiskplayerSmackerFileHashes[] = {
0x04002810
};
-static const uint32 kDiskplayerSlotFileHashes1[] = {
+static const uint32 kDiskplayerSlotFileHashes1[] = {
0x81312280,
0x01312281,
0x01312282,
@@ -84,7 +84,7 @@ static const uint32 kDiskplayerSlotFileHashes1[] = {
0x04312281
};
-static const uint32 kDiskplayerSlotFileHashes2[] = {
+static const uint32 kDiskplayerSlotFileHashes2[] = {
0x90443A00,
0x90443A18,
0x90443A28,
@@ -107,8 +107,8 @@ static const uint32 kDiskplayerSlotFileHashes2[] = {
0xC0443A18
};
-static const uint32 kDiskplayerSlotFileHashes3[] = {
- 0x10357320,
+static const uint32 kDiskplayerSlotFileHashes3[] = {
+ 0x10357320,
0x10557320,
0x10957320,
0x11157320,
@@ -130,7 +130,7 @@ static const uint32 kDiskplayerSlotFileHashes3[] = {
0x10543320
};
-static const uint32 kDiskplayerSlotFileHashes4[] = {
+static const uint32 kDiskplayerSlotFileHashes4[] = {
0xDC8020E4,
0xDC802164,
0xDC802264,
@@ -155,7 +155,7 @@ static const uint32 kDiskplayerSlotFileHashes4[] = {
AsDiskplayerSceneKey::AsDiskplayerSceneKey(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100) {
-
+
createSurface1(0x100B90B4, 1200);
_x = 211;
_y = 195;
@@ -193,7 +193,7 @@ void AsDiskplayerSceneKey::stDropKeyDone() {
DiskplayerPlayButton::DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene)
: StaticSprite(vm, 1400), _diskplayerScene(diskplayerScene), _isPlaying(false) {
-
+
loadSprite(0x24A4A664, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
setVisible(false);
loadSound(0, 0x44043000);
@@ -317,10 +317,10 @@ void DiskplayerSlot::stop() {
DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int paletteIndex)
: Scene(vm, parentModule), _diskIndex(0), _appearCountdown(0), _tuneInCountdown(0),
- _hasAllDisks(false), _dropKey(false), _inputDisabled(true), _updateStatus(kUSStopped) {
+ _hasAllDisks(false), _dropKey(false), _inputDisabled(true), _updateStatus(kUSStopped) {
int availableDisksCount = 0;
-
+
setBackground(0x8A000044);
setPalette(kDiskplayerPaletteFileHashes[paletteIndex]);
@@ -344,7 +344,7 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int
}
_hasAllDisks = availableDisksCount == 20;
-
+
if (_hasAllDisks && !getGlobalVar(V_HAS_FINAL_KEY))
_dropKey = true;
@@ -360,8 +360,8 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int
_palette->usePalette();
- SetMessageHandler(&DiskplayerScene::handleMessage);
- SetUpdateHandler(&DiskplayerScene::update);
+ SetMessageHandler(&DiskplayerScene::handleMessage);
+ SetUpdateHandler(&DiskplayerScene::update);
_appearCountdown = 6;
}
@@ -417,7 +417,7 @@ void DiskplayerScene::update() {
}
_diskIndex++;
while (!_diskAvailable[_diskIndex] && _diskIndex < 19)
- _diskIndex++;
+ _diskIndex++;
if (_diskIndex < 20) {
_appearCountdown = 1;
} else {
@@ -448,7 +448,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
} else if (!_dropKey &&
param.asPoint().x > 38 && param.asPoint().x < 598 &&
param.asPoint().y > 400 && param.asPoint().y < 460) {
-
+
_diskSlots[_diskIndex]->stop();
_diskIndex = (param.asPoint().x - 38) / 28;
_diskSlots[_diskIndex]->activate();
@@ -462,10 +462,10 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
break;
case 0x2000:
tuneIn();
- break;
+ break;
case 0x2001:
stop();
- break;
+ break;
}
}
return 0;
diff --git a/engines/neverhood/diskplayerscene.h b/engines/neverhood/diskplayerscene.h
index 4afaf8af9f..150d5c58ed 100644
--- a/engines/neverhood/diskplayerscene.h
+++ b/engines/neverhood/diskplayerscene.h
@@ -36,7 +36,7 @@ class AsDiskplayerSceneKey : public AnimatedSprite {
public:
AsDiskplayerSceneKey(NeverhoodEngine *vm);
void stDropKey();
-protected:
+protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void stDropKeyDone();
};
@@ -47,7 +47,7 @@ public:
void press();
void release();
protected:
- DiskplayerScene *_diskplayerScene;
+ DiskplayerScene *_diskplayerScene;
bool _isPlaying;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
@@ -69,7 +69,7 @@ protected:
int _blinkCountdown;
bool _isLocked;
bool _isBlinking;
- void update();
+ void update();
};
enum {
diff --git a/engines/neverhood/entity.cpp b/engines/neverhood/entity.cpp
index 8b1298916c..1ebf1dcf6c 100644
--- a/engines/neverhood/entity.cpp
+++ b/engines/neverhood/entity.cpp
@@ -25,29 +25,29 @@
namespace Neverhood {
-uint32 MessageParam::asInteger() const {
- assert(_type == mptInteger);
- return _integer;
+uint32 MessageParam::asInteger() const {
+ assert(_type == mptInteger);
+ return _integer;
}
-NPoint MessageParam::asPoint() const {
+NPoint MessageParam::asPoint() const {
assert(_type == mptInteger || _type == mptPoint);
if (_type == mptInteger) {
NPoint pt;
pt.x = _integer & 0xFFFF;
- pt.y = (_integer >> 16) & 0xFFFF;
+ pt.y = (_integer >> 16) & 0xFFFF;
return pt;
- }
- return _point;
+ }
+ return _point;
}
Entity *MessageParam::asEntity() const {
- assert(_type == mptEntity);
- return _entity;
+ assert(_type == mptEntity);
+ return _entity;
}
Entity::Entity(NeverhoodEngine *vm, int priority)
- : _vm(vm), _updateHandlerCb(NULL), _messageHandlerCb(NULL), _priority(priority), _soundResources(NULL) {
+ : _vm(vm), _updateHandlerCb(NULL), _messageHandlerCb(nullptr), _priority(priority), _soundResources(NULL) {
}
Entity::~Entity() {
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h
index cba1bb9a7f..5c29bf8a4f 100644
--- a/engines/neverhood/entity.h
+++ b/engines/neverhood/entity.h
@@ -98,7 +98,7 @@ public:
void incGlobalVar(uint32 nameHash, int incrValue);
void incSubVar(uint32 nameHash, uint32 subNameHash, int incrValue);
int getPriority() const { return _priority; }
- bool hasMessageHandler() const { return _messageHandlerCb != NULL; }
+ bool hasMessageHandler() const { return _messageHandlerCb != nullptr; }
protected:
void (Entity::*_updateHandlerCb)();
uint32 (Entity::*_messageHandlerCb)(int messageNum, const MessageParam &param, Entity *sender);
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index b3589837df..47cc818fea 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -77,7 +77,7 @@ GameModule::GameModule(NeverhoodEngine *vm)
: Module(vm, NULL), _moduleNum(-1), _prevChildObject(NULL), _prevModuleNum(-1),
_restoreGameRequested(false), _restartGameRequested(false), _canRequestMainMenu(true),
_mainMenuRequested(false) {
-
+
// Other initializations moved to actual engine class
_vm->_soundMan->playSoundThree(0x002D0031, 0x8861079);
SetMessageHandler(&GameModule::handleMessage);
@@ -96,7 +96,7 @@ void GameModule::handleMouseMove(int16 x, int16 y) {
mousePos.y = y;
debug(2, "GameModule::handleMouseMove(%d, %d)", x, y);
sendPointMessage(_childObject, 0, mousePos);
- }
+ }
}
void GameModule::handleMouseDown(int16 x, int16 y) {
@@ -106,7 +106,7 @@ void GameModule::handleMouseDown(int16 x, int16 y) {
mousePos.y = y;
debug(2, "GameModule::handleMouseDown(%d, %d)", x, y);
sendPointMessage(_childObject, 0x0001, mousePos);
- }
+ }
}
void GameModule::handleMouseUp(int16 x, int16 y) {
@@ -116,21 +116,21 @@ void GameModule::handleMouseUp(int16 x, int16 y) {
mousePos.y = y;
debug(2, "GameModule::handleMouseUp(%d, %d)", x, y);
sendPointMessage(_childObject, 0x0002, mousePos);
- }
+ }
}
void GameModule::handleSpaceKey() {
if (_childObject) {
debug(2, "GameModule::handleSpaceKey()");
sendMessage(_childObject, 0x0009, 0);
- }
+ }
}
void GameModule::handleAsciiKey(char key) {
if (_childObject) {
debug(2, "GameModule::handleAsciiKey()");
sendMessage(_childObject, 0x000A, (uint32)key);
- }
+ }
}
void GameModule::handleKeyDown(Common::KeyCode keyCode) {
@@ -141,7 +141,7 @@ void GameModule::handleKeyDown(Common::KeyCode keyCode) {
handleSpaceKey();
debug(2, "GameModule::handleKeyDown()");
sendMessage(_childObject, 0x000B, keyCode);
- }
+ }
}
void GameModule::handleEscapeKey() {
@@ -166,7 +166,7 @@ void GameModule::initKeySlotsPuzzle() {
void GameModule::initMemoryPuzzle() {
if (!getSubVar(VA_IS_PUZZLE_INIT, 0xC8606803)) {
- NonRepeatingRandomNumbers diceIndices(_vm->_rnd, 3);
+ NonRepeatingRandomNumbers diceIndices(_vm->_rnd, 3);
NonRepeatingRandomNumbers availableTiles(_vm->_rnd, 48);
NonRepeatingRandomNumbers tileSymbols(_vm->_rnd, 10);
for (uint32 i = 0; i < 3; i++)
@@ -320,11 +320,11 @@ uint32 GameModule::handleMessage(int messageNum, const MessageParam &param, Enti
switch (messageNum) {
case 0x0800:
_canRequestMainMenu = true;
- break;
+ break;
case 0x1009:
_moduleResult = param.asInteger();
_done = true;
- break;
+ break;
}
return messageResult;
}
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index 1fb3557b81..2f2fecf463 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -49,7 +49,7 @@ public:
void initWaterPipesPuzzle();
void initRadioPuzzle();
void initTestTubes1Puzzle();
- void initTestTubes2Puzzle();
+ void initTestTubes2Puzzle();
void initCannonSymbolsPuzzle();
void initCodeSymbolsPuzzle();
void initCubeSymbolsPuzzle();
diff --git a/engines/neverhood/gamevars.cpp b/engines/neverhood/gamevars.cpp
index dc25f74e56..9c080fea24 100644
--- a/engines/neverhood/gamevars.cpp
+++ b/engines/neverhood/gamevars.cpp
@@ -75,7 +75,7 @@ uint32 GameVars::getSubVar(uint32 nameHash, uint32 subNameHash) {
int16 subVarIndex = findSubVarIndex(varIndex, subNameHash);
if (subVarIndex != -1)
value = _vars[subVarIndex].value;
- }
+ }
return value;
}
diff --git a/engines/neverhood/gamevars.h b/engines/neverhood/gamevars.h
index de9ffb8ec5..3aec4d1da4 100644
--- a/engines/neverhood/gamevars.h
+++ b/engines/neverhood/gamevars.h
@@ -160,7 +160,7 @@ enum {
VA_HAS_KEY = 0x0090EA95,
VA_IS_KEY_INSERTED = 0x08D0AB11,
VA_LOCKS_DISABLED = 0x14800353,
- V_END_
+ V_END_
};
struct GameVar {
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 66a7999e59..490959020f 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -29,7 +29,7 @@ namespace Neverhood {
BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name)
: _vm(vm), _priority(priority), _visible(true), _transparent(true),
_clipRects(NULL), _clipRectsCount(0), _version(0), _name(name) {
-
+
_drawRect.x = 0;
_drawRect.y = 0;
_drawRect.width = width;
@@ -68,7 +68,7 @@ void BaseSurface::clear() {
}
void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) {
- if (spriteResource.getDimensions().width <= _drawRect.width &&
+ if (spriteResource.getDimensions().width <= _drawRect.width &&
spriteResource.getDimensions().height <= _drawRect.height) {
clear();
spriteResource.draw(_surface, false, false);
@@ -77,7 +77,7 @@ void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) {
}
void BaseSurface::drawSpriteResourceEx(SpriteResource &spriteResource, bool flipX, bool flipY, int16 width, int16 height) {
- if (spriteResource.getDimensions().width <= _sysRect.width &&
+ if (spriteResource.getDimensions().width <= _sysRect.width &&
spriteResource.getDimensions().height <= _sysRect.height) {
if (width > 0 && width <= _sysRect.width)
_drawRect.width = width;
@@ -145,7 +145,7 @@ void ShadowSurface::draw() {
FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
: BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows),
_firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) {
-
+
_tracking = new NPointArray();
*_tracking = *tracking;
@@ -154,7 +154,7 @@ FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsP
FontSurface::FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
: BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows, "font"), _charsPerRow(charsPerRow), _numRows(numRows),
_firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(NULL) {
-
+
SpriteResource fontSpriteResource(_vm);
fontSpriteResource.load(fileHash, true);
drawSpriteResourceEx(fontSpriteResource, false, false, 0, 0);
@@ -182,7 +182,7 @@ void FontSurface::drawString(BaseSurface *destSurface, int16 x, int16 y, const b
for (; stringLen > 0; --stringLen, ++string) {
drawChar(destSurface, x, y, *string);
x += _tracking ? (*_tracking)[*string - _firstChar].x : _charWidth;
- }
+ }
}
@@ -201,7 +201,7 @@ FontSurface *FontSurface::createFontSurface(NeverhoodEngine *vm, uint32 fileHash
uint16 charHeight = fontData.getPoint(calcHash("meCharHeight")).x;
NPointArray *tracking = fontData.getPointArray(calcHash("meTracking"));
fontSprite.load(fileHash, true);
- fontSurface = new FontSurface(vm, tracking, 16, numRows, firstChar, charWidth, charHeight);
+ fontSurface = new FontSurface(vm, tracking, 16, numRows, firstChar, charWidth, charHeight);
fontSurface->drawSpriteResourceEx(fontSprite, false, false, 0, 0);
return fontSurface;
}
@@ -219,7 +219,7 @@ enum BitmapFlags {
void parseBitmapResource(const byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, const byte **palette, const byte **pixels) {
uint16 flags;
-
+
flags = READ_LE_UINT16(sprite);
sprite += 2;
@@ -278,7 +278,7 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int
rows = READ_LE_UINT16(source);
chunks = READ_LE_UINT16(source + 2);
source += 4;
-
+
do {
if (chunks == 0) {
dest += rows * destPitch;
@@ -316,7 +316,7 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int
void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY) {
const int sourcePitch = (width + 3) & 0xFFFC;
-
+
if (flipY) {
dest += destPitch * (height - 1);
destPitch = -destPitch;
diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h
index 9ab0d87ab9..b80bd60729 100644
--- a/engines/neverhood/graphics.h
+++ b/engines/neverhood/graphics.h
@@ -43,9 +43,11 @@ struct NDimensions {
struct NRect {
int16 x1, y1, x2, y2;
- NRect() : x1(0), y1(0), x2(0), y2(0) {}
-
- NRect(int16 x01, int16 y01, int16 x02, int16 y02) : x1(x01), y1(y01), x2(x02), y2(y02) {}
+ static NRect make(int16 x01, int16 y01, int16 x02, int16 y02) {
+ NRect r;
+ r.set(x01, y01, x02, y02);
+ return r;
+ }
void set(int16 x01, int16 y01, int16 x02, int16 y02) {
x1 = x01;
@@ -62,12 +64,12 @@ struct NRect {
typedef Common::Array<NRect> NRectArray;
-// TODO: Use Common::Rect
+// TODO: Use Common::Rect
struct NDrawRect {
int16 x, y, width, height;
NDrawRect() : x(0), y(0), width(0), height(0) {}
NDrawRect(int16 x0, int16 y0, int16 width0, int16 height0) : x(x0), y(y0), width(width0), height(height0) {}
- int16 x2() { return x + width; }
+ int16 x2() { return x + width; }
int16 y2() { return y + height; }
void set(int16 x0, int16 y0, int16 width0, int16 height0) {
x = x0;
diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp
index 70567806fa..8ed27c825a 100644
--- a/engines/neverhood/klaymen.cpp
+++ b/engines/neverhood/klaymen.cpp
@@ -33,19 +33,19 @@ static const KlaymenIdleTableItem klaymenIdleTable1[] = {
{1, kIdleArms},
{1, kIdleChest},
{1, kIdleHeadOff}
-};
+};
static const KlaymenIdleTableItem klaymenIdleTable2[] = {
{1, kIdlePickEar},
{1, kIdleSpinHead},
{1, kIdleChest},
{1, kIdleHeadOff}
-};
+};
static const KlaymenIdleTableItem klaymenIdleTable3[] = {
{1, kIdleTeleporterHands},
{1, kIdleTeleporterHands2}
-};
+};
static const KlaymenIdleTableItem klaymenIdleTable4[] = {
{1, kIdleSpinHead},
@@ -56,7 +56,7 @@ static const KlaymenIdleTableItem klaymenIdleTable4[] = {
static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
{1, kIdlePickEar},
{2, kIdleWonderAbout}
-};
+};
// Klaymen
@@ -66,7 +66,7 @@ Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRec
_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) {
-
+
createSurface(1000, 320, 200);
_x = x;
_y = y;
@@ -447,7 +447,7 @@ void Klaymen::upIdleAnimation() {
bool Klaymen::stStartActionFromIdle(AnimationCb callback) {
if (_busyStatus == 2) {
_busyStatus = 1;
- _acceptInput = false;
+ _acceptInput = false;
startAnimation(0x9A7020B8, 0, -1);
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmStartAction);
@@ -684,35 +684,35 @@ void Klaymen::suAction() {
_x += _deltaX;
}
_deltaX = 0;
-
+
if (_doDeltaY) {
_y -= _deltaY;
} else {
_y += _deltaY;
}
_deltaY = 0;
-
+
if (_frameChanged) {
if (xdiff > 6)
_x += 6;
else if (xdiff < -6)
_x -= 6;
else
- _x = _destX;
+ _x = _destX;
}
-
+
updateBounds();
-
+
}
void Klaymen::suSneaking() {
-
+
int16 xdiff = _destX - _x;
-
+
if (_currFrameIndex == 9) {
if (xdiff > 26)
_deltaX += xdiff - 26;
- else if (xdiff < -26)
+ else if (xdiff < -26)
_deltaX -= xdiff + 26;
}
@@ -720,7 +720,7 @@ void Klaymen::suSneaking() {
xdiff = _deltaX;
else if (xdiff < -_deltaX)
xdiff = -_deltaX;
- _deltaX = 0;
+ _deltaX = 0;
if (_destX != _x) {
HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y);
@@ -749,7 +749,7 @@ void Klaymen::suSneaking() {
}
updateBounds();
}
-
+
}
void Klaymen::stSneak() {
@@ -761,7 +761,7 @@ void Klaymen::stSneak() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmSneaking);
SetSpriteUpdate(&Klaymen::suSneaking);
- FinalizeState(&Klaymen::evSneakingDone);
+ FinalizeState(&Klaymen::evSneakingDone);
}
void Klaymen::evSneakingDone() {
@@ -801,7 +801,7 @@ void Klaymen::stStartWalking() {
SetMessageHandler(&Klaymen::hmStartWalking);
SetSpriteUpdate(&Klaymen::suWalkingTestExit);
NextState(&Klaymen::stWalkingFirst);
- FinalizeState(&Klaymen::evStartWalkingDone);
+ FinalizeState(&Klaymen::evStartWalkingDone);
}
}
@@ -832,7 +832,7 @@ void Klaymen::stWalkingFirst() {
SetMessageHandler(&Klaymen::hmWalking);
SetSpriteUpdate(&Klaymen::suWalkingFirst);
NextState(&Klaymen::stUpdateWalkingFirst);
- FinalizeState(&Klaymen::evStartWalkingDone);
+ FinalizeState(&Klaymen::evStartWalkingDone);
}
void Klaymen::suWalkingFirst() {
@@ -882,20 +882,20 @@ void Klaymen::stUpdateWalkingFirst() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmSneaking);
SetSpriteUpdate(&Klaymen::suSneaking);
- FinalizeState(&Klaymen::evSneakingDone);
+ FinalizeState(&Klaymen::evSneakingDone);
}
}
void Klaymen::suWalkingTestExit() {
int16 xdiff = ABS(_destX - _x);
int16 xdelta = _destX - _x;
-
+
if (xdelta > _deltaX)
xdelta = _deltaX;
else if (xdelta < -_deltaX)
xdelta = -_deltaX;
-
- _deltaX = 0;
+
+ _deltaX = 0;
if (xdiff == 0 ||
(_actionStatus != 2 && _actionStatus != 3 && xdiff <= 42 && _currFrameIndex >= 5 && _currFrameIndex <= 11) ||
@@ -928,7 +928,7 @@ void Klaymen::suWalkingTestExit() {
}
updateBounds();
}
-
+
}
uint32 Klaymen::hmLever(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1363,7 +1363,7 @@ void Klaymen::stLargeStep() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLargeStep);
SetSpriteUpdate(&Klaymen::suLargeStep);
- FinalizeState(&Klaymen::evLargeStepDone);
+ FinalizeState(&Klaymen::evLargeStepDone);
}
void Klaymen::evLargeStepDone() {
@@ -1372,11 +1372,11 @@ void Klaymen::evLargeStepDone() {
void Klaymen::suLargeStep() {
int16 xdiff = _destX - _x;
-
+
if (_doDeltaX) {
_deltaX = -_deltaX;
}
-
+
if (_currFrameIndex == 7) {
_deltaX = xdiff;
}
@@ -1385,7 +1385,7 @@ void Klaymen::suLargeStep() {
xdiff = _deltaX;
_deltaX = 0;
-
+
if (_x != _destX) {
HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y);
_x += xdiff;
@@ -1420,7 +1420,7 @@ uint32 Klaymen::hmLargeStep(int messageNum, const MessageParam &param, Entity *s
case 0x3002:
_x = _destX;
gotoNextStateExt();
- break;
+ break;
}
return messageResult;
}
@@ -1681,7 +1681,7 @@ void Klaymen::stStartClimbLadderDown() {
_ladderStatus = 2;
_acceptInput = true;
startAnimation(0x122D1505, 29 - _currFrameIndex, -1);
- }
+ }
}
}
@@ -1979,7 +1979,7 @@ uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Enti
break;
case 0x480A:
_isMoveObjectRequested = true;
- return 0;
+ return 0;
}
return hmLowLevelAnimation(messageNum, param, sender);
}
@@ -2521,7 +2521,7 @@ void Klaymen::stInsertKey() {
more = true;
} while (more);
_keysToInsert++;
- }
+ }
}
if (_keysToInsert == 0) {
GotoState(NULL);
@@ -3049,7 +3049,7 @@ void Klaymen::stFallSkipJump() {
void Klaymen::upMoveObject() {
if (_x >= 380)
gotoNextStateExt();
- Klaymen::update();
+ Klaymen::update();
}
uint32 Klaymen::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
@@ -3165,7 +3165,7 @@ void Klaymen::stTumbleHeadless() {
void Klaymen::stCloseEyes() {
if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stCloseEyes))) {
_busyStatus = 1;
- _acceptInput = false;
+ _acceptInput = false;
startAnimation(0x5420E254, 0, -1);
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLowLevel);
@@ -3358,7 +3358,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
- break;
+ break;
case 0x4804:
if (param.asInteger() == 2)
GotoState(&Klaymen::stSleeping);
@@ -3380,7 +3380,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -3408,10 +3408,10 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2002, 0);
GotoState(&Klaymen::stWakeUp);
}
- break;
+ break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -3423,7 +3423,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
setKlaymenIdleTable1();
}
@@ -3438,7 +3438,7 @@ void KmScene1002::xUpdate() {
_idleTableNum = 0;
}
}
-
+
uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x2001:
@@ -3451,7 +3451,7 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
- case 0x4004:
+ case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
break;
case 0x4803:
@@ -3479,42 +3479,42 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
break;
}
break;
- case 0x480A:
+ case 0x480A:
GotoState(&Klaymen::stMoveVenusFlyTrap);
break;
- case 0x480D:
+ case 0x480D:
GotoState(&Klaymen::stJumpToRingVenusFlyTrap);
break;
- case 0x4816:
+ case 0x4816:
if (param.asInteger() == 0)
GotoState(&Klaymen::stPressDoorButton);
break;
- case 0x4817:
+ case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
break;
- case 0x481B:
+ case 0x481B:
startWalkToAttachedSpriteXDistance(param.asInteger());
break;
- case 0x4820:
+ case 0x4820:
sendMessage(_parentScene, 0x2005, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
break;
- case 0x4821:
+ case 0x4821:
sendMessage(_parentScene, 0x2005, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
+ GotoState(&Klaymen::stStartClimbLadderDown);
break;
- case 0x4822:
+ case 0x4822:
sendMessage(_parentScene, 0x2005, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
+ GotoState(&Klaymen::stStartClimbLadderUp);
break;
case 0x4823:
sendMessage(_parentScene, 0x2006, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
+ GotoState(&Klaymen::stClimbLadderHalf);
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -3529,7 +3529,7 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
- case 0x4840:
+ case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
@@ -3540,8 +3540,8 @@ uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x01900A04);
+
+ _dataResource.load(0x01900A04);
}
uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -3606,7 +3606,7 @@ uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
// Empty
}
@@ -3615,7 +3615,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x2000:
_isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
+ messageResult = 1;
break;
case 0x4001:
case 0x4800:
@@ -3653,7 +3653,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -3673,7 +3673,7 @@ uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
_doYHitIncr = true;
}
@@ -3741,7 +3741,7 @@ uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
// Empty
}
@@ -3762,8 +3762,8 @@ uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
- // Empty
+
+ // Empty
}
uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -3774,7 +3774,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
- break;
+ break;
case 0x4812:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
@@ -3792,7 +3792,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
+ break;
case 0x481F:
if (param.asInteger() == 1)
GotoState(&Klaymen::stTurnAwayFromUse);
@@ -3803,7 +3803,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -3814,7 +3814,7 @@ uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -3825,10 +3825,10 @@ uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
- break;
+ break;
case 0x4804:
GotoState(&Klaymen::stCrashDown);
- break;
+ break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
@@ -3839,7 +3839,7 @@ uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
// Empty
}
@@ -3879,9 +3879,9 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -3936,7 +3936,7 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -3944,13 +3944,13 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483D:
teleporterAppear(0xEE084A04);
- break;
+ break;
case 0x483E:
teleporterDisappear(0xB86A4274);
- break;
+ break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -3961,7 +3961,7 @@ uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -3978,7 +3978,7 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
+ break;
case 0x480D:
GotoState(&Klaymen::stUseLever);
break;
@@ -3993,12 +3993,12 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481A:
if (param.asInteger() == 1)
- GotoState(&Klaymen::stInsertKey);
+ GotoState(&Klaymen::stInsertKey);
else
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -4020,7 +4020,7 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4032,8 +4032,8 @@ uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
- // Empty
+
+ // Empty
}
uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4044,13 +4044,13 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
- break;
+ break;
case 0x480A:
if (param.asInteger() == 1)
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
+ break;
case 0x4816:
if (param.asInteger() == 1)
GotoState(&Klaymen::stPressButton);
@@ -4068,7 +4068,7 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
+ break;
case 0x481F:
if (param.asInteger() == 1)
GotoState(&Klaymen::stTurnAwayFromUse);
@@ -4101,8 +4101,8 @@ uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
- SetFilterY(&Sprite::defFilterY);
+
+ SetFilterY(&Sprite::defFilterY);
}
uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4113,13 +4113,13 @@ uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4004:
GotoState(&Klaymen::stTryStandIdle);
- break;
+ break;
case 0x480A:
if (param.asInteger() == 1)
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
+ break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
@@ -4129,7 +4129,7 @@ uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
+ break;
case 0x481D:
GotoState(&Klaymen::stTurnToUse);
break;
@@ -4162,7 +4162,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
+ break;
case 0x480D:
GotoState(&Klaymen::stUseLever);
break;
@@ -4177,7 +4177,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -4189,7 +4189,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4202,7 +4202,7 @@ uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4219,7 +4219,7 @@ uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
else
GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
+ break;
case 0x4812:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
@@ -4233,7 +4233,7 @@ uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
gotoNextStateExt();
break;
case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -4307,7 +4307,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -4345,7 +4345,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2032, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2032, 0);
_isSittingInTeleporter = false;
@@ -4353,7 +4353,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4366,7 +4366,7 @@ uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4388,7 +4388,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4803:
GotoState(&Klaymen::stFallSkipJump);
- break;
+ break;
case 0x4812:
if (param.asInteger() == 2)
GotoState(&Klaymen::stPickUpNeedle);
@@ -4435,7 +4435,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -4443,10 +4443,10 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483D:
teleporterAppear(0x5E0A4905);
- break;
+ break;
case 0x483E:
teleporterDisappear(0xD86E4477);
- break;
+ break;
}
return messageResult;
}
@@ -4454,7 +4454,7 @@ uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4469,7 +4469,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481D:
GotoState(&Klaymen::stTurnToUse);
break;
@@ -4482,7 +4482,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4493,7 +4493,7 @@ uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
- // Empty
+ // Empty
}
uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
@@ -4557,7 +4557,7 @@ uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
// Empty
}
@@ -4600,7 +4600,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -4622,7 +4622,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -4635,7 +4635,7 @@ uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
teleporterDisappear(0x9A28CA1C);
break;
}
- return messageResult;
+ return messageResult;
}
KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
@@ -4684,7 +4684,7 @@ uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -4698,12 +4698,12 @@ uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
- return 0;
+ return 0;
}
KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
@@ -4711,7 +4711,7 @@ KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
// Empty
}
-
+
uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
@@ -4740,7 +4740,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
@@ -4748,7 +4748,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
GotoState(&Klaymen::stClayDoorOpen);
break;
case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -4768,7 +4768,7 @@ uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4785,7 +4785,7 @@ KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
void KmScene2205::xUpdate() {
setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
}
-
+
uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
@@ -4809,13 +4809,13 @@ uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4837,7 +4837,7 @@ KmScene2206::~KmScene2206() {
void KmScene2206::xUpdate() {
setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
}
-
+
uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
@@ -4874,7 +4874,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -4897,7 +4897,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -4914,7 +4914,7 @@ uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -4927,7 +4927,7 @@ KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
// Empty
}
-
+
uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x2001:
@@ -4961,7 +4961,7 @@ uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -4977,7 +4977,7 @@ uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -5022,7 +5022,7 @@ uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -5080,7 +5080,7 @@ uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481F:
if (param.asInteger() == 0)
GotoState(&Klaymen::stWonderAboutHalf);
@@ -5133,7 +5133,7 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481F:
if (param.asInteger() == 0)
GotoState(&Klaymen::stWonderAboutHalf);
@@ -5156,13 +5156,13 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
}
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) {
@@ -5184,7 +5184,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
@@ -5203,7 +5203,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -5228,7 +5228,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
- break;
+ break;
case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
@@ -5357,23 +5357,23 @@ uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
else
GotoState(&Klaymen::stWonderAbout);
break;
- case 0x4820:
+ case 0x4820:
sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
break;
- case 0x4821:
+ case 0x4821:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
+ GotoState(&Klaymen::stStartClimbLadderDown);
break;
- case 0x4822:
+ case 0x4822:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
+ GotoState(&Klaymen::stStartClimbLadderUp);
break;
case 0x4823:
sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
+ GotoState(&Klaymen::stClimbLadderHalf);
break;
case 0x482D:
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
@@ -5382,16 +5382,16 @@ uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
- case 0x4840:
+ 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);
}
@@ -5425,7 +5425,7 @@ uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
gotoNextStateExt();
break;
case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -5451,40 +5451,40 @@ uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
else
GotoState(&Klaymen::stWonderAbout);
break;
- case 0x4820:
+ case 0x4820:
sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
break;
- case 0x4821:
+ case 0x4821:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
+ GotoState(&Klaymen::stStartClimbLadderDown);
break;
- case 0x4822:
+ case 0x4822:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
+ GotoState(&Klaymen::stStartClimbLadderUp);
break;
case 0x4823:
sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
+ GotoState(&Klaymen::stClimbLadderHalf);
break;
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
- case 0x4840:
+ 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) {
@@ -5505,7 +5505,7 @@ uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481D:
if (_isSittingInTeleporter)
GotoState(&Klaymen::stTurnToUseInTeleporter);
@@ -5521,7 +5521,7 @@ uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -5536,7 +5536,7 @@ KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
// Empty
}
-
+
uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4804:
@@ -5570,13 +5570,13 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481B:
if (param.asPoint().y != 0)
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
else
startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
+ break;
case 0x481D:
GotoState(&Klaymen::stTurnToUse);
break;
@@ -5599,7 +5599,7 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -5620,7 +5620,7 @@ uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
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);
}
@@ -5648,7 +5648,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
@@ -5664,7 +5664,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
else
GotoState(&Klaymen::stWonderAboutHalf);
break;
- case 0x482E:
+ case 0x482E:
GotoState(&Klaymen::stWalkToFront);
break;
case 0x482F:
@@ -5682,7 +5682,7 @@ uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
-
+
_dataResource.load(0x81120132);
}
@@ -5759,7 +5759,7 @@ uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x481D:
if (_isSittingInTeleporter)
GotoState(&Klaymen::stTurnToUseInTeleporter);
@@ -5775,7 +5775,7 @@ uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
sendMessage(_parentScene, 0x2000, 1);
_isSittingInTeleporter = true;
GotoState(&Klaymen::stSitInTeleporter);
- break;
+ break;
case 0x4836:
sendMessage(_parentScene, 0x2000, 0);
_isSittingInTeleporter = false;
@@ -5805,7 +5805,7 @@ KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
loadSound(6, 0x166FC6E0);
loadSound(7, 0x00018040);
}
-
+
_dataResource.load(0x98182003);
_surface->setClipRects(clipRects, clipRectsCount);
}
@@ -5827,12 +5827,12 @@ uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4816:
if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
+ GotoState(&Klaymen::stPressButtonSide);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
@@ -5885,12 +5885,12 @@ uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4816:
if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
+ GotoState(&Klaymen::stPressButtonSide);
break;
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
@@ -5907,7 +5907,7 @@ uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
return 0;
}
-KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
: Klaymen(vm, parentScene, x, y) {
// Empty
@@ -5925,7 +5925,7 @@ uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &para
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
break;
@@ -5937,7 +5937,7 @@ uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &para
else
GotoState(&Klaymen::stWonderAboutSmall);
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStepSmall);
else
@@ -5961,7 +5961,7 @@ KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
_surface->setClipRects(clipRects, clipRectsCount);
}
-
+
uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
@@ -5985,7 +5985,7 @@ uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4817:
setDoDeltaX(param.asInteger());
gotoNextStateExt();
- break;
+ break;
case 0x4818:
startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
break;
@@ -6009,23 +6009,23 @@ uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
else
GotoState(&Klaymen::stWonderAbout);
break;
- case 0x4820:
+ case 0x4820:
sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
break;
- case 0x4821:
+ case 0x4821:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
+ GotoState(&Klaymen::stStartClimbLadderDown);
break;
- case 0x4822:
+ case 0x4822:
sendMessage(_parentScene, 0x2000, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
+ GotoState(&Klaymen::stStartClimbLadderUp);
break;
case 0x4823:
sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
+ GotoState(&Klaymen::stClimbLadderHalf);
break;
case 0x4824:
sendMessage(_parentScene, 0x2000, 0);
@@ -6080,7 +6080,7 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
gotoNextStateExt();
break;
case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
+ GotoState(&Klaymen::stInsertDisk);
break;
case 0x481B:
if (param.asPoint().y != 0)
@@ -6094,29 +6094,29 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x481E:
GotoState(&Klaymen::stReturnFromUse);
break;
- case 0x4820:
+ case 0x4820:
sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
break;
- case 0x4821:
+ case 0x4821:
sendMessage(_parentScene, 0x2001, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
+ GotoState(&Klaymen::stStartClimbLadderDown);
break;
- case 0x4822:
+ case 0x4822:
sendMessage(_parentScene, 0x2001, 0);
_destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
+ GotoState(&Klaymen::stStartClimbLadderUp);
break;
case 0x4823:
sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
+ GotoState(&Klaymen::stClimbLadderHalf);
break;
case 0x482D:
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
gotoNextStateExt();
break;
- case 0x482E:
+ case 0x482E:
if (param.asInteger() == 1)
GotoState(&Klaymen::stWalkToFrontNoStep);
else
@@ -6131,7 +6131,7 @@ uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x483F:
startSpecialWalkRight(param.asInteger());
break;
- case 0x4840:
+ case 0x4840:
startSpecialWalkLeft(param.asInteger());
break;
}
diff --git a/engines/neverhood/klaymen.h b/engines/neverhood/klaymen.h
index 25443b5a35..9e461a9c9c 100644
--- a/engines/neverhood/klaymen.h
+++ b/engines/neverhood/klaymen.h
@@ -77,24 +77,24 @@ public:
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();
void stTryStandIdle();
void stStandAround();
void upStandIdle();
void stIdleBlink();
-
+
bool stStartAction(AnimationCb callback3);
bool stStartActionFromIdle(AnimationCb callback);
uint32 hmStartAction(int messageNum, const MessageParam &param, Entity *sender);
@@ -134,7 +134,7 @@ public:
void stPickUpTube();
uint32 hmPickUpTube(int messageNum, const MessageParam &param, Entity *sender);
-
+
void stTurnToUse();
void stTurnToUseHalf();
void stTurnAwayFromUse();
@@ -263,10 +263,10 @@ public:
void stJumpToGrabFall();
uint32 hmJumpToGrab(int messageNum, const MessageParam &param, Entity *sender);
void suJumpToGrab();
-
+
void stJumpToGrabRelease();
uint32 hmJumpToGrabRelease(int messageNum, const MessageParam &param, Entity *sender);
-
+
void stSitInTeleporter();
uint32 hmSitInTeleporter(int messageNum, const MessageParam &param, Entity *sender);
@@ -326,7 +326,7 @@ public:
void stFinishGrow();
uint32 hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender);
-
+
void stJumpToRingVenusFlyTrap();
uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
@@ -363,7 +363,7 @@ public:
////////////////////////////////////////////////////////////////////////////
void stopWalking();
-
+
void suAction();
void suUpdateDestX();
void suWalkingTestExit();
@@ -375,7 +375,7 @@ public:
void setKlaymenIdleTable1();
void setKlaymenIdleTable2();
void setKlaymenIdleTable3();
-
+
void setSoundFlag(bool value) { _soundFlag = value; }
void spitIntoPipe();
@@ -416,7 +416,7 @@ protected:
NPointArray *_pathPoints;
bool _soundFlag;
-
+
int16 _spitOutCountdown;
bool _isSittingInTeleporter;
@@ -456,16 +456,16 @@ protected:
void stStartWalkingSmall();
uint32 hmWalkingSmall(int messageNum, const MessageParam &param, Entity *sender);
-
+
void enterIdleAnimation(uint idleAnimation);
void walkAlongPathPoints();
-
+
};
class KmScene1001 : public Klaymen {
public:
KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
+protected:
uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
@@ -473,7 +473,7 @@ class KmScene1002 : public Klaymen {
public:
KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
protected:
- void xUpdate();
+ void xUpdate();
uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index da7abd41e1..7bf64a4602 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -73,9 +73,9 @@ static const uint32 kMakingOfSmackerFileHashList[] = {
MenuModule::MenuModule(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule), _savegameList(NULL) {
-
+
SetMessageHandler(&MenuModule::handleMessage);
-
+
_savedPaletteData = _vm->_screen->getPaletteData();
_vm->_mixer->pauseAll(true);
_vm->toggleSoundUpdate(false);
@@ -266,7 +266,7 @@ void MenuModule::loadSavegameList() {
Neverhood::NeverhoodEngine::SaveHeader header;
Common::String pattern = _vm->getTargetName();
pattern += ".???";
-
+
Common::StringArray filenames;
filenames = saveFileMan->listSavefiles(pattern.c_str());
Common::sort(filenames.begin(), filenames.end());
@@ -324,7 +324,7 @@ uint32 MenuButton::handleMessage(int messageNum, const MessageParam &param, Enti
MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule) {
-
+
static const uint32 kMenuButtonFileHashes[] = {
0x36C62120,
0x56C62120,
@@ -336,26 +336,26 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
0x16C62130,
0x16C62100
};
-
+
static const NRect kMenuButtonCollisionBounds[] = {
- NRect(52, 121, 110, 156),
- NRect(52, 192, 109, 222),
- NRect(60, 257, 119, 286),
- NRect(67, 326, 120, 354),
- NRect(70, 389, 128, 416),
- NRect(523, 113, 580, 144),
- NRect(525, 176, 577, 206),
- NRect(527, 384, 580, 412),
- NRect(522, 255, 580, 289)
+ { 52, 121, 110, 156 },
+ { 52, 192, 109, 222 },
+ { 60, 257, 119, 286 },
+ { 67, 326, 120, 354 },
+ { 70, 389, 128, 416 },
+ { 523, 113, 580, 144 },
+ { 525, 176, 577, 206 },
+ { 527, 384, 580, 412 },
+ { 522, 255, 580, 289 }
};
-
+
setBackground(0x08C0020C);
setPalette(0x08C0020C);
insertScreenMouse(0x00208084);
-
+
insertStaticSprite(0x41137051, 100);
insertStaticSprite(0xC10B2015, 100);
-
+
// TODO Only if music is enabled
_musicOnButton = insertStaticSprite(0x0C24C0EE, 100);
@@ -364,9 +364,9 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
kMenuButtonFileHashes[buttonIndex], kMenuButtonCollisionBounds[buttonIndex]);
addCollisionSprite(menuButton);
}
-
- SetUpdateHandler(&Scene::update);
- SetMessageHandler(&MainMenu::handleMessage);
+
+ SetUpdateHandler(&Scene::update);
+ SetMessageHandler(&MainMenu::handleMessage);
}
@@ -396,18 +396,18 @@ CreditsScene::CreditsScene(NeverhoodEngine *vm, Module *parentModule, bool canAb
: Scene(vm, parentModule), _canAbort(canAbort), _screenIndex(0), _ticksDuration(0),
_countdown(216) {
- SetUpdateHandler(&CreditsScene::update);
+ SetUpdateHandler(&CreditsScene::update);
SetMessageHandler(&CreditsScene::handleMessage);
-
+
setBackground(0x6081128C);
setPalette(0x6081128C);
_ticksTime = _vm->_system->getMillis() + 202100;
-
+
_musicResource = new MusicResource(_vm);
_musicResource->load(0x30812225);
_musicResource->play(0);
-
+
}
CreditsScene::~CreditsScene() {
@@ -469,7 +469,7 @@ Widget::Widget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene
SetUpdateHandler(&Widget::update);
SetMessageHandler(&Widget::handleMessage);
-
+
setPosition(x, y);
}
@@ -532,7 +532,7 @@ TextLabelWidget::TextLabelWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStat
const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface)
: Widget(vm, x, y, parentScene, baseObjectPriority, baseSurfacePriority),
_string(string), _stringLen(stringLen), _drawSurface(drawSurface), _tx(tx), _ty(ty), _fontSurface(fontSurface) {
-
+
}
void TextLabelWidget::initialize() {
@@ -573,7 +573,7 @@ TextEditWidget::TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateM
_maxVisibleChars = (_rect.x2 - _rect.x1) / _fontSurface->getCharWidth();
_cursorPos = 0;
-
+
SetUpdateHandler(&TextEditWidget::update);
SetMessageHandler(&TextEditWidget::handleMessage);
}
@@ -804,7 +804,7 @@ void SavegameListBox::buildItems() {
void SavegameListBox::drawItems() {
for (int i = 0; i < (int)_textLabelItems.size(); ++i) {
- TextLabelWidget *label = _textLabelItems[i];
+ TextLabelWidget *label = _textLabelItems[i];
if (i >= _firstVisibleItem && i <= _lastVisibleItem) {
label->setY(_rect.y1 + (i - _firstVisibleItem) * _fontSurface->getCharHeight());
label->updateBounds();
@@ -886,12 +886,12 @@ int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc)
GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList,
const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds,
uint32 backgroundFileHash, uint32 fontFileHash,
- uint32 mouseFileHash, const NRect *mouseRect,
+ uint32 mouseFileHash, const NRect *mouseRect,
uint32 listBoxBackgroundFileHash, int16 listBoxX, int16 listBoxY, const NRect &listBoxRect,
uint32 textEditBackgroundFileHash, uint32 textEditCursorFileHash, int16 textEditX, int16 textEditY, const NRect &textEditRect,
- uint32 textFileHash1, uint32 textFileHash2)
+ uint32 textFileHash1, uint32 textFileHash2)
: Scene(vm, parentModule), _currWidget(NULL), _savegameList(savegameList) {
-
+
bool isSave = (textEditCursorFileHash != 0);
_fontSurface = new FontSurface(_vm, fontFileHash, 32, 7, 32, 11, 17);
@@ -933,7 +933,7 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
_textEditWidget->setReadOnly(true);
_textEditWidget->initialize();
setCurrWidget(_textEditWidget);
-
+
for (uint buttonIndex = 0; buttonIndex < 6; ++buttonIndex) {
Sprite *menuButton = insertSprite<MenuButton>(this, buttonIndex,
buttonFileHashes[buttonIndex], buttonCollisionBounds[buttonIndex]);
@@ -1026,17 +1026,17 @@ static const uint32 kSaveGameMenuButtonFileHashes[] = {
};
static const NRect kSaveGameMenuButtonCollisionBounds[] = {
- NRect(518, 106, 602, 160),
- NRect(516, 378, 596, 434),
- NRect(394, 108, 458, 206),
- NRect(400, 204, 458, 276),
- NRect(398, 292, 456, 352),
- NRect(396, 352, 460, 444)
+ { 518, 106, 602, 160 },
+ { 516, 378, 596, 434 },
+ { 394, 108, 458, 206 },
+ { 400, 204, 458, 276 },
+ { 398, 292, 456, 352 },
+ { 396, 352, 460, 444 }
};
-static const NRect kSaveGameMenuListBoxRect(0, 0, 320, 272);
-static const NRect kSaveGameMenuTextEditRect(0, 0, 377, 17);
-static const NRect kSaveGameMenuMouseRect(50, 47, 427, 64);
+static const NRect kSaveGameMenuListBoxRect = { 0, 0, 320, 272 };
+static const NRect kSaveGameMenuTextEditRect = { 0, 0, 377, 17 };
+static const NRect kSaveGameMenuMouseRect = { 50, 47, 427, 64 };
SaveGameMenu::SaveGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList)
: GameStateMenu(vm, parentModule, savegameList, kSaveGameMenuButtonFileHashes, kSaveGameMenuButtonCollisionBounds,
@@ -1060,17 +1060,17 @@ static const uint32 kLoadGameMenuButtonFileHashes[] = {
};
static const NRect kLoadGameMenuButtonCollisionBounds[] = {
- NRect( 44, 115, 108, 147),
- NRect( 52, 396, 112, 426),
- NRect(188, 116, 245, 196),
- NRect(189, 209, 239, 269),
- NRect(187, 301, 233, 349),
- NRect(182, 358, 241, 433)
+ { 44, 115, 108, 147 },
+ { 52, 396, 112, 426 },
+ { 188, 116, 245, 196 },
+ { 189, 209, 239, 269 },
+ { 187, 301, 233, 349 },
+ { 182, 358, 241, 433 }
};
-static const NRect kLoadGameMenuListBoxRect(0, 0, 320, 271);
-static const NRect kLoadGameMenuTextEditRect(0, 0, 320, 17);
-static const NRect kLoadGameMenuMouseRect(263, 48, 583, 65);
+static const NRect kLoadGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kLoadGameMenuTextEditRect = { 0, 0, 320, 17 };
+static const NRect kLoadGameMenuMouseRect = { 263, 48, 583, 65 };
LoadGameMenu::LoadGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList)
: GameStateMenu(vm, parentModule, savegameList, kLoadGameMenuButtonFileHashes, kLoadGameMenuButtonCollisionBounds,
@@ -1093,21 +1093,21 @@ static const uint32 kDeleteGameMenuButtonFileHashes[] = {
};
static const NRect kDeleteGameMenuButtonCollisionBounds[] = {
- NRect(518, 46, 595, 91),
- NRect(524, 322, 599, 369),
- NRect(395, 40, 462, 127),
- NRect(405, 126, 460, 185),
- NRect(397, 205, 456, 273),
- NRect(395, 278, 452, 372)
+ { 518, 46, 595, 91 },
+ { 524, 322, 599, 369 },
+ { 395, 40, 462, 127 },
+ { 405, 126, 460, 185 },
+ { 397, 205, 456, 273 },
+ { 395, 278, 452, 372 }
};
-static const NRect kDeleteGameMenuListBoxRect(0, 0, 320, 271);
-static const NRect kDeleteGameMenuTextEditRect(0, 0, 320, 17);
+static const NRect kDeleteGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kDeleteGameMenuTextEditRect = { 0, 0, 320, 17 };
DeleteGameMenu::DeleteGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList)
: GameStateMenu(vm, parentModule, savegameList, kDeleteGameMenuButtonFileHashes, kDeleteGameMenuButtonCollisionBounds,
0x4080E01C, 0x728523ED,
- 0x0E018400, NULL,
+ 0x0E018400, NULL,
0xA5584211, 61, 64, kDeleteGameMenuListBoxRect,
0x250A3060, 0, 49, 414, kDeleteGameMenuTextEditRect,
0x80083C01, 0x84181E81) {
@@ -1128,10 +1128,10 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule
};
static const NRect kQueryOverwriteMenuCollisionBounds[] = {
- NRect(145, 334, 260, 385),
- NRect(365, 340, 477, 388)
+ { 145, 334, 260, 385 },
+ { 365, 340, 477, 388 }
};
-
+
setBackground(0x043692C4);
setPalette(0x043692C4);
insertScreenMouse(0x692C004B);
@@ -1154,7 +1154,7 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule
fontSurface->drawString(_background->getSurface(), 106 + (423 - textLines[i].size() * 11) / 2,
127 + 31 + i * 17, (const byte*)textLines[i].c_str());
delete fontSurface;
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&QueryOverwriteMenu::handleMessage);
}
diff --git a/engines/neverhood/menumodule.h b/engines/neverhood/menumodule.h
index 6ee990de67..f201654ceb 100644
--- a/engines/neverhood/menumodule.h
+++ b/engines/neverhood/menumodule.h
@@ -124,8 +124,8 @@ protected:
class TextLabelWidget : public Widget {
public:
TextLabelWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene,
- int baseObjectPriority, int baseSurfacePriority,
- const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface);
+ int baseObjectPriority, int baseSurfacePriority,
+ const byte *string, int stringLen, BaseSurface *drawSurface, int16 tx, int16 ty, FontSurface *fontSurface);
virtual void initialize();
virtual int16 getWidth();
virtual int16 getHeight();
@@ -206,13 +206,13 @@ protected:
uint _currIndex;
int _maxVisibleItemsCount;
};
-
+
class GameStateMenu : public Scene {
public:
GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList,
const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds,
uint32 backgroundFileHash, uint32 fontFileHash,
- uint32 mouseFileHash, const NRect *mouseRect,
+ uint32 mouseFileHash, const NRect *mouseRect,
uint32 listBoxBackgroundFileHash, int16 listBoxX, int16 listBoxY, const NRect &listBoxRect,
uint32 textEditBackgroundFileHash, uint32 textEditCursorFileHash, int16 textEditX, int16 textEditY, const NRect &textEditRect,
uint32 textFileHash1, uint32 textFileHash2);
diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp
index e384b5a4d2..d1578e680c 100644
--- a/engines/neverhood/module.cpp
+++ b/engines/neverhood/module.cpp
@@ -31,9 +31,9 @@ namespace Neverhood {
Module::Module(NeverhoodEngine *vm, Module *parentModule)
: Entity(vm, 0), _parentModule(parentModule), _childObject(NULL),
_done(false), _sceneType(kSceneTypeNormal) {
-
+
SetMessageHandler(&Module::handleMessage);
-
+
}
Module::~Module() {
diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp
index a28d934cf6..f65b89899d 100644
--- a/engines/neverhood/modules/module1000.cpp
+++ b/engines/neverhood/modules/module1000.cpp
@@ -26,8 +26,8 @@ namespace Neverhood {
Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
- _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
+
+ _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
_vm->_soundMan->addMusic(0x03294419, 0x061880C6);
_vm->_soundMan->addMusic(0x03294419, _musicFileHash);
@@ -118,11 +118,11 @@ void Module1000::updateScene() {
}
}
-// Scene1001
+// Scene1001
AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100) {
-
+
createSurface(800, 137, 242);
_x = 726;
_y = 440;
@@ -151,16 +151,16 @@ void AsScene1001Door::hammerHitsDoor() {
case 1:
playSound(0, 0x65482F03);
startAnimation(0x624C0498, 1, 3);
- NextState(&AsScene1001Door::stShowIdleDoor);
+ NextState(&AsScene1001Door::stShowIdleDoor);
break;
case 2:
playSound(1);
startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorMove);
+ NextState(&AsScene1001Door::stBustedDoorMove);
break;
default:
// Nothing
- break;
+ break;
}
incGlobalVar(V_DOOR_STATUS, 1);
}
@@ -196,9 +196,9 @@ void AsScene1001Door::stBustedDoorMove() {
void AsScene1001Door::stBustedDoorGone() {
playSound(0);
stopAnimation();
- setVisible(false);
+ setVisible(false);
}
-
+
AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
: AnimatedSprite(vm, 1100), _asDoor(asDoor) {
@@ -262,7 +262,7 @@ uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &para
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);
@@ -302,22 +302,22 @@ uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param
}
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;
+ _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) {
@@ -330,19 +330,19 @@ uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &p
}
return messageResult;
}
-
+
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asDoor(NULL), _asWindow(NULL) {
Sprite *tempSprite;
SetMessageHandler(&Scene1001::handleMessage);
-
+
setHitRects(0x004B4860);
setBackground(0x4086520E);
setPalette(0x4086520E);
insertScreenMouse(0x6520A400);
-
+
if (which < 0) {
// Restoring game
setRectList(0x004B49F0);
@@ -373,7 +373,7 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
tempSprite = insertStaticSprite(0x2080A3A8, 1300);
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
-
+
if (!getGlobalVar(V_DOOR_BUSTED)) {
_asDoor = insertSprite<AsScene1001Door>();
_asDoor->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
@@ -445,7 +445,7 @@ AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool i
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
SetUpdateHandler(&AsScene1002Ring::update);
-
+
if (_isSpecial) {
createSurface(990, 68, 314);
if (isRingLow) {
@@ -581,7 +581,7 @@ uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param
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);
@@ -637,7 +637,7 @@ AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine
createSurface(1025, 88, 165);
setVisible(false);
SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
+ SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
}
uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -716,7 +716,7 @@ void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
}
-SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+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;
@@ -788,7 +788,7 @@ AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *par
stRingGrabbed();
} else {
stIdle();
- }
+ }
}
_flags = 4;
SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
@@ -850,12 +850,12 @@ uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam
if (_isSecond) {
if (_x >= 154 && _x <= 346)
messageResult = 1;
- else
+ else
messageResult = 0;
} else {
if (_x >= 174 && _x <= 430)
messageResult = 1;
- else
+ else
messageResult = 0;
}
break;
@@ -1023,7 +1023,7 @@ AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngi
} else
setVisible(false);
SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
}
void AsScene1002OutsideDoorBackground::update() {
@@ -1083,7 +1083,7 @@ void AsScene1002OutsideDoorBackground::stDoorClosed() {
AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
: AnimatedSprite(vm, 1200), _klaymen(klaymen) {
-
+
createSurface(1200, 40, 163);
setVisible(false);
SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
@@ -1095,15 +1095,15 @@ void AsScene1002KlaymenLadderHands::update() {
startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
_newStickFrameIndex = _klaymen->getFrameIndex();
setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
+ _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();
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
} else
setVisible(false);
@@ -1113,7 +1113,7 @@ void AsScene1002KlaymenLadderHands::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);
@@ -1245,7 +1245,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
-
+
setRectList(0x004B43A0);
loadSound(1, 0x60755842);
@@ -1322,11 +1322,11 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x2002:
_messageList = NULL;
- break;
+ break;
case 0x2005:
_isClimbingLadder = true;
setRectList(0x004B4418);
- break;
+ break;
case 0x2006:
_isClimbingLadder = false;
setRectList(0x004B43A0);
@@ -1360,11 +1360,11 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
sendMessage(_asRing3, 0x4807, 0);
}
- }
+ }
break;
case 0x480B:
sendEntityMessage(_klaymen, 0x1014, _asDoorSpy);
- break;
+ break;
case 0x480F:
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(1);
@@ -1379,7 +1379,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
setSpriteSurfacePriority(_ssCeiling, 1015);
setSpriteSurfacePriority(_ssLadderArch, 1015);
break;
- }
+ }
return messageResult;
}
@@ -1389,7 +1389,7 @@ StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backg
: Scene(vm, parentModule) {
SetMessageHandler(&StaticScene::handleMessage);
-
+
setBackground(backgroundFileHash);
setPalette(backgroundFileHash);
insertPuzzleMouse(cursorFileHash, 20, 620);
@@ -1442,7 +1442,7 @@ Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
Sprite *tempSprite;
-
+
SetUpdateHandler(&Scene1004::update);
SetMessageHandler(&Scene1004::handleMessage);
@@ -1475,16 +1475,16 @@ Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
insertKlaymen<KmScene1004>(_dataResource.getPoint(0x80052A29).x, 27);
setMessageList(0x004B7BF0);
}
-
+
updatePaletteArea();
-
+
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
insertStaticSprite(0x800034A0, 1100);
insertStaticSprite(0x64402020, 1100);
insertStaticSprite(0x3060222E, 1300);
tempSprite = insertStaticSprite(0x0E002004, 1300);
-
+
_klaymen->setClipRect(0, tempSprite->getDrawRect().y, 640, 480);
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
@@ -1518,7 +1518,7 @@ uint32 Scene1004::handleMessage(int messageNum, const MessageParam &param, Entit
break;
}
return messageResult;
-}
+}
void Scene1004::updatePaletteArea() {
if (_klaymen->getY() < 150) {
@@ -1557,7 +1557,7 @@ Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
}
drawTextToBackground();
-
+
}
uint32 Scene1005::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1565,7 +1565,7 @@ uint32 Scene1005::handleMessage(int messageNum, const MessageParam &param, Entit
switch (messageNum) {
case 0x0001:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
- leaveScene(0);
+ leaveScene(0);
break;
}
return 0;
@@ -1614,19 +1614,19 @@ uint32 Scene1005::getTextIndex1() {
textIndex = 23;
else if (!getSubVar(VA_HAS_KEY, 0) && !getSubVar(VA_IS_KEY_INSERTED, 0))
textIndex = 24;
- else if (!getGlobalVar(V_HAS_FINAL_KEY))
+ else if (!getGlobalVar(V_HAS_FINAL_KEY))
textIndex = 26;
else if (!getSubVar(VA_HAS_KEY, 1) && !getSubVar(VA_IS_KEY_INSERTED, 1))
textIndex = 27;
- else if (!getGlobalVar(V_HAS_FINAL_KEY))
+ else if (!getGlobalVar(V_HAS_FINAL_KEY))
textIndex = 28;
- else
+ else
textIndex = 29;
} else if (!getGlobalVar(V_FELL_DOWN_HOLE))
textIndex = 20;
else if (!getGlobalVar(V_SEEN_SYMBOLS_NO_LIGHT))
textIndex = 21;
- else
+ else
textIndex = 22;
} else if (getGlobalVar(V_BOLT_DOOR_UNLOCKED)) {
if (!getGlobalVar(V_WALL_BROKEN))
@@ -1641,7 +1641,7 @@ uint32 Scene1005::getTextIndex1() {
textIndex = 15;
else if (!getGlobalVar(V_BEEN_STATUE_ROOM))
textIndex = 16;
- else
+ else
textIndex = 17;
} else if (!getGlobalVar(V_FLYTRAP_RING_EATEN)) {
textIndex = 0;
@@ -1660,7 +1660,7 @@ uint32 Scene1005::getTextIndex1() {
textIndex = 9;
else if (!getSubVar(VA_LOCKS_DISABLED, 0x01180951))
textIndex = 10;
- else
+ else
textIndex = 11;
} else if (!getGlobalVar(V_CREATURE_ANGRY)) {
textIndex = 1;
diff --git a/engines/neverhood/modules/module1000.h b/engines/neverhood/modules/module1000.h
index 9977590a6a..8461ecfc6f 100644
--- a/engines/neverhood/modules/module1000.h
+++ b/engines/neverhood/modules/module1000.h
@@ -85,7 +85,7 @@ protected:
Scene *_parentScene;
uint32 _soundFileHash;
int16 _countdown;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp
index dbd8c60210..faa0516d7e 100644
--- a/engines/neverhood/modules/module1100.cpp
+++ b/engines/neverhood/modules/module1100.cpp
@@ -40,7 +40,7 @@ static const uint32 kModule1100SoundList[] = {
Module1100::Module1100(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
if (which < 0) {
createScene(_vm->gameState().sceneNum, -1);
} else if (which == 1) {
@@ -271,7 +271,7 @@ static const uint32 kSsScene1105SymbolDieFileHashes[] = {
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);
@@ -347,7 +347,7 @@ void SsScene1105SymbolDie::hide() {
AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
+
createSurface(100, 556, 328);
_x = 320;
_y = 240;
@@ -396,7 +396,7 @@ void AsScene1105TeddyBear::hide() {
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);
@@ -432,26 +432,26 @@ uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
-
+
Sprite *ssOpenButton;
-
+
_vm->gameModule()->initMemoryPuzzle();
-
+
SetUpdateHandler(&Scene1105::update);
SetMessageHandler(&Scene1105::handleMessage);
-
+
setBackground(0x20010002);
setPalette(0x20010002);
-
+
_asTeddyBear = insertSprite<AsScene1105TeddyBear>(this);
ssOpenButton = insertSprite<SsScene1105OpenButton>(this);
addCollisionSprite(ssOpenButton);
insertPuzzleMouse(0x10006208, 20, 620);
-
+
loadSound(0, 0x48442057);
loadSound(1, 0xC025014F);
loadSound(2, 0x68E25540);
-
+
}
uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -555,27 +555,27 @@ void Scene1105::createObjects() {
_ssSymbolDice[1] = insertSprite<SsScene1105SymbolDie>(1, 339, 304);
_ssSymbolDice[2] = insertSprite<SsScene1105SymbolDie>(2, 485, 304);
- _ssSymbol1UpButton = insertSprite<SsScene1105Button>(this, 0x08002860, NRect(146, 362, 192, 403));
+ _ssSymbol1UpButton = insertSprite<SsScene1105Button>(this, 0x08002860, NRect::make(146, 362, 192, 403));
addCollisionSprite(_ssSymbol1UpButton);
- _ssSymbol1DownButton = insertSprite<SsScene1105Button>(this, 0x42012460, NRect(147, 404, 191, 442));
+ _ssSymbol1DownButton = insertSprite<SsScene1105Button>(this, 0x42012460, NRect::make(147, 404, 191, 442));
addCollisionSprite(_ssSymbol1DownButton);
- _ssSymbol2UpButton = insertSprite<SsScene1105Button>(this, 0x100030A0, NRect(308, 361, 355, 402));
+ _ssSymbol2UpButton = insertSprite<SsScene1105Button>(this, 0x100030A0, NRect::make(308, 361, 355, 402));
addCollisionSprite(_ssSymbol2UpButton);
- _ssSymbol2DownButton = insertSprite<SsScene1105Button>(this, 0x840228A0, NRect(306, 406, 352, 445));
+ _ssSymbol2DownButton = insertSprite<SsScene1105Button>(this, 0x840228A0, NRect::make(306, 406, 352, 445));
addCollisionSprite(_ssSymbol2DownButton);
- _ssSymbol3UpButton = insertSprite<SsScene1105Button>(this, 0x20000120, NRect(476, 358, 509, 394));
+ _ssSymbol3UpButton = insertSprite<SsScene1105Button>(this, 0x20000120, NRect::make(476, 358, 509, 394));
addCollisionSprite(_ssSymbol3UpButton);
- _ssSymbol3DownButton = insertSprite<SsScene1105Button>(this, 0x08043121, NRect(463, 401, 508, 438));
+ _ssSymbol3DownButton = insertSprite<SsScene1105Button>(this, 0x08043121, NRect::make(463, 401, 508, 438));
addCollisionSprite(_ssSymbol3DownButton);
- _ssActionButton = insertSprite<SsScene1105Button>(this, 0x8248AD35, NRect(280, 170, 354, 245));
+ _ssActionButton = insertSprite<SsScene1105Button>(this, 0x8248AD35, NRect::make(280, 170, 354, 245));
addCollisionSprite(_ssActionButton);
-
+
_isPanelOpen = true;
-
+
_asTeddyBear->show();
insertPuzzleMouse(0x18666208, 20, 620);
-
+
}
void Scene1105::upOpenPanel() {
@@ -639,13 +639,13 @@ void Scene1105::update() {
Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene1109::handleMessage);
-
+
setBackground(0x8449E02F);
setPalette(0x8449E02F);
insertScreenMouse(0x9E02B84C);
-
+
_sprite1 = insertStaticSprite(0x600CEF01, 1100);
if (which < 0) {
diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp
index ae84d59113..e7766419f9 100644
--- a/engines/neverhood/modules/module1200.cpp
+++ b/engines/neverhood/modules/module1200.cpp
@@ -26,7 +26,7 @@ namespace Neverhood {
Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
SetMessageHandler(&Module1200::handleMessage);
if (which < 0)
@@ -124,7 +124,7 @@ static const uint32 kScene1201TntFileHashList2[] = {
0xB140A1E6, 0x5088A068, 0x5088A068,
0x74C4C866, 0x3192C059, 0x3192C059
};
-
+
SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
: StaticSprite(vm, 900) {
@@ -136,10 +136,10 @@ SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 poi
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 {
@@ -253,10 +253,10 @@ void AsScene1201RightDoor::stCloseDoorDone() {
stopAnimation();
setVisible(false);
}
-
+
AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1200) {
-
+
createSurface(1200, 69, 98);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
@@ -301,7 +301,7 @@ AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sp
AsScene1201TntMan::~AsScene1201TntMan() {
_vm->_soundMan->deleteSoundGroup(0x01D00560);
-}
+}
uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
@@ -396,7 +396,7 @@ void AsScene1201TntManFlame::suUpdate() {
AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
-
+
createSurface(1100, 57, 60);
SetUpdateHandler(&AsScene1201Match::update);
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
@@ -518,7 +518,7 @@ AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene
: 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);
@@ -664,7 +664,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene1201::handleMessage);
setHitRects(0x004AEBD0);
-
+
if (!getSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52)) {
setSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52, 1);
for (uint32 index = 0; index < 18; index++)
@@ -672,25 +672,25 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
}
insertScreenMouse(0x9A2C0409);
-
+
_asTape = insertSprite<AsScene1201Tape>(this, 3, 1100, 243, 340, 0x9148A011);
addCollisionSprite(_asTape);
-
+
tempSprite = insertStaticSprite(0x03C82530, 100);
- topY1 = tempSprite->getY() + tempSprite->getDrawRect().height;
+ topY1 = tempSprite->getY() + tempSprite->getDrawRect().height;
tempSprite = insertStaticSprite(0x88182069, 200);
- topY2 = tempSprite->getY() + tempSprite->getDrawRect().height;
+ topY2 = tempSprite->getY() + tempSprite->getDrawRect().height;
tempSprite = insertStaticSprite(0x476014E0, 300);
- topY3 = tempSprite->getY() + tempSprite->getDrawRect().height;
+ topY3 = tempSprite->getY() + tempSprite->getDrawRect().height;
tempSprite = insertStaticSprite(0x04063110, 500);
- topY4 = tempSprite->getY() + 1;
+ topY4 = tempSprite->getY() + 1;
_asTntManRope = insertSprite<AsScene1201TntManRope>(getGlobalVar(V_TNT_DUMMY_BUILT) && which != 1);
_asTntManRope->setClipRect(0, topY4, 640, 480);
-
+
insertStaticSprite(0x400B04B0, 1200);
tempSprite = insertStaticSprite(0x40295462, 1200);
@@ -735,7 +735,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(x1, 0, x2, 480);
_klaymen->setRepl(64, 0);
-
+
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
setBackground(0x4019A2C4);
setPalette(0x4019A2C4);
@@ -756,8 +756,8 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
tempSprite = insertSprite<AsScene1201TntManFlame>(_asTntMan);
tempSprite->setClipRect(x1, 0, x2, 480);
}
-
- uint32 tntIndex = 1;
+
+ uint32 tntIndex = 1;
while (tntIndex < 18) {
uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex);
int16 clipY2;
@@ -783,10 +783,10 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004AEE58);
} else {
setRectList(0x004AEDC8);
- }
-
+ }
+
} else {
-
+
insertStaticSprite(0x8E8A1981, 900);
uint32 tntIndex = 0;
@@ -795,7 +795,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
int16 clipY2;
if (kScene1201PointArray[elemIndex].x < 300) {
clipY2 = 480;
- } else {
+ } else {
if (kScene1201PointArray[elemIndex].y < 175)
clipY2 = topY1;
else if (kScene1201PointArray[elemIndex].y < 230)
@@ -811,7 +811,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004AEE18);
else
setRectList(0x004AED88);
-
+
}
tempSprite = insertStaticSprite(0x63D400BC, 900);
@@ -875,7 +875,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004AECC0);
}
break;
- case 0x2002:
+ case 0x2002:
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
// Move the TNT dummy if the fuse is burning
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
@@ -903,7 +903,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x8000:
sendMessage(_asKlaymenHead, 0x2006, 0);
- break;
+ break;
}
return messageResult;
}
@@ -956,7 +956,7 @@ uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param,
case 0x2001:
_newPosition = (int)param.asInteger();
stChangePositionFadeOut();
- break;
+ break;
}
return messageResult;
}
@@ -998,7 +998,7 @@ void AsScene1202TntItem::stChangePositionDone() {
}
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule), _paletteResource(vm),
+ : Scene(vm, parentModule), _paletteResource(vm),
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
SetMessageHandler(&Scene1202::handleMessage);
@@ -1093,8 +1093,8 @@ uint32 Scene1202::hmSolved(int messageNum, const MessageParam &param, Entity *se
}
bool Scene1202::isSolved() {
- return
- getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 &&
+ return
+ getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 &&
getSubVar(VA_TNT_POSITIONS, 6) == 6 && getSubVar(VA_TNT_POSITIONS, 9) == 9 &&
getSubVar(VA_TNT_POSITIONS, 12) == 12 && getSubVar(VA_TNT_POSITIONS, 15) == 15;
}
diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp
index 062434f064..c8a561af76 100644
--- a/engines/neverhood/modules/module1300.cpp
+++ b/engines/neverhood/modules/module1300.cpp
@@ -45,7 +45,7 @@ static const uint32 kModule1300SoundList[] = {
Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x61C090, 0x00203197);
_vm->_soundMan->addSoundList(0x61C090, kModule1300SoundList);
_vm->_soundMan->setSoundListParams(kModule1300SoundList, false, 50, 600, 20, 150);
@@ -56,7 +56,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)
if (which < 0) {
if (_vm->gameState().sceneNum >= 1 && _vm->gameState().sceneNum <= 17)
createScene(_vm->gameState().sceneNum, -1);
- else
+ else
createScene(11, 0);
} else {
switch (which) {
@@ -101,7 +101,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)
break;
}
}
-
+
}
Module1300::~Module1300() {
@@ -218,7 +218,7 @@ void Module1300::createScene(int sceneNum, int which) {
SetUpdateHandler(&Module1300::updateScene);
_childObject->handleUpdate();
}
-
+
void Module1300::updateScene() {
if (!updateChild()) {
switch (_sceneNum) {
@@ -274,7 +274,7 @@ void Module1300::updateScene() {
createScene(11, 1);
break;
case 12:
- if (_moduleResult == 0)
+ if (_moduleResult == 0)
createScene(14, 1);
else if (_moduleResult == 1)
createScene(15, 1);
@@ -367,7 +367,7 @@ void AsScene1302Bridge::cbLowerBridgeEvent() {
SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
: StaticSprite(vm, 0x11122122, 200) {
-
+
_firstY = _y;
if (getGlobalVar(V_FLYTRAP_RING_FENCE))
_y += 152;
@@ -459,7 +459,7 @@ Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
addCollisionSprite(_asVenusFlyTrap);
sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
-
+
}
uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -513,7 +513,7 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x2000:
if (_klaymen->getY() > 360) {
sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
- setMessageList2(0x004B08F0);
+ setMessageList2(0x004B08F0);
} else
setMessageList2(0x004B0920);
break;
@@ -583,7 +583,7 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
+
createSurface(200, 128, 315);
_x = 289;
_y = 390;
@@ -643,7 +643,7 @@ Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
_asBalloon = insertSprite<AsScene1303Balloon>(this);
addCollisionSprite(_asBalloon);
}
-
+
_sprite1 = insertStaticSprite(0xA014216B, 1100);
insertKlaymen<KmScene1303>(207, 332);
@@ -671,7 +671,7 @@ uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entit
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
+ // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
SetMessageHandler(&AsScene1304Needle::handleMessage);
}
@@ -693,14 +693,14 @@ uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &para
Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asNeedle(NULL) {
-
+
SetMessageHandler(&Scene1304::handleMessage);
setRectList(0x004B91A8);
setBackground(0x062C0214);
setPalette(0x062C0214);
insertScreenMouse(0xC021006A);
-
+
if (getGlobalVar(V_BALLOON_POPPED)) {
_asKey = insertSprite<AsCommonKey>(this, 0, 1100, 278, 347);
addCollisionSprite(_asKey);
@@ -774,7 +774,7 @@ Scene1305::Scene1305(NeverhoodEngine *vm, Module *parentModule, int which)
insertKlaymen<KmScene1305>(212, 441);
setMessageList(0x004B6E48);
}
-
+
}
uint32 Scene1305::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -868,10 +868,10 @@ void AsScene1306Elevator::cbGoingDownEvent() {
Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
setGlobalVar(V_KEY3_LOCATION, 4);
-
+
SetMessageHandler(&Scene1306::handleMessage);
setBackground(0x05303114);
@@ -949,7 +949,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
}
}
-
+
Scene1306::~Scene1306() {
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
}
@@ -1073,7 +1073,7 @@ static const NPoint kAsScene1307KeyPoints[] = {
const uint kAsScene1307KeyFrameIndicesCount = 20;
static const int16 kAsScene1307KeyFrameIndices[] = {
- 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
+ 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
15, 14, 12, 10, 9, 7, 5, 3, 2, 1
};
@@ -1084,10 +1084,10 @@ 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];
-
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+
_dataResource.load(0x22102142);
_pointList = _dataResource.getPointArray(0xAC849240);
pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
@@ -1173,7 +1173,7 @@ void AsScene1307Key::suMoveKey() {
}
void AsScene1307Key::stRemoveKey() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
_pointIndex = 0;
startAnimation(fileHashes[0], 0, -1);
playSound(1);
@@ -1199,7 +1199,7 @@ void AsScene1307Key::stMoveKey() {
if (newX == _x && newY == _y) {
stInsertKey();
} else {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
_pointIndex = 0;
_frameIndex = 0;
_deltaX = newX - _x;
@@ -1210,13 +1210,13 @@ void AsScene1307Key::stMoveKey() {
}
void AsScene1307Key::stUnlock() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
startAnimation(fileHashes[1], 0, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
void AsScene1307Key::stInsert() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
startAnimation(fileHashes[2], 0, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
}
@@ -1226,9 +1226,9 @@ Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule)
_isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) {
Sprite *tempSprite;
-
+
_vm->gameModule()->initKeySlotsPuzzle();
-
+
_dataResource.load(0x22102142);
_keyHolePoints = _dataResource.getPointArray(0xAC849240);
@@ -1279,7 +1279,7 @@ void Scene1307::update() {
if (_doLeaveScene && !isSoundPlaying(0)) {
leaveScene(1);
setGlobalVar(V_KEYDOOR_UNLOCKED, 1);
- }
+ }
}
uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1294,7 +1294,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entit
int16 mouseY = param.asPoint().y;
uint clickedKeyHoleIndex;
for (clickedKeyHoleIndex = 0; clickedKeyHoleIndex < 16; clickedKeyHoleIndex++) {
- if (mouseX >= _keyHoleRects[clickedKeyHoleIndex].x1 && mouseX <= _keyHoleRects[clickedKeyHoleIndex].x2 &&
+ if (mouseX >= _keyHoleRects[clickedKeyHoleIndex].x1 && mouseX <= _keyHoleRects[clickedKeyHoleIndex].x2 &&
mouseY >= _keyHoleRects[clickedKeyHoleIndex].y1 && mouseY <= _keyHoleRects[clickedKeyHoleIndex].y2)
break;
}
@@ -1362,7 +1362,7 @@ static const uint32 kScene1308NumberFileHashes[] = {
AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
-
+
setVisible(false);
stopAnimation();
SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
@@ -1412,12 +1412,12 @@ void AsScene1308JaggyDoor::stCloseDoorDone() {
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) {
@@ -1443,7 +1443,7 @@ void AsScene1308KeyboardDoor::stFallingKeysDone() {
AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
-
+
setVisible(false);
stopAnimation();
Entity::_priority = 1200;
@@ -1486,7 +1486,7 @@ void AsScene1308LightWallSymbols::stFadeOutDone() {
SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
: StaticSprite(vm, fileHash, 100) {
-
+
setVisible(false);
_x = _spriteResource.getPosition().x + index * 20;
updatePosition();
@@ -1520,11 +1520,11 @@ uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param
Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) {
-
+
_vm->gameModule()->initKeySlotsPuzzle();
SetMessageHandler(&Scene1308::handleMessage);
-
+
setBackground(0x41024202);
setPalette(0x41024202);
insertScreenMouse(0x24206418);
@@ -1536,7 +1536,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
insertSprite<AsScene1308Mouse>();
insertSprite<AnimatedSprite>(0x461A1490, 200, 235, 429);
}
-
+
_sprite1 = insertStaticSprite(0x0A042060, 1100);
_asJaggyDoor = insertSprite<AsScene1308JaggyDoor>(this);
_asLightWallSymbols = insertSprite<AsScene1308LightWallSymbols>(this);
@@ -1546,7 +1546,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
_sprite2 = insertStaticSprite(0x40043120, 995);
_sprite3 = insertStaticSprite(0x43003100, 995);
_sprite4 = NULL;
-
+
if (which < 0) {
// Restoring game
insertKlaymen<KmScene1308>(380, 440);
@@ -1698,7 +1698,7 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
Scene1317::Scene1317(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene1317::handleMessage);
_smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08982841, true, false));
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
@@ -1720,7 +1720,7 @@ void Scene1317::update() {
void Scene1317::upChooseKing() {
if (!_klaymenBlinks && _klaymenBlinkCountdown != 0 && (--_klaymenBlinkCountdown == 0))
_klaymenBlinks = true;
-
+
if (!_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 2) {
_smackerPlayer->rewind();
} else if (_klaymenBlinks && _smackerPlayer->getFrameNumber() + 1 >= 6) {
@@ -1731,7 +1731,7 @@ void Scene1317::upChooseKing() {
if (!_klaymenBlinks && _decisionCountdown != 0 && (--_decisionCountdown == 0))
stNoDecisionYet();
-
+
if (_smackerFileHash) {
_smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame);
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
@@ -1739,7 +1739,7 @@ void Scene1317::upChooseKing() {
}
Scene::update();
-
+
}
uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1751,7 +1751,7 @@ uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entit
}
return messageResult;
}
-
+
uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp
index 56c6ca5f13..0a029632b6 100644
--- a/engines/neverhood/modules/module1400.cpp
+++ b/engines/neverhood/modules/module1400.cpp
@@ -31,7 +31,7 @@ namespace Neverhood {
Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x00AD0012, 0x06333232);
_vm->_soundMan->addMusic(0x00AD0012, 0x624A220E);
@@ -139,7 +139,7 @@ void Module1400::updateScene() {
AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
-
+
createSurface(900, 152, 147);
_x = 454;
_y = 217;
@@ -179,10 +179,10 @@ uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param,
_countdown1 = 70;
_countdown2 = 8;
stStartSucking();
- break;
+ break;
case 0x483A:
stSuckInProjector();
- break;
+ break;
}
return messageResult;
}
@@ -221,7 +221,7 @@ void AsScene1401Pipe::stSuckInProjector() {
AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100) {
-
+
createSurface(100, 71, 41);
_x = 478;
_y = 433;
@@ -243,7 +243,7 @@ uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param
break;
case 0x4839:
stSuckedIn();
- break;
+ break;
}
return messageResult;
}
@@ -280,7 +280,7 @@ uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &para
switch (messageNum) {
case 0x4839:
stSuckedIn();
- break;
+ break;
}
return messageResult;
}
@@ -332,7 +332,7 @@ uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &pa
case 0x2001:
if (_isOpen)
_countdown = 168;
- messageResult = _isOpen ? 1 : 0;
+ messageResult = _isOpen ? 1 : 0;
break;
case 0x3002:
gotoNextState();
@@ -341,7 +341,7 @@ uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &pa
_countdown = 168;
if (!_isOpen)
stOpenDoor();
- break;
+ break;
}
return messageResult;
}
@@ -540,7 +540,7 @@ void AsCommonProjector::moveProjector() {
playSound(1, 0x5440E474);
_lockedInSlot = true;
}
-
+
}
void AsCommonProjector::stSuckedIn() {
@@ -627,8 +627,8 @@ void AsCommonProjector::stStartSuckedIn() {
}
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),
+ : Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL),
+ _asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL),
_sprite1(NULL), _sprite2(NULL), _sprite3(NULL), _ssButton(NULL) {
SetMessageHandler(&Scene1401::handleMessage);
@@ -638,7 +638,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
setBackground(0x08221FA5);
setPalette(0x08221FA5);
insertScreenMouse(0x21FA108A);
-
+
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x980F3124, 0x12192892, 100, 0);
_asPipe = insertSprite<AsScene1401Pipe>();
@@ -692,7 +692,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
}
_asProjector->setClipRect(_sprite3->getDrawRect().x, _sprite2->getDrawRect().y, 640, 480);
}
-
+
_klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480);
if (which == 0 && _asProjector)
@@ -752,7 +752,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004B6658);
} else
setMessageList2(0x004B65F0);
- }
+ }
break;
case 0x482A:
_sprite1->setVisible(true);
@@ -772,7 +772,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
: StaticSprite(vm, fileHash, surfacePriority) {
-
+
SetFilterY(&Sprite::defFilterY);
SetUpdateHandler(&StaticSprite::updatePosition);
}
@@ -892,7 +892,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
startShaking();
}
}
-
+
if (_asPuzzleBox)
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
@@ -914,7 +914,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
}
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
-
+
}
void Scene1402::upShaking() {
@@ -1082,7 +1082,7 @@ static const struct {
AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
-
+
createSurface(100, 117, 45);
_x = 108;
_y = 106;
@@ -1096,7 +1096,7 @@ void AsScene1407Mouse::suWalkTo() {
xdelta = _deltaX;
else if (xdelta < -_deltaX)
xdelta = -_deltaX;
- _deltaX = 0;
+ _deltaX = 0;
if (_walkDestX == _x)
sendMessage(this, 0x1019, 0);
else {
@@ -1231,7 +1231,7 @@ Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
_asMouse = insertSprite<AsScene1407Mouse>(this);
_ssResetButton = insertStaticSprite(0x12006600, 100);
- _ssResetButton->setVisible(false);
+ _ssResetButton->setVisible(false);
}
@@ -1279,9 +1279,9 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _isProjecting(false) {
-
+
SetMessageHandler(&Scene1403::handleMessage);
-
+
setRectList(0x004B1FF8);
setBackground(0x2110A234);
setPalette(0x2110A234);
@@ -1383,10 +1383,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _asKey(NULL) {
-
+
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
setGlobalVar(V_KEY3_LOCATION, 5);
-
+
SetMessageHandler(&Scene1404::handleMessage);
setRectList(0x004B8D80);
@@ -1555,14 +1555,14 @@ Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
_vm->gameModule()->initMemoryPuzzle();
-
+
SetUpdateHandler(&Scene1405::update);
SetMessageHandler(&Scene1405::handleMessage);
setBackground(0x0C0C007D);
setPalette(0x0C0C007D);
insertPuzzleMouse(0xC00790C8, 20, 620);
-
+
for (uint32 tileIndex = 0; tileIndex < 48; tileIndex++) {
_tiles[tileIndex] = insertSprite<AsScene1405Tile>(this, tileIndex);
addCollisionSprite(_tiles[tileIndex]);
diff --git a/engines/neverhood/modules/module1500.cpp b/engines/neverhood/modules/module1500.cpp
index 00d64a8c2d..3ce9783b69 100644
--- a/engines/neverhood/modules/module1500.cpp
+++ b/engines/neverhood/modules/module1500.cpp
@@ -26,7 +26,7 @@ namespace Neverhood {
Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else
@@ -86,7 +86,7 @@ Scene1501::Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroun
SetUpdateHandler(&Scene1501::update);
SetMessageHandler(&Scene1501::handleMessage);
-
+
setBackground(backgroundFileHash);
setPalette();
addEntity(_palette);
@@ -118,7 +118,7 @@ void Scene1501::update() {
_countdown1 = 12;
_palette->startFadeToBlack(11);
}
-
+
}
uint32 Scene1501::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp
index 40faa1e82d..a5a785e130 100644
--- a/engines/neverhood/modules/module1600.cpp
+++ b/engines/neverhood/modules/module1600.cpp
@@ -34,7 +34,7 @@ static const uint32 kModule1600SoundList[] = {
Module1600::Module1600(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else if (which == 1)
@@ -109,7 +109,7 @@ void Module1600::createScene(int sceneNum, int which) {
if (getGlobalVar(V_TALK_COUNTING_INDEX) >= 2)
setGlobalVar(V_TALK_COUNTING_INDEX, 0);
else
- incGlobalVar(V_TALK_COUNTING_INDEX, +1);
+ incGlobalVar(V_TALK_COUNTING_INDEX, +1);
break;
}
SetUpdateHandler(&Module1600::updateScene);
@@ -185,11 +185,11 @@ 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;
@@ -207,7 +207,7 @@ AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16
_soundCounter = 0;
_pathPoints = NULL;
_currMoveDirection = 0;
-
+
startAnimation(0xD4220027, 0, -1);
setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
@@ -517,7 +517,7 @@ void AsCommonCar::moveToNextPoint() {
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)
+ if (_currMoveDirection == 2)
_currMoveDirection = 4;
else if (_currMoveDirection == 4)
_currMoveDirection = 2;
@@ -605,7 +605,7 @@ void AsCommonCar::moveToPrevPoint() {
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)
+ if (_currMoveDirection == 2)
_currMoveDirection = 4;
else if (_currMoveDirection == 4)
_currMoveDirection = 2;
@@ -668,7 +668,7 @@ void AsCommonCar::suMoveToNextPoint() {
bool firstTime = true;
_ySteps = _steps;
int stepsCtr = _steps;
-
+
while (stepsCtr > 0) {
NPoint pt1;
NPoint pt2 = pathPoint(_currPointIndex);
@@ -739,7 +739,7 @@ void AsCommonCar::suMoveToNextPoint() {
stepsCtr = 0;
}
}
- firstTime = false;
+ firstTime = false;
}
if (_yMoveTotalSteps != 0) {
@@ -811,7 +811,7 @@ void AsCommonCar::suMoveToPrevPoint() {
bool firstTime = true;
_ySteps = _steps;
int stepsCtr = _steps;
-
+
while (stepsCtr > 0) {
if (_stepError == 0)
_currPointIndex--;
@@ -884,7 +884,7 @@ void AsCommonCar::suMoveToPrevPoint() {
stepsCtr = 0;
}
}
- firstTime = false;
+ firstTime = false;
}
if (_yMoveTotalSteps != 0) {
@@ -971,7 +971,7 @@ AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
: AnimatedSprite(vm, 1100), _asCar(asCar) {
-
+
createSurface1(0x60281C10, 150);
startAnimation(0x60281C10, -1, -1);
_newStickFrameIndex = STICK_LAST_FRAME;
@@ -1006,9 +1006,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asCar(NULL), _countdown1(0) {
setGlobalVar(V_CAR_DELTA_X, 1);
-
+
SetMessageHandler(&Scene1608::hmLowerFloor);
-
+
_asKey = insertSprite<AsCommonKey>(this, 1, 1100, 198, 220);
addCollisionSprite(_asKey);
@@ -1092,9 +1092,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
_carClipFlag = false;
_carStatus = 0;
setRectList(0x004B4810);
- }
+ }
- // NOTE: Not in the else because 'which' is set to 1 in the true branch
+ // NOTE: Not in the else because 'which' is set to 1 in the true branch
if (which == 1) {
// Klaymen riding the car
_vm->gameState().which = 1;
@@ -1134,9 +1134,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
_carClipFlag = true;
_carStatus = 0;
}
-
+
_palette->addPalette("paKlayRed", 0, 64, 0);
-
+
}
Scene1608::~Scene1608() {
@@ -1308,7 +1308,7 @@ uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam &param, Entity
}
return 0;
}
-
+
void Scene1608::updateKlaymenCliprect() {
if (_kmScene1608->getX() <= 375)
_kmScene1608->setClipRect(_clipRect1);
@@ -1321,17 +1321,17 @@ Scene1609::Scene1609(NeverhoodEngine *vm, Module *parentModule)
_vm->gameModule()->initCodeSymbolsPuzzle();
_noisySymbolIndex = getGlobalVar(V_NOISY_SYMBOL_INDEX);
-
+
SetMessageHandler(&Scene1609::handleMessage);
SetUpdateHandler(&Scene1609::update);
-
+
setBackground(0x92124A14);
setPalette(0x92124A14);
insertPuzzleMouse(0x24A10929, 20, 620);
-
+
for (int symbolPosition = 0; symbolPosition < 12; symbolPosition++)
_asSymbols[symbolPosition] = insertSprite<AsScene3011Symbol>(symbolPosition, false);
-
+
_ssButton = insertSprite<SsScene3011Button>(this, true);
addCollisionSprite(_ssButton);
loadSound(0, 0x68E25540);
@@ -1408,5 +1408,5 @@ bool Scene1609::testVars() {
return true;
}
-
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp
index 38ed561d51..2aeae466ff 100644
--- a/engines/neverhood/modules/module1700.cpp
+++ b/engines/neverhood/modules/module1700.cpp
@@ -36,7 +36,7 @@ static const uint32 kModule1700SoundList[] = {
Module1700::Module1700(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x04212331, 0x31114225);
_vm->_soundMan->addSoundList(0x04212331, kModule1700SoundList);
_vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 50, 600, 5, 150);
@@ -125,7 +125,7 @@ void Module1700::updateScene() {
}
}
}
-
+
// Scene1705
static const uint32 kScene1705FileHashes[] = {
@@ -137,7 +137,7 @@ static const uint32 kScene1705FileHashes[] = {
SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
: StaticSprite(vm, fileHash, 100) {
-
+
_x = _spriteResource.getPosition().x + symbolIndex * 30;
_y = _spriteResource.getPosition().y + 160;
updatePosition();
@@ -171,7 +171,7 @@ uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param,
setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
setVisible(false);
SetMessageHandler(NULL);
- break;
+ break;
}
return messageResult;
}
@@ -180,7 +180,7 @@ Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(1) {
Sprite *tempSprite;
-
+
setGlobalVar(V_FELL_DOWN_HOLE, 1);
_vm->gameModule()->initCannonSymbolsPuzzle();
@@ -271,7 +271,7 @@ uint32 Scene1705::handleMessage(int messageNum, const MessageParam &param, Entit
sendEntityMessage(_klaymen, 0x1014, sender);
setMessageList(0x004B6AC0);
}
- break;
+ break;
}
return 0;
}
diff --git a/engines/neverhood/modules/module1700.h b/engines/neverhood/modules/module1700.h
index f57c411a18..deb5573f2b 100644
--- a/engines/neverhood/modules/module1700.h
+++ b/engines/neverhood/modules/module1700.h
@@ -50,7 +50,7 @@ public:
class SsScene1705Tape : public StaticSprite {
public:
SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
+protected:
Scene *_parentScene;
uint32 _tapeIndex;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp
index b7371c9a4a..b312678467 100644
--- a/engines/neverhood/modules/module1800.cpp
+++ b/engines/neverhood/modules/module1800.cpp
@@ -38,7 +38,7 @@ static const uint32 kModule1800SoundList[] = {
Module1800::Module1800(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addSoundList(0x04A14718, kModule1800SoundList);
_vm->_soundMan->setSoundListParams(kModule1800SoundList, true, 50, 600, 10, 150);
_vm->_soundMan->playTwoSounds(0x04A14718, 0x8A382B55, 0x0C242F1D, 0);
@@ -177,5 +177,5 @@ void Module1800::updateScene() {
}
}
}
-
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp
index 7f08b01d3f..29c20083f9 100644
--- a/engines/neverhood/modules/module1900.cpp
+++ b/engines/neverhood/modules/module1900.cpp
@@ -35,8 +35,8 @@ static const uint32 kModule1900SoundList[] = {
Module1900::Module1900(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
- // NOTE: The original has a Scene1908 here as well but it's not used here but in another module...
-
+ // NOTE: The original has a Scene1908 here as well but it's not used here but in another module...
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else
@@ -88,7 +88,7 @@ void Module1900::updateScene() {
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
setRectList(0x004B34C8);
@@ -98,7 +98,7 @@ Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
insertScreenMouse(0x0322301B);
insertStaticSprite(0x42213133, 1100);
-
+
if (!getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
insertStaticSprite(0x40A40168, 100);
else if (getGlobalVar(V_STAIRS_DOWN)) {
@@ -132,16 +132,16 @@ static const NPoint kAsScene1907SymbolGroundPositions[] = {
{400, 375}, {370, 435}, {475, 415}
};
-static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
+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}
+ {275, 299}, {244, 299}, {238, 305},
+ {221, 309}, {199, 310}, {168, 323},
+ {145, 326}, {123, 328}, {103, 331}
};
static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
@@ -164,7 +164,7 @@ AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene
_plugInFailed = false;
_plugInTryCount = 0;
-
+
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
_isPluggedIn = true;
_currPositionIndex = elementIndex;
@@ -289,7 +289,7 @@ void AsScene1907Symbol::suMoveDown() {
_y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
_isMoving = false;
SetSpriteUpdate(NULL);
- }
+ }
}
void AsScene1907Symbol::suMoveUp() {
@@ -423,7 +423,7 @@ void AsScene1907Symbol::moveDown() {
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);
@@ -474,7 +474,7 @@ void SsScene1907UpDownButton::setToDownPosition() {
AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1400) {
-
+
createSurface1(0x110A1061, 1500);
_x = 320;
_y = 240;
@@ -515,10 +515,10 @@ void AsScene1907WaterHint::hide() {
SetMessageHandler(&Sprite::handleMessage);
}
-Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
+Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
+ : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
_moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) {
-
+
setBackground(0x20628E05);
setPalette(0x20628E05);
@@ -529,12 +529,12 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
_asSymbols[i] = insertSprite<AsScene1907Symbol>(this, i, getRandomPositionIndex());
addCollisionSprite(_asSymbols[i]);
}
-
+
_ssUpDownButton = insertSprite<SsScene1907UpDownButton>(this, _asSymbols[8]);
addCollisionSprite(_ssUpDownButton);
_asWaterHint = insertSprite<AsScene1907WaterHint>();
-
+
insertPuzzleMouse(0x28E0120E, 20, 620);
SetMessageHandler(&Scene1907::handleMessage);
@@ -542,7 +542,7 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
_pluggedInCount = 9;
-
+
loadSound(0, 0x72004A10);
loadSound(1, 0x22082A12);
loadSound(2, 0x21100A10);
@@ -552,7 +552,7 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
void Scene1907::update() {
Scene::update();
-
+
if (_hasPlugInFailed) {
int fallOffDelay = 0;
_hasPlugInFailed = false;
@@ -619,7 +619,7 @@ uint32 Scene1907::handleMessage(int messageNum, const MessageParam &param, Entit
playSound(3);
setGlobalVar(V_STAIRS_PUZZLE_SOLVED, 1);
break;
- }
+ }
return 0;
}
diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp
index 644b7c479a..fcccdefbdd 100644
--- a/engines/neverhood/modules/module2000.cpp
+++ b/engines/neverhood/modules/module2000.cpp
@@ -28,7 +28,7 @@ namespace Neverhood {
Module2000::Module2000(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else if (which == 0)
@@ -137,9 +137,9 @@ Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which)
sendMessage(this, 0x2000, 0);
_klaymen->setDoDeltaX(1);
}
-
+
_klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480);
-
+
}
uint32 Scene2001::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -153,7 +153,7 @@ uint32 Scene2001::handleMessage(int messageNum, const MessageParam &param, Entit
setRectList(0x004B3670);
_klaymen->setKlaymenIdleTable1();
}
- }
+ }
return 0;
}
diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp
index 7f9ca94430..bcff9d9d1b 100644
--- a/engines/neverhood/modules/module2100.cpp
+++ b/engines/neverhood/modules/module2100.cpp
@@ -30,7 +30,7 @@ Module2100::Module2100(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
_vm->_soundMan->addMusic(0x10A10C14, 0x11482B95);
-
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else if (which == 1)
@@ -129,7 +129,7 @@ void AsScene2101Door::stCloseDoorDone() {
AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
: AnimatedSprite(vm, 1400), _klaymen(klaymen) {
-
+
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
createSurface(1200, 88, 165);
@@ -176,8 +176,8 @@ void SsCommonFloorButton::update() {
else
setVisible(false);
}
-}
-
+}
+
uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -195,12 +195,12 @@ uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &pa
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
-
+
SetMessageHandler(&Scene2101::handleMessage);
SetUpdateHandler(&Scene2101::update);
-
+
setBackground(0x44242305);
setPalette(0x44242305);
insertScreenMouse(0x4230144A);
@@ -212,7 +212,7 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
addCollisionSprite(_asTape1);
_asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093);
addCollisionSprite(_asTape2);
-
+
if (which < 0) {
insertKlaymen<KmScene2101>(380, 438);
setMessageList(0x004B8E48);
@@ -256,10 +256,10 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
_doorStatus = 1;
_countdown1 = 0;
}
-
+
_asHitByDoorEffect = insertSprite<AsScene2101HitByDoorEffect>(_klaymen);
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
-
+
}
void Scene2101::update() {
diff --git a/engines/neverhood/modules/module2100.h b/engines/neverhood/modules/module2100.h
index 369f5ac0cc..d76bed0780 100644
--- a/engines/neverhood/modules/module2100.h
+++ b/engines/neverhood/modules/module2100.h
@@ -68,7 +68,7 @@ protected:
uint32 _soundFileHash;
uint32 _fileHash1, _fileHash2;
int16 _countdown;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index 04e3f0bfee..99f21cad74 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -30,8 +30,8 @@ namespace Neverhood {
Module2200::Module2200(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
- _vm->_soundMan->addMusic(0x11391412, 0x601C908C);
+
+ _vm->_soundMan->addMusic(0x11391412, 0x601C908C);
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
@@ -440,7 +440,7 @@ void Module2200::updateScene() {
}
#undef HallOfRecordsSceneLink
-
+
void Module2200::createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId) {
_childObject = new HallOfRecordsScene(_vm, this, which, hallOfRecordsInfoId);
}
@@ -461,7 +461,7 @@ AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *
: AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
_x = 408;
- _y = 290;
+ _y = 290;
createSurface(900, 63, 266);
SetUpdateHandler(&AsScene2201Door::update);
SetMessageHandler(&AsScene2201Door::handleMessage);
@@ -528,7 +528,7 @@ void AsScene2201Door::stCloseDoor() {
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);
@@ -543,7 +543,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene2201::handleMessage);
SetUpdateHandler(&Scene2201::update);
-
+
loadDataResource(0x04104242);
loadHitRectList();
setBackground(0x40008208);
@@ -551,9 +551,9 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
insertScreenMouse(0x0820C408);
_asTape = insertSprite<AsScene1201Tape>(this, 7, 1100, 459, 432, 0x9148A011);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
_ssDoorButton = insertSprite<SsCommonPressButton>(this, 0xE4A43E29, 0xE4A43E29, 100, 0);
-
+
for (uint32 cubeIndex = 0; cubeIndex < 9; cubeIndex++)
if ((int16)getSubVar(VA_CUBE_POSITIONS, cubeIndex) >= 0)
insertSprite<SsScene2201PuzzleCube>(cubeIndex, (int16)getSubVar(VA_CUBE_POSITIONS, cubeIndex));
@@ -562,10 +562,10 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
_clipRects[0].x2 = 640;
_clipRects[1].x2 = 640;
_clipRects[1].y2 = 480;
-
+
if (!getGlobalVar(V_TILE_PUZZLE_SOLVED))
insertStaticSprite(0x00026027, 900);
-
+
tempSprite = insertStaticSprite(0x030326A0, 1100);
_clipRects[0].x1 = tempSprite->getDrawRect().x;
insertStaticSprite(0x811DA061, 1100);
@@ -602,7 +602,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
setMessageList(0x004B8120);
_asDoor = insertSprite<AsScene2201Door>(_klaymen, _ssDoorLight, true);
}
-
+
insertSprite<AsScene2201CeilingFan>();
_vm->_soundMan->addSound(0x04106220, 0x81212040);
@@ -719,7 +719,7 @@ uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &
}
return messageResult;
}
-
+
void SsScene2202PuzzleCube::suMoveCubeX() {
bool done = false;
@@ -746,9 +746,9 @@ void SsScene2202PuzzleCube::suMoveCubeX() {
if (_x == _xFlagPos)
_counterDirection = true;
}
-
+
if (done)
- stopMoving();
+ stopMoving();
updateBounds();
@@ -780,9 +780,9 @@ void SsScene2202PuzzleCube::suMoveCubeY() {
if (_x == _xFlagPos)
_counterDirection = true;
}
-
+
if (done)
- stopMoving();
+ stopMoving();
updateBounds();
@@ -794,7 +794,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
-
+
_cubePosition = newCubePosition;
_errValue = 0;
_counterDirection = false;
@@ -837,7 +837,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
if (_newX - _x >= 180)
_xFlagPos = _newX - 90;
else
- _xFlagPos = _x + _newX / 2;
+ _xFlagPos = _x + _newX / 2;
} else {
if (_x - _newX >= 180)
_xFlagPos = _x + 90;
@@ -851,7 +851,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
if (_newY - _y >= 180)
_xFlagPos = _newY - 90;
else
- _xFlagPos = _y + _newY / 2;
+ _xFlagPos = _y + _newY / 2;
} else {
if (_y - _newY >= 180)
_xFlagPos = _y + 90;
@@ -860,7 +860,7 @@ void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
}
playSound(1);
}
-
+
}
void SsScene2202PuzzleCube::stopMoving() {
@@ -939,7 +939,7 @@ void Scene2202::update() {
_isSolved = true;
}
}
-
+
}
uint32 Scene2202::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -981,7 +981,7 @@ int16 Scene2202::getFreeCubePosition(int16 cubePosition) {
}
bool Scene2202::testIsSolved() {
- return
+ return
getSubVar(VA_CUBE_POSITIONS, 0) == 0 &&
getSubVar(VA_CUBE_POSITIONS, 2) == 2 &&
getSubVar(VA_CUBE_POSITIONS, 3) == 3 &&
@@ -1146,7 +1146,7 @@ Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
_ssSmallRightDoor->setVisible(false);
_klaymen->setClipRect(_leftDoorClipRect);
}
-
+
}
Scene2203::~Scene2203() {
@@ -1220,7 +1220,7 @@ Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene2205::handleMessage);
SetUpdateHandler(&Scene2205::update);
-
+
setHitRects(0x004B0620);
if (getGlobalVar(V_LIGHTS_ON)) {
_isLightOn = true;
@@ -1263,11 +1263,11 @@ Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(_ssDoorFrame->getDrawRect().x, 0, 640, 480);
_klaymen->setSoundFlag(true);
-
+
loadDataResource(0x00144822);
-
+
}
-
+
void Scene2205::update() {
Scene::update();
if (!_isLightOn && getGlobalVar(V_LIGHTS_ON)) {
@@ -1343,7 +1343,7 @@ static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
: StaticSprite(vm, fileHash, 200) {
-
+
if (getGlobalVar(V_SPIKES_RETRACTED))
_x -= 63;
SetUpdateHandler(&AsScene2206DoorSpikes::update);
@@ -1457,10 +1457,10 @@ Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
uint32 fileHash;
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene2206::handleMessage);
-
+
if (getGlobalVar(V_LIGHTS_ON)) {
fileHash = 0x41983216;
_sprite1 = insertStaticSprite(0x2201266A, 100);
@@ -1495,7 +1495,7 @@ Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which)
if (!getGlobalVar(V_LIGHTS_ON))
_palette->addPalette(0x0263D144, 0, 65, 0);
addCollisionSprite(_ssTestTube);
-
+
if (which < 0) {
// Restoring game
insertKlaymen<KmScene2206>(200, 430);
@@ -1644,7 +1644,7 @@ void AsScene2207Elevator::update() {
if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
_pointIndex++;
startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
+ _newStickFrameIndex = _pointIndex;
if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
if (_destPointIndexDelta != 0)
_destPointIndexDelta = 0;
@@ -1660,7 +1660,7 @@ void AsScene2207Elevator::update() {
if (_pointIndex == 0)
sendMessage(_parentScene, 0x2003, 0);
startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
+ _newStickFrameIndex = _pointIndex;
if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
if (_destPointIndexDelta != 0)
_destPointIndexDelta = 0;
@@ -1675,14 +1675,14 @@ void AsScene2207Elevator::update() {
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() {
@@ -1706,14 +1706,14 @@ void AsScene2207Elevator::moveToY(int16 y) {
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)
@@ -1732,7 +1732,7 @@ void AsScene2207Elevator::moveToY(int16 y) {
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);
@@ -1793,7 +1793,7 @@ void AsScene2207Lever::stLeverUpEvent() {
AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1200), _idle(true) {
-
+
_x = 309;
_y = 320;
createSurface1(0xCCFD6090, 100);
@@ -1874,7 +1874,7 @@ void AsScene2207WallRobotAnimation::cbStopAnimation() {
AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1200), _idle(true) {
-
+
_x = 309;
_y = 320;
createSurface1(0x8CAA0099, 100);
@@ -1925,7 +1925,7 @@ SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int i
_x = 330;
_y = 246 + index * 50;
- updatePosition();
+ updatePosition();
}
Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
@@ -1943,7 +1943,7 @@ Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
_klaymen->setRepl(64, 0);
setMessageList(0x004B38E8);
_asElevator = insertSprite<AsScene2207Elevator>(this);
-
+
if (getGlobalVar(V_LIGHTS_ON)) {
setBackground(0x88C00241);
setPalette(0x88C00241);
@@ -1952,7 +1952,7 @@ Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
_ssMaskPart2 = insertStaticSprite(0x688F62A5, 1100);
_ssMaskPart3 = insertStaticSprite(0x0043B038, 1100);
_asTape = insertSprite<AsScene1201Tape>(this, 4, 1100, 277, 428, 0x9148A011);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
_asLever = insertSprite<AsScene2207Lever>(this, 527, 333, 0);
addCollisionSprite(_asLever);
_asWallRobotAnimation = insertSprite<AsScene2207WallRobotAnimation>(this);
@@ -2106,7 +2106,7 @@ static const uint32 kScene2208FileHashes1[] = {
0x041023CB, 0x041020CB, 0x041026CB, 0x04102ACB,
0x041032CB, 0x041002CB
};
-
+
static const uint32 kScene2208FileHashes2[] = {
0x091206C9, 0x091406C9, 0x091806C9, 0x090006C9,
0x093006C9, 0x095006C9
@@ -2122,13 +2122,13 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which)
setGlobalVar(V_COLUMN_TEXT_NAME, calcHash("stLineagex"));
_textResource.load(getGlobalVar(V_COLUMN_TEXT_NAME));
-
+
textStart = _textResource.getString(getGlobalVar(V_CLICKED_COLUMN_INDEX), textEnd);
while (textStart < textEnd) {
_strings.push_back(textStart);
textStart += strlen(textStart) + 1;
}
-
+
_maxRowIndex = 8 + 10 * (3 - (getGlobalVar(V_COLUMN_TEXT_NAME) == calcHash("stLineagex") ? 1 : 0));
_background = new Background(_vm, 0);
@@ -2154,7 +2154,7 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which)
_bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192, "bottom background");
spriteResource.load(kScene2208FileHashes2[getGlobalVar(V_CLICKED_COLUMN_INDEX) % 6], true);
_bottomBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
-
+
SetUpdateHandler(&Scene2208::update);
SetMessageHandler(&Scene2208::handleMessage);
@@ -2165,7 +2165,7 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which)
if (_newRowIndex < 6)
_newRowIndex = 0;
_rowScrollY = 0;
- _backgroundScrollY = 48 * _newRowIndex;
+ _backgroundScrollY = 48 * _newRowIndex;
_currRowIndex = _newRowIndex;
for (int16 rowIndex = 0; rowIndex < _visibleRowsCount; rowIndex++)
@@ -2185,7 +2185,7 @@ Scene2208::~Scene2208() {
void Scene2208::update() {
int16 mouseY = _vm->getMouseY();
-
+
if (mouseY < 48) {
if (_currRowIndex > 0)
_newRowIndex = _currRowIndex - 1;
@@ -2235,7 +2235,7 @@ uint32 Scene2208::handleMessage(int messageNum, const MessageParam &param, Entit
}
void Scene2208::drawRow(int16 rowIndex) {
- NDrawRect sourceRect;
+ NDrawRect sourceRect;
int16 y = (rowIndex * 48) % 528;
if (rowIndex < 4) {
sourceRect.x = 0;
@@ -2280,7 +2280,7 @@ Scene2242::Scene2242(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene2242::handleMessage);
SetUpdateHandler(&Scene2242::update);
-
+
if (getGlobalVar(V_LIGHTS_ON)) {
setBackground(0x11840E24);
setPalette(0x11840E24);
@@ -2297,7 +2297,7 @@ Scene2242::Scene2242(NeverhoodEngine *vm, Module *parentModule, int which)
}
_asTape = insertSprite<AsScene1201Tape>(this, 10, 1100, 464, 435, 0x9148A011);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
if (which < 0) {
// Restoring game
@@ -2380,7 +2380,7 @@ void Scene2242::readClickedColumn() {
}
static const int16 kHallOfRecordsKlaymenXPos[] = {
- 68, 157, 246, 335,
+ 68, 157, 246, 335,
424, 513, 602
};
@@ -2396,7 +2396,7 @@ static const uint32 kHallOfRecordsSceneMessageListIds1[] = {
HallOfRecordsScene::HallOfRecordsScene(NeverhoodEngine *vm, Module *parentModule, int which, uint32 hallOfRecordsInfoId)
: Scene(vm, parentModule) {
-
+
_hallOfRecordsInfo = _vm->_staticData->getHallOfRecordsInfoItem(hallOfRecordsInfoId);
SetMessageHandler(&HallOfRecordsScene::handleMessage);
@@ -2487,7 +2487,7 @@ static const uint32 kScene2247MessageListIds1[] = {
Scene2247::Scene2247(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene2247::handleMessage);
SetUpdateHandler(&Scene::update);
@@ -2524,7 +2524,7 @@ Scene2247::Scene2247(NeverhoodEngine *vm, Module *parentModule, int which)
}
_klaymen->setSoundFlag(true);
-
+
}
Scene2247::~Scene2247() {
diff --git a/engines/neverhood/modules/module2200.h b/engines/neverhood/modules/module2200.h
index af7171dd53..5c19f2a818 100644
--- a/engines/neverhood/modules/module2200.h
+++ b/engines/neverhood/modules/module2200.h
@@ -100,7 +100,7 @@ class SsScene2202PuzzleCube : public StaticSprite {
public:
SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
protected:
- Scene *_parentScene;
+ Scene *_parentScene;
int16 _cubeSymbol;
int16 _cubePosition;
int16 _newX, _newY;
@@ -135,7 +135,7 @@ protected:
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
int16 getFreeCubePosition(int16 index);
- bool testIsSolved();
+ bool testIsSolved();
};
class AsCommonKey : public AnimatedSprite {
diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp
index b434fb98c0..2a46df1ee2 100644
--- a/engines/neverhood/modules/module2300.cpp
+++ b/engines/neverhood/modules/module2300.cpp
@@ -32,12 +32,12 @@ static const uint32 kModule2300SoundList[] = {
Module2300::Module2300(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule), _soundVolume(0) {
-
+
_vm->_soundMan->addSoundList(0x1A214010, kModule2300SoundList);
_vm->_soundMan->setSoundListParams(kModule2300SoundList, true, 50, 600, 10, 150);
_isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
-
+
if (_isWallBroken) {
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
@@ -161,12 +161,12 @@ void Module2300::updateScene() {
} else {
switch (_sceneNum) {
case 1:
- if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
+ if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
navigationScene()->getFrameNumber() % 2) {
_soundVolume++;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
}
- if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 &&
+ if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 &&
navigationScene()->getFrameNumber() == 50) {
_vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0);
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
@@ -182,5 +182,5 @@ void Module2300::updateScene() {
}
}
}
-
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp
index 8d3b763f72..21ea390ba2 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -26,7 +26,7 @@ namespace Neverhood {
Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x202D1010, 0xB110382D);
if (which < 0)
@@ -168,11 +168,11 @@ static const uint32 kScene2401FileHashes3[] = {
};
static const NRect kScene2401Rects[] = {
- NRect(369, 331, 394, 389),
- NRect(395, 331, 419, 389),
- NRect(420, 331, 441, 389),
- NRect(442, 331, 464, 389),
- NRect(465, 331, 491, 389)
+ { 369, 331, 394, 389 },
+ { 395, 331, 419, 389 },
+ { 420, 331, 441, 389 },
+ { 442, 331, 464, 389 },
+ { 465, 331, 491, 389 }
};
static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
@@ -187,7 +187,7 @@ static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1200) {
-
+
_x = 240;
_y = 447;
createSurface(100, 146, 74);
@@ -222,7 +222,7 @@ uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &p
AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
-
+
_x = 88;
_y = 421;
createSurface1(0x10203116, 100);
@@ -262,10 +262,10 @@ uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam
}
return messageResult;
}
-
+
AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
: AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
-
+
_x = x;
_y = y;
createSurface1(0xB8596884, 100);
@@ -308,7 +308,7 @@ uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessagePara
AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
: AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
-
+
_x = 320;
_y = 240;
createSurface1(0x44687810, 100);
@@ -398,7 +398,7 @@ Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
_ssWaterPipes[i] = insertStaticSprite(kScene2401FileHashes1[i], 300);
_ssWaterPipes[i]->setVisible(false);
}
-
+
_asWaterSpit[0] = insertSprite<AsScene2401WaterSpit>();
_asWaterSpit[1] = insertSprite<AsScene2401WaterSpit>();
@@ -461,7 +461,7 @@ void Scene2401::update() {
if (_countdown2 != 0 && (--_countdown2) == 0)
sendMessage(_asFlowingWater, 0x2003, 0);
-
+
Scene::update();
}
@@ -559,7 +559,7 @@ AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool i
} else {
stopAnimation();
setVisible(false);
- }
+ }
SetUpdateHandler(&AsScene2402Door::update);
SetMessageHandler(&AsScene2402Door::handleMessage);
}
@@ -654,7 +654,7 @@ void AsScene2402TV::upFocusKlaymen() {
_newStickFrameIndex = _currFrameIndex;
if (_countdown2 == 0) {
_vm->_soundMan->addSound(0x01520123, 0xC42D4528);
- _vm->_soundMan->playSoundLooping(0xC42D4528);
+ _vm->_soundMan->playSoundLooping(0xC42D4528);
}
_countdown2 = 5;
} else if (_countdown2 != 0 && (--_countdown2 == 0))
@@ -698,7 +698,7 @@ Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
_asTape = insertSprite<AsScene1201Tape>(this, 9, 1100, 286, 409, 0x9148A011);
addCollisionSprite(_asTape);
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
-
+
if (which < 0) {
// Restoring game
insertKlaymen<KmScene2402>(198, 404);
@@ -779,7 +779,7 @@ uint32 Scene2402::handleMessage(int messageNum, const MessageParam &param, Entit
}
return messageResult;
}
-
+
void Scene2402::playPipeSound(uint32 fileHash) {
playSound(_soundToggle ? 0 : 1, fileHash);
_soundToggle = !_soundToggle;
@@ -787,7 +787,7 @@ void Scene2402::playPipeSound(uint32 fileHash) {
Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite1, *tempSprite2, *tempSprite3;
SetMessageHandler(&Scene2403::handleMessage);
@@ -799,7 +799,7 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
addCollisionSprite(_asTape);
_asLightCord = insertSprite<AsScene2803LightCord>(this, 0xA1095A10, 0x836D3813, 368, 200);
_asLightCord->setClipRect(0, 25, 640, 480);
-
+
if (which < 0) {
// Restoring game
_isClimbingLadder = false;
@@ -828,11 +828,11 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
}
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x3130B0EB, 100, 0);
- tempSprite1 = insertStaticSprite(0x20C24220, 1100);
+ tempSprite1 = insertStaticSprite(0x20C24220, 1100);
tempSprite2 = insertStaticSprite(0x03080900, 1300);
tempSprite3 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
tempSprite3->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
- _klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
+ _klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
loadSound(1, calcHash("fxFogHornSoft"));
}
@@ -887,7 +887,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
setGlobalVar(V_KEY3_LOCATION, 2);
SetMessageHandler(&Scene2406::handleMessage);
-
+
setRectList(0x004B78C8);
insertScreenMouse(0xB03001A8);
@@ -913,7 +913,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
setPalette(0x0A038595);
tempSprite1 = insertStaticSprite(0x1712112A, 1100);
}
-
+
tempSprite2 = insertStaticSprite(0x22300924, 1300);
_clipRects[1].x1 = tempSprite1->getDrawRect().x;
_clipRects[1].y1 = tempSprite2->getDrawRect().y;
diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp
index e3a3b74280..46ce2ba4fc 100644
--- a/engines/neverhood/modules/module2500.cpp
+++ b/engines/neverhood/modules/module2500.cpp
@@ -29,29 +29,29 @@ static const uint32 kScene2505StaticSprites[] = {
0x4000A226, 0
};
-static const NRect kScene2505ClipRect = NRect(0, 0, 564, 480);
+static const NRect kScene2505ClipRect = { 0, 0, 564, 480 };
static const uint32 kScene2506StaticSprites[] = {
0x4027AF02, 0
};
-static const NRect kScene2506ClipRect = NRect(0, 0, 640, 441);
+static const NRect kScene2506ClipRect = { 0, 0, 640, 441 };
static const uint32 kScene2508StaticSprites1[] = {
0x2F08E610, 0xD844E6A0, 0
};
-static const NRect kScene2508ClipRect1 = NRect(0, 0, 594, 448);
+static const NRect kScene2508ClipRect1 = { 0, 0, 594, 448 };
static const uint32 kScene2508StaticSprites2[] = {
0x2F08E610, 0
};
-static const NRect kScene2508ClipRect2 = NRect(0, 0, 594, 448);
+static const NRect kScene2508ClipRect2 = { 0, 0, 594, 448 };
Module2500::Module2500(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule), _soundIndex(0) {
-
+
_vm->_soundMan->addMusic(0x29220120, 0x05343184);
_vm->_soundMan->startMusic(0x05343184, 0, 0);
SetMessageHandler(&Module2500::handleMessage);
@@ -212,14 +212,14 @@ uint32 Module2500::handleMessage(int messageNum, const MessageParam &param, Enti
}
return messageResult;
}
-
+
void Module2500::createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites, const NRect *clipRect) {
_childObject = new Scene2704(_vm, this, which, sceneInfoId, value, staticSprites, clipRect);
}
Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2628));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B264C));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2670));
@@ -282,7 +282,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
_asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
_asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
insertSprite<AsCommonCarConnector>(_asCar);
-
+
_newTrackIndex = -1;
_dataResource.load(calcHash("Ashooded"));
@@ -300,9 +300,9 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
sendMessage(_asCar, 0x2008, 150);
}
-
+
_carStatus = 0;
-
+
}
Scene2501::~Scene2501() {
@@ -391,7 +391,7 @@ uint32 Scene2501::handleMessage(int messageNum, const MessageParam &param, Entit
}
return messageResult;
}
-
+
uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -434,7 +434,7 @@ uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam &param, Entity
}
return messageResult;
}
-
+
void Scene2501::moveCarToPoint(NPoint &pt) {
int minMatchTrackIndex, minMatchDistance;
_tracks.findTrackPoint(pt, minMatchTrackIndex, minMatchDistance, _dataResource);
@@ -472,7 +472,7 @@ void Scene2501::updateKlaymenClipRect() {
SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
: StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
-
+
loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
setVisible(false);
loadSound(0, 0x4600204C);
@@ -520,9 +520,9 @@ uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &para
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *ssButton;
-
+
setBackground(0x90791B80);
setPalette(0x90791B80);
ssButton = insertSprite<SsScene2504Button>();
diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp
index 56b4c65f8d..2fce82b777 100644
--- a/engines/neverhood/modules/module2600.cpp
+++ b/engines/neverhood/modules/module2600.cpp
@@ -35,7 +35,7 @@ static const uint32 kModule2600SoundList[] = {
Module2600::Module2600(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
else if (which == 1)
@@ -218,10 +218,10 @@ void Module2600::updateScene() {
}
}
}
-
+
SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
: StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
+
SetUpdateHandler(&SsScene2609Button::update);
SetMessageHandler(&SsScene2609Button::handleMessage);
@@ -273,7 +273,7 @@ uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &para
AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1000) {
-
+
_x = 240;
_y = 420;
setDoDeltaX(1);
@@ -309,7 +309,7 @@ uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isBusy(false) {
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene2609::handleMessage);
diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp
index e9ea10bd16..7aea82f6b1 100644
--- a/engines/neverhood/modules/module2700.cpp
+++ b/engines/neverhood/modules/module2700.cpp
@@ -26,14 +26,14 @@
namespace Neverhood {
-static const NRect kScene2710ClipRect = NRect(0, 0, 626, 480);
+static const NRect kScene2710ClipRect = { 0, 0, 626, 480 };
static const uint32 kScene2710StaticSprites[] = {
0x0D2016C0,
0
};
-static const NRect kScene2711ClipRect = NRect(0, 0, 521, 480);
+static const NRect kScene2711ClipRect = { 0, 0, 521, 480 };
static const uint32 kScene2711FileHashes1[] = {
0,
@@ -68,14 +68,14 @@ static const uint32 kScene2711FileHashes3[] = {
0
};
-static const NRect kScene2724ClipRect = NRect(0, 141, 640, 480);
+static const NRect kScene2724ClipRect = { 0, 141, 640, 480 };
static const uint32 kScene2724StaticSprites[] = {
0xC20D00A5,
0
};
-static const NRect kScene2725ClipRect = NRect(0, 0, 640, 413);
+static const NRect kScene2725ClipRect = { 0, 0, 640, 413 };
static const uint32 kScene2725StaticSprites[] = {
0xC20E00A5,
@@ -84,7 +84,7 @@ static const uint32 kScene2725StaticSprites[] = {
Module2700::Module2700(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule), _soundIndex(0), _radioMusicInitialized(false) {
-
+
_vm->_soundMan->addMusic(0x42212411, 0x04020210);
_vm->_soundMan->startMusic(0x04020210, 24, 2);
SetMessageHandler(&Module2700::handleMessage);
@@ -527,7 +527,7 @@ uint32 Module2700::handleMessage(int messageNum, const MessageParam &param, Enti
}
return messageResult;
}
-
+
void Module2700::createScene2703(int which, uint32 trackInfoId) {
_childObject = new Scene2703(_vm, this, which, trackInfoId);
}
@@ -545,7 +545,7 @@ static const NPoint kCarShadowOffsets[] = {
SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
: StaticSprite(vm, 0) {
-
+
loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
}
@@ -555,7 +555,7 @@ AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar,
SetUpdateHandler(&AsCommonCarShadow::update);
createShadowSurface(shadowSurface, 211, 147, 100);
updateShadow();
-}
+}
void AsCommonCarShadow::update() {
updateShadow();
@@ -589,8 +589,8 @@ AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Spri
SetUpdateHandler(&AsCommonCarConnectorShadow::update);
createShadowSurface1(shadowSurface, 0x60281C10, 150);
startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
void AsCommonCarConnectorShadow::update() {
_x = _asCar->getX() + kCarShadowOffsets[_index].x;
@@ -605,7 +605,7 @@ AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCa
createShadowSurface1(shadowSurface, 0x0759129C, 100);
startAnimation(0x0759129C, frameIndex, -1);
_newStickFrameIndex = frameIndex;
-}
+}
void AsCommonCarTrackShadow::update() {
_x = _asCar->getX();
@@ -615,19 +615,19 @@ void AsCommonCarTrackShadow::update() {
Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
-
+
NRect clipRect;
TrackInfo *tracks = _vm->_staticData->getTrackInfo(0x004B2240);
setGlobalVar(V_CAR_DELTA_X, 1);
-
+
setBackground(tracks->bgFilename);
setPalette(tracks->bgFilename);
_palette->addPalette(calcHash("paPodFloor"), 65, 31, 65);
_palette->addPalette(calcHash("paKlayFloor"), 0, 65, 0);
insertScreenMouse(0x08B08180);
-
+
tempSprite = insertStaticSprite(0x1E086325, 1200);
clipRect.set(0, 0, 640, tempSprite->getDrawRect().y2());
@@ -661,7 +661,7 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
sendMessage(_asCar, 0x2008, 150);
}
-
+
_asCar->setClipRect(clipRect);
_asCarConnector->setClipRect(clipRect);
@@ -715,10 +715,10 @@ uint32 Scene2701::hmCarAtHome(int messageNum, const MessageParam &param, Entity
Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isInLight(true), _newTrackIndex(-1) {
-
+
SetMessageHandler(&Scene2702::handleMessage);
SetUpdateHandler(&Scene2702::update);
-
+
setBackground(0x18808B00);
setPalette(0x18808B00);
_palette->addPalette(calcHash("paPodFloor"), 65, 31, 65);
@@ -734,7 +734,7 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which)
_asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
_asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
_dataResource.load(0x04310014);
-
+
if (which == 1) {
_isUpperTrack = false;
_currTrackIndex = 1;
@@ -765,11 +765,11 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which)
}
if (_isUpperTrack) {
- _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F68));
+ _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F68));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5F8C));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FB0));
} else {
- _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FD8));
+ _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FD8));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B5FFC));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B6020));
}
@@ -873,19 +873,19 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
: Scene(vm, parentModule) {
TrackInfo *tracks = _vm->_staticData->getTrackInfo(trackInfoId);
-
+
SetMessageHandler(&Scene2703::handleMessage);
SetUpdateHandler(&Scene2703::update);
-
+
setBackground(tracks->bgFilename);
setPalette(tracks->bgFilename);
_palette->addPalette(calcHash("paPodShade"), 65, 31, 65);
_palette->addPalette(calcHash("paKlayShade"), 0, 65, 0);
addEntity(_palette);
insertScreenMouse(tracks->mouseCursorFilename);
-
+
_palStatus = 2;
-
+
if (tracks->bgShadowFilename) {
_ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(tracks->bgShadowFilename);
addEntity(_ssTrackShadowBackground);
@@ -905,7 +905,7 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
_dataResource.load(tracks->dataResourceFilename);
_trackPoints = _dataResource.getPointArray(tracks->trackPointsName);
_asCar->setPathPoints(_trackPoints);
-
+
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
@@ -921,7 +921,7 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
else
sendMessage(_asCar, 0x2008, 150);
}
-
+
if (which == 0) {
_palette->addPalette(calcHash("paPodShade"), 65, 31, 65);
_palette->addPalette(calcHash("paKlayShade"), 0, 65, 0);
@@ -931,9 +931,9 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
_palette->addPalette(calcHash("paKlayBlack"), 0, 65, 0);
_palStatus = 0;
}
-
+
_palette->copyBasePalette(0, 256, 0);
-
+
}
void Scene2703::update() {
@@ -981,16 +981,16 @@ uint32 Scene2703::handleMessage(int messageNum, const MessageParam &param, Entit
}
return 0;
}
-
+
Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId, int16 value,
const uint32 *staticSprites, const NRect *clipRect)
: Scene(vm, parentModule) {
TrackInfo *tracks = _vm->_staticData->getTrackInfo(trackInfoId);
-
+
SetMessageHandler(&Scene2704::handleMessage);
SetUpdateHandler(&Scene2704::update);
-
+
setBackground(tracks->bgFilename);
setPalette(tracks->bgFilename);
@@ -999,12 +999,12 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3
if (tracks->exPaletteFilename2)
_palette->addPalette(tracks->exPaletteFilename2, 65, 31, 65);
-
+
while (staticSprites && *staticSprites)
insertStaticSprite(*staticSprites++, 1100);
insertScreenMouse(tracks->mouseCursorFilename);
-
+
if (tracks->bgShadowFilename) {
_ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(tracks->bgShadowFilename);
addEntity(_ssTrackShadowBackground);
@@ -1024,7 +1024,7 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3
_dataResource.load(tracks->dataResourceFilename);
_trackPoints = _dataResource.getPointArray(tracks->trackPointsName);
_asCar->setPathPoints(_trackPoints);
-
+
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
@@ -1040,21 +1040,21 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3
else
sendMessage(_asCar, 0x2008, 0);
}
-
+
if (clipRect) {
_asCar->getClipRect() = *clipRect;
if (_asCarShadow)
- _asCarShadow->getClipRect() = *clipRect;
+ _asCarShadow->getClipRect() = *clipRect;
if (_asCarTrackShadow)
- _asCarTrackShadow->getClipRect() = *clipRect;
+ _asCarTrackShadow->getClipRect() = *clipRect;
if (_asCarConnectorShadow)
- _asCarConnectorShadow->getClipRect() = *clipRect;
+ _asCarConnectorShadow->getClipRect() = *clipRect;
if (_asCarConnector)
_asCarConnector->getClipRect() = *clipRect;
}
}
-
+
void Scene2704::update() {
Scene::update();
if (_mouseClicked) {
@@ -1083,24 +1083,24 @@ uint32 Scene2704::handleMessage(int messageNum, const MessageParam &param, Entit
Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _newTrackIndex(-1) {
-
+
SetMessageHandler(&Scene2706::handleMessage);
- _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22A0));
+ _tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22A0));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22C4));
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B22E8));
-
+
setBackground(0x18808B88);
setPalette(0x18808B88);
-
+
_palette->addPalette(calcHash("paPodShade"), 65, 31, 65);
_palette->addPalette(calcHash("paKlayShade"), 0, 65, 0);
-
+
insertScreenMouse(0x08B8C180);
_ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(0x18808B88);
addEntity(_ssTrackShadowBackground);
-
+
_asCar = insertSprite<AsCommonCar>(this, 320, 240);
_asCarShadow = insertSprite<AsCommonCarShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
_asCarConnector = insertSprite<AsCommonCarConnector>(_asCar);
@@ -1108,10 +1108,10 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
_asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
_dataResource.load(0x06000162);
-
+
if (which == 5)
_currTrackIndex = 2;
- else if (which == 6)
+ else if (which == 6)
_currTrackIndex = 1;
else
_currTrackIndex = 0;
@@ -1123,16 +1123,16 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
if (which == 5)
sendMessage(_asCar, 0x2007, 50);
- else
+ else
sendMessage(_asCar, 0x2007, 150);
} else {
sendMessage(_asCar, 0x2002, 0);
if (which == 5)
sendMessage(_asCar, 0x2008, 50);
- else
+ else
sendMessage(_asCar, 0x2008, 150);
}
-
+
}
uint32 Scene2706::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1192,7 +1192,7 @@ void Scene2706::changeTrack() {
Scene2732::Scene2732(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
setBackground(0x0220C041);
diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp
index 7ab732b4ac..1c0f9fc9fb 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -36,7 +36,7 @@ Module2800::Module2800(NeverhoodEngine *vm, Module *parentModule, int which)
_currentMusicFileHash = 0;
_vm->_soundMan->addMusic(0x64210814, 0xD2FA4D14);
setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 1);
-
+
if (which < 0) {
createScene(_vm->gameState().sceneNum, which);
} else if (which == 2) {
@@ -224,7 +224,7 @@ void Module2800::updateScene() {
_musicResource = NULL;
}
_currentMusicFileHash = 0;
- }
+ }
if (_moduleResult == 1) {
createScene(2, 0);
} else if (_moduleResult == 2) {
@@ -251,7 +251,7 @@ void Module2800::updateScene() {
createScene(9, 0);
else if (_moduleResult == 5)
createScene(25, 0);
- else
+ else
createScene(0, 1);
break;
case 3:
@@ -318,7 +318,7 @@ void Module2800::updateScene() {
createScene(22, 0);
else if (_moduleResult == 22)
createScene(23, 0);
- else
+ else
createScene(2, 4);
break;
case 10:
@@ -331,7 +331,7 @@ void Module2800::updateScene() {
createScene(26, 0);
else if (_moduleResult == 3)
createScene(9, 5);
- else
+ else
createScene(9, 1);
break;
case 12:
@@ -401,7 +401,7 @@ void Module2800::updateMusic(bool halfVolume) {
if (!_musicResource)
_musicResource = new MusicResource(_vm);
-
+
if (newMusicFileHash != _currentMusicFileHash) {
_currentMusicFileHash = newMusicFileHash;
if (_currentMusicFileHash != 0) {
@@ -469,7 +469,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, _sprite2->getDrawRect().x2(), 480);
insertScreenMouse(0x0066201C);
_asTape = insertSprite<AsScene1201Tape>(this, 8, 1100, 302, 437, 0x9148A011);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
} else if (getGlobalVar(V_RADIO_ROOM_RIGHT_DOOR)) {
setRectList(0x004B6CD0);
setBackground(0x11E00684);
@@ -480,7 +480,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(0, 0, _sprite2->getDrawRect().x2(), 480);
insertScreenMouse(0x00680116);
_asTape = insertSprite<SsScene1705Tape>(this, 8, 1100, 302, 437, 0x01142428);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
} else {
setRectList(0x004B6CF0);
setBackground(0x030006E6);
@@ -491,9 +491,9 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(0, 0, _sprite2->getDrawRect().x2(), 480);
insertScreenMouse(0x006E2038);
_asTape = insertSprite<AsScene1201Tape>(this, 8, 1100, 302, 437, 0x9148A011);
- addCollisionSprite(_asTape);
+ addCollisionSprite(_asTape);
}
-
+
addEntity(_palette);
if (which == 1) {
@@ -503,7 +503,7 @@ Scene2801::Scene2801(NeverhoodEngine *vm, Module *parentModule, int which)
_palette->addPalette(_paletteHash, 0, 65, 0);
_palette->addBasePalette(_paletteHash, 0, 65, 0);
}
-
+
}
Scene2801::~Scene2801() {
@@ -565,7 +565,7 @@ Scene2802::~Scene2802() {
}
setGlobalVar(V_CURR_RADIO_MUSIC_INDEX, _currRadioMusicIndex);
}
-
+
void Scene2802::update() {
int prevTuneStatus = _currTuneStatus;
uint prevRadioMusicIndex = _currRadioMusicIndex;
@@ -577,7 +577,7 @@ void Scene2802::update() {
_currTuneStatus = 3;
else if (_currTuneStatus == 4)
_currTuneStatus = 6;
-
+
switch (_currTuneStatus) {
case 2:
if (_currRadioMusicIndex < 90)
@@ -607,20 +607,20 @@ void Scene2802::update() {
} else
_currTuneStatus = 0;
break;
-
+
}
if (prevRadioMusicIndex != _currRadioMusicIndex)
_smackerPlayer->gotoFrame(_currRadioMusicIndex);
-
+
if (prevTuneStatus != _currTuneStatus)
changeTuneStatus(prevTuneStatus, _currTuneStatus);
-
+
if (getGlobalVar(V_RADIO_MOVE_DISH_VIDEO) && prevTuneStatus != _currTuneStatus && _currRadioMusicIndex != 0) {
setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 0);
leaveScene(1);
}
-
+
}
uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -758,7 +758,7 @@ void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2)
: AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) {
-
+
createSurface1(fileHash1, 100);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene2803TestTubeOne::handleMessage);
@@ -781,7 +781,7 @@ uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam
AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
+
createSurface(990, 68, 476);
SetUpdateHandler(&AnimatedSprite::update);
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
@@ -837,7 +837,7 @@ void AsScene2803Rope::stHide() {
Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(0) {
-
+
static const uint32 kScene2803FileHashes1[] = {
0,
0x081000F1,
@@ -854,20 +854,20 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
setGlobalVar(V_BEEN_SHRINKING_ROOM, 1);
_vm->gameModule()->initTestTubes1Puzzle();
-
+
SetMessageHandler(&Scene2803::handleMessage);
-
+
loadDataResource(0x00900849);
-
+
_background = new Background(_vm, 0);
_background->createSurface(0, 640, 480);
addBackground(_background);
-
+
setPalette(0x412A423E);
addEntity(_palette);
-
+
insertScreenMouse(0xA423A41A);
-
+
if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0) == 0) {
_asTestTubeOne = (StaticSprite*)insertStaticSprite(0x66121222, 100);
} else {
@@ -875,13 +875,13 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
kScene2803FileHashes1[getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0)],
kScene2803FileHashes2[getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0)]);
}
-
+
if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1) == 3)
_asTestTubeTwo = (StaticSprite*)insertStaticSprite(0x64330236, 100);
if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2) == 3)
_asTestTubeThree = (StaticSprite*)insertStaticSprite(0x2E4A22A2, 100);
-
+
_asLightCord = insertSprite<AsScene2803LightCord>(this, 0x8FAD5932, 0x276E1A3D, 578, 200);
_sprite3 = (StaticSprite*)insertStaticSprite(0xA40EF2FB, 1100);
_sprite4 = (StaticSprite*)insertStaticSprite(0x0C03AA23, 1100);
@@ -896,7 +896,7 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
_clipRectsFloor[0].y1 = 0;
_clipRectsFloor[0].x2 = 640;
_clipRectsFloor[0].y2 = _sprite8->getDrawRect().y2();
-
+
_clipRectsFloor[1].x1 = _sprite8->getDrawRect().x2();
_clipRectsFloor[1].y1 = _sprite8->getDrawRect().y2();
_clipRectsFloor[1].x2 = 640;
@@ -906,12 +906,12 @@ Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
_clipRectsStairs[0].y1 = 0;
_clipRectsStairs[0].x2 = _sprite5->getDrawRect().x2();
_clipRectsStairs[0].y2 = _sprite5->getDrawRect().y2();
-
+
_clipRectsStairs[1].x1 = _sprite6->getDrawRect().x;
_clipRectsStairs[1].y1 = 0;
_clipRectsStairs[1].x2 = _sprite3->getDrawRect().x;
_clipRectsStairs[1].y2 = _sprite6->getDrawRect().y2();
-
+
_clipRectsStairs[2].x1 = _sprite3->getDrawRect().x;
_clipRectsStairs[2].y1 = 0;
_clipRectsStairs[2].x2 = _sprite4->getDrawRect().x2();
@@ -1112,7 +1112,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh
static const uint32 kScene2803SmallFileHashes2[] = {
0, 0x286800D4, 0x286806D4, 0x28680AD4
};
-
+
SetMessageHandler(&Scene2803Small::handleMessage);
loadDataResource(0x81120132);
@@ -1160,7 +1160,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh
if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2) == 3)
insertStaticSprite(0x30022689, 100);
}
-
+
_sprite6->setVisible(false);
_sprite7->setVisible(false);
@@ -1352,7 +1352,7 @@ void Scene2803Small::updatePaletteArea(bool instantly) {
SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene)
: StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) {
-
+
loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
setVisible(false);
SetUpdateHandler(&SsScene2804RedButton::update);
@@ -1385,7 +1385,7 @@ uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &p
SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
: StaticSprite(vm, 900) {
-
+
loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400);
setVisible(false);
SetMessageHandler(&SsScene2804LightCoil::handleMessage);
@@ -1410,7 +1410,7 @@ uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &p
SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm)
: StaticSprite(vm, 900) {
-
+
loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400);
setVisible(false);
SetMessageHandler(&SsScene2804LightTarget::handleMessage);
@@ -1435,7 +1435,7 @@ uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam
SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm)
: StaticSprite(vm, 900) {
-
+
loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400);
setVisible(false);
loadSound(0, 0xCB36BA54);
@@ -1449,7 +1449,7 @@ void SsScene2804Flash::show() {
SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm)
: StaticSprite(vm, 900) {
-
+
loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400);
setVisible(false);
}
@@ -1585,7 +1585,7 @@ SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene280
0xA8042525,
0x5008292B
};
-
+
loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex],
kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
setVisible(false);
@@ -1619,7 +1619,7 @@ uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessagePara
AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody)
: AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) {
-
+
createSurface1(0x00494891, 1000);
_x = 125;
_y = 184;
@@ -1659,7 +1659,7 @@ uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &pa
}
return messageResult;
}
-
+
void AsScene2804BeamCoil::show() {
_ssBeamCoilBody->setVisible(true);
setVisible(true);
@@ -1695,7 +1695,7 @@ uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param,
AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1400) {
-
+
createSurface1(0x03842000, 1000);
_x = 475;
_y = 278;
@@ -1750,7 +1750,7 @@ Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
_asTarget = insertSprite<AsScene2804BeamTarget>();
_ssFlash = insertSprite<SsScene2804Flash>();
}
-
+
_ssRedButton = insertSprite<SsScene2804RedButton>(this);
addCollisionSprite(_ssRedButton);
@@ -1797,7 +1797,7 @@ uint32 Scene2804::handleMessage(int messageNum, const MessageParam &param, Entit
void Scene2804::update() {
Scene::update();
-
+
if (_countdown1 != 0 && (--_countdown1) == 0) {
leaveScene(0);
}
@@ -1836,7 +1836,7 @@ void Scene2804::update() {
Scene2805::Scene2805(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene2805::handleMessage);
setBackground(0x08021E04);
@@ -1894,7 +1894,7 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entit
AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1200) {
-
+
createSurface1(0x04211490, 1200);
_x = 378;
_y = 423;
@@ -1919,7 +1919,7 @@ uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param,
}
return messageResult;
}
-
+
Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1927,16 +1927,16 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene2806::handleMessage);
SetUpdateHandler(&Scene2806::update);
-
+
loadDataResource(0x98182003);
loadHitRectList();
-
+
_pointList = _dataResource.getPointArray(0x3606A422);
- insertScreenMouse(0x22114C13);
+ insertScreenMouse(0x22114C13);
setBackground(0xC1B22110);
setPalette(0xC1B22110);
-
+
_sprite1 = insertStaticSprite(0xA21F82CB, 1100);
_clipRects[0].x1 = _sprite1->getDrawRect().x;
_clipRects[0].y1 = _sprite1->getDrawRect().y;
@@ -1951,7 +1951,7 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
_sprite4 = insertStaticSprite(0x72090342, 1100);
_clipRects[1].x1 = _sprite4->getDrawRect().x;
_clipRects[1].y1 = _sprite4->getDrawRect().y;
-
+
tempSprite = insertStaticSprite(0xD2012C02, 1100);
_clipRects[2].x1 = tempSprite->getDrawRect().x;
_clipRects[2].y2 = tempSprite->getDrawRect().y2();
@@ -2027,7 +2027,7 @@ void Scene2806::findClosestPoint() {
int16 x = MIN<int16>(_klaymen->getX(), 639);
int index = 1;
-
+
while (index < (int)_pointList->size() && (*_pointList)[index].x < x)
++index;
--index;
@@ -2036,12 +2036,12 @@ void Scene2806::findClosestPoint() {
_pointIndex = index;
_palette->addPalette(kScene2806PaletteFileHashes[index], 0, 64, 0);
}
-
+
}
Scene2807::Scene2807(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene2807::handleMessage);
if (getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0) == 1) {
@@ -2136,7 +2136,7 @@ static const int16 kClass490FrameIndices2[] = {
SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex)
: StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum),
_testTubeIndex(testTubeIndex) {
-
+
loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500);
setVisible(false);
SetUpdateHandler(&SsScene2808Dispenser::update);
@@ -2149,7 +2149,7 @@ void SsScene2808Dispenser::update() {
setVisible(false);
}
}
-
+
uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -2197,16 +2197,16 @@ AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum
loadSound(7, 0x70A43D2D);
loadSound(8, 0xF0601E2D);
}
-
+
startAnimation(kClass490FileHashes[testTubeIndex], 0, -1);
_newStickFrameIndex = 0;
-
+
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene2808TestTube::handleMessage);
-
+
if (_fillLevel == 0)
setVisible(false);
-
+
}
uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -2253,7 +2253,7 @@ void AsScene2808TestTube::flush() {
AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
: AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) {
-
+
loadSound(0, 0xE18D1F30);
_x = 320;
_y = 240;
@@ -2325,7 +2325,7 @@ AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int te
SetUpdateHandler(&AnimatedSprite::update);
AnimatedSprite::updatePosition();
}
-
+
uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -2351,7 +2351,7 @@ void AsScene2808Flow::stKeepFlowing() {
AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum)
: AnimatedSprite(vm, 800), _countdown(1) {
-
+
_x = 320;
_y = 240;
if (testTubeSetNum == 1)
@@ -2381,7 +2381,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
_vm->gameModule()->initTestTubes1Puzzle();
else
_vm->gameModule()->initTestTubes2Puzzle();
-
+
SetMessageHandler(&Scene2808::handleMessage);
SetUpdateHandler(&Scene2808::update);
@@ -2400,7 +2400,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
_asTestTubes[testTubeIndex] = insertSprite<AsScene2808TestTube>(which, testTubeIndex, ssDispenser);
addCollisionSprite(_asTestTubes[testTubeIndex]);
}
-
+
insertScreenMouse(kScene2808FileHashes2[which]);
}
@@ -2498,13 +2498,13 @@ Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
Sprite *tempSprite;
-
+
SetMessageHandler(&Scene2809::handleMessage);
SetUpdateHandler(&Scene2809::update);
-
+
loadDataResource(0x1830009A);
loadHitRectList();
-
+
_pointList = _dataResource.getPointArray(0x064A310E);
setBackground(0xB22116C5);
@@ -2535,7 +2535,7 @@ Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which)
tempSprite = insertStaticSprite(0x877F6252, 1100);
_clipRects[3].x2 = tempSprite->getDrawRect().x2();
-
+
insertStaticSprite(0x01612A22, 1100);
insertStaticSprite(0x877F6252, 1100);
@@ -2610,7 +2610,7 @@ void Scene2809::findClosestPoint() {
_pointIndex = index;
_palette->addPalette(kScene2809PaletteFileHashes[index], 0, 64, 0);
}
-
+
}
AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
@@ -2647,7 +2647,7 @@ Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)
Sprite *tempSprite;
SetMessageHandler(&Scene2810::handleMessage);
-
+
setBackground(0x26508804);
setPalette(0x26508804);
insertScreenMouse(0x0880026D);
@@ -2683,7 +2683,7 @@ Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)
}
_sprite4->setClipRect(0, _sprite1->getDrawRect().y, 640, 480);
}
-
+
if (which < 0) {
if (getGlobalVar(V_KLAYMEN_SMALL)) {
insertKlaymen<KmScene2810Small>(240, 448);
@@ -2864,7 +2864,7 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100) {
-
+
createSurface1(0x20DA08A0, 1200);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene2812Winch::handleMessage);
@@ -2895,7 +2895,7 @@ uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param
AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
+
createSurface(990, 68, 476);
SetUpdateHandler(&AnimatedSprite::update);
SetMessageHandler(&AsScene2812Rope::handleMessage);
@@ -2940,7 +2940,7 @@ void AsScene2812Rope::stRopingDown() {
AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
: AnimatedSprite(vm, 0x805D0029, 100, 320, 240) {
-
+
SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
_newStickFrameIndex = 0;
}
@@ -2959,15 +2959,15 @@ uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &pa
Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(0) {
-
+
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
setGlobalVar(V_KEY3_LOCATION, 3);
SetMessageHandler(&Scene2812::handleMessage);
SetUpdateHandler(&Scene2812::update);
-
+
setRectList(0x004AF700);
-
+
setBackground(0x03600606);
setPalette(0x03600606);
addEntity(_palette);
@@ -2983,7 +2983,7 @@ Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)
_ssTape = insertSprite<SsScene1705Tape>(this, 6, 1100, 513, 437, 0xA1361863);
addCollisionSprite(_ssTape);
-
+
_asWinch = insertSprite<AsScene2812Winch>();
_asTrapDoor = insertSprite<AsScene2812TrapDoor>();
_asRope = insertSprite<AsScene2812Rope>(this);
@@ -3023,9 +3023,9 @@ Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)
_sprite1->setVisible(false);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
}
-
+
_asRope->setClipRect(0, _sprite2->getDrawRect().y, 640, _sprite3->getDrawRect().y2());
-
+
}
void Scene2812::update() {
@@ -3140,7 +3140,7 @@ void Scene2822::update() {
_ssButton->setVisible(false);
_countdownStatus = 1;
_countdown = 48;
- } else if (_countdownStatus == 1) {
+ } else if (_countdownStatus == 1 && getGlobalVar(V_LADDER_DOWN_ACTION)) {
playSound(0, 0x1384CB60);
_countdownStatus = 2;
_countdown = 12;
diff --git a/engines/neverhood/modules/module2800.h b/engines/neverhood/modules/module2800.h
index fe62f11307..54a9daeb16 100644
--- a/engines/neverhood/modules/module2800.h
+++ b/engines/neverhood/modules/module2800.h
@@ -79,7 +79,7 @@ public:
protected:
Scene *_parentScene;
uint32 _fileHash1, _fileHash2;
- bool _isPulled, _isBusy;
+ bool _isPulled, _isBusy;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
uint32 hmPulled(int messageNum, const MessageParam &param, Entity *sender);
};
@@ -323,7 +323,7 @@ protected:
Scene *_parentScene;
int _countdown;
int _testTubeSetNum, _testTubeIndex;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
@@ -408,7 +408,7 @@ protected:
Sprite *_sprite3;
Sprite *_sprite4;
Sprite *_asSpew;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void findClosestPoint();
};
diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp
index 248fb81bdc..9e51001a2e 100644
--- a/engines/neverhood/modules/module2900.cpp
+++ b/engines/neverhood/modules/module2900.cpp
@@ -36,7 +36,7 @@ Module2900::Module2900(NeverhoodEngine *vm, Module *parentModule, int which)
if (which >= 0)
setGlobalVar(V_TELEPORTER_WHICH, which);
-
+
createScene(0, 0);
}
@@ -255,7 +255,7 @@ SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene
: 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);
@@ -263,7 +263,7 @@ SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene
SetUpdateHandler(&SsScene2901LocationButton::update);
SetMessageHandler(&SsScene2901LocationButton::handleMessage);
}
-
+
void SsScene2901LocationButton::update() {
updatePosition();
if (_countdown1 != 0 && (--_countdown1) == 0) {
@@ -289,7 +289,7 @@ uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessagePar
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]);
@@ -315,7 +315,7 @@ SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
: StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
- loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
+ loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
_collisionBounds.set(62, 94, 322, 350);
setVisible(false);
loadSound(0, 0xF3D420C8);
@@ -330,7 +330,7 @@ void SsScene2901BigButton::update() {
sendMessage(_parentScene, 0x2000, 0);
}
}
-
+
uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
@@ -361,7 +361,7 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
setBackground(kScene2901FileHashes1[_currLocationButtonNum]);
setPalette(kScene2901FileHashes1[_currLocationButtonNum]);
-
+
for (uint i = 0; i < 6; ++i) {
if (i != 2 || !_isButton2Broken) {
_ssLocationButtons[i] = insertSprite<SsScene2901LocationButton>(this, _currLocationButtonNum, i);
@@ -369,7 +369,7 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
_ssLocationButtonLights[i] = insertSprite<SsScene2901LocationButtonLight>(_currLocationButtonNum, i);
}
}
-
+
if (_isButton2Broken)
insertSprite<SsScene2901BrokenButton>(_currLocationButtonNum);
@@ -377,10 +377,10 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
addCollisionSprite(_ssBigButton);
insertPuzzleMouse(kScene2901FileHashes2[_currLocationButtonNum], 20, 620);
-
+
SetUpdateHandler(&Scene2901::update);
SetMessageHandler(&Scene2901::handleMessage);
-
+
}
void Scene2901::update() {
diff --git a/engines/neverhood/modules/module2900.h b/engines/neverhood/modules/module2900.h
index 75b29567f6..142f39a35c 100644
--- a/engines/neverhood/modules/module2900.h
+++ b/engines/neverhood/modules/module2900.h
@@ -49,7 +49,7 @@ protected:
Scene *_parentScene;
uint _index;
int _countdown1;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
@@ -74,7 +74,7 @@ protected:
Scene *_parentScene;
int _which;
int _countdown1;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index f483e0c95f..ab3c18d1f4 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -39,7 +39,7 @@ static const uint32 kModule3000SoundList[] = {
Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule), _soundVolume(0) {
-
+
_vm->_soundMan->addSoundList(0x81293110, kModule3000SoundList);
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 50, 600, 5, 150);
_vm->_soundMan->setSoundParams(0x90F0D1C3, false, 20000, 30000, 20000, 30000);
@@ -440,7 +440,7 @@ static const uint32 kAsScene3009SymbolFileHashes[] = {
};
static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
- 0x24016060,
+ 0x24016060,
0x21216221,
0x486160A0,
0x42216422,
@@ -455,7 +455,7 @@ static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
};
static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
- 0x40092024,
+ 0x40092024,
0x01636002,
0x8071E028,
0x02A56064,
@@ -471,7 +471,7 @@ static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
: StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
-
+
loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
setVisible(false);
SetUpdateHandler(&SsScene3009FireCannonButton::update);
@@ -637,7 +637,7 @@ uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const Message
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);
@@ -702,7 +702,7 @@ AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene
: 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);
@@ -753,17 +753,17 @@ void AsScene3009Symbol::hide() {
}
Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
- : Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
+ : Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
_isTurning(false), _lockSymbolsPart1Countdown(1), _lockSymbolsPart2Countdown(1) {
_cannonTargetStatus = getGlobalVar(V_CANNON_TARGET_STATUS);
-
+
_vm->gameModule()->initCannonSymbolsPuzzle();
-
+
setGlobalVar(V_CANNON_SMACKER_NAME, 0);
-
+
_vm->_screen->clear();
-
+
setBackground(0xD000420C);
setPalette(0xD000420C);
insertPuzzleMouse(0x04208D08, 20, 620);
@@ -821,7 +821,7 @@ void Scene3009::openSmacker(uint32 fileHash, bool keepLastFrame) {
void Scene3009::update() {
Scene::update();
-
+
if (!_keepVideo && _cannonSmackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) {
switch (_cannonTargetStatus) {
case kCTSNull:
@@ -850,9 +850,9 @@ void Scene3009::update() {
if (_moveCannonLeftFirst) {
if (_cannonTargetStatus == kCTSLeftRobotNoTarget)
openSmacker(0x110A000F, false);
- else if (_cannonTargetStatus == kCTSLeftRobotIsTarget)
+ else if (_cannonTargetStatus == kCTSLeftRobotIsTarget)
openSmacker(0x500B004F, false);
- else if (_cannonTargetStatus == kCTSLeftNoRobot)
+ else if (_cannonTargetStatus == kCTSLeftNoRobot)
openSmacker(0x100B010E, false);
_moveCannonLeftFirst = false;
_asHorizontalIndicator->stMoveLeft();
@@ -1119,7 +1119,7 @@ AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene
loadSound(0, 0x420073DC);
loadSound(1, 0x420073DC);
}
-
+
setVisible(false);
stIdle();
if (initUnlocked)
@@ -1127,7 +1127,7 @@ AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene
_needRefresh = true;
AnimatedSprite::updatePosition();
-
+
}
void AsScene3010DeadBolt::update() {
@@ -1217,7 +1217,7 @@ void AsScene3010DeadBolt::stDisabledMessage() {
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
-
+
int initCountdown = 0;
setBackground(0x80802626);
@@ -1348,7 +1348,7 @@ static const uint32 kAsScene3011SymbolFileHashes[] = {
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);
@@ -1446,7 +1446,7 @@ Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene3011::handleMessage);
SetUpdateHandler(&Scene3011::update);
-
+
setBackground(0x92124A04);
setPalette(0xA4070114);
addEntity(_palette);
@@ -1458,12 +1458,12 @@ Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
_ssButton = insertSprite<SsScene3011Button>(this, true);
addCollisionSprite(_ssButton);
-
+
}
void Scene3011::update() {
Scene::update();
-
+
if (_countdown != 0 && (--_countdown == 0)) {
switch (_updateStatus) {
case 0:
diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h
index 797be1885f..a6cecb227e 100644
--- a/engines/neverhood/modules/module3000.h
+++ b/engines/neverhood/modules/module3000.h
@@ -244,7 +244,7 @@ protected:
bool _buttonClicked;
int _countdown;
int _noisySymbolIndex;
- int _currentSymbolIndex;
+ int _currentSymbolIndex;
int _noisyRandomSymbolIndex;
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
diff --git a/engines/neverhood/mouse.cpp b/engines/neverhood/mouse.cpp
index 632f56fb74..f11a3f99ea 100644
--- a/engines/neverhood/mouse.cpp
+++ b/engines/neverhood/mouse.cpp
@@ -26,9 +26,9 @@
namespace Neverhood {
Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect)
- : StaticSprite(vm, 2000), _mouseType(kMouseType433),
+ : StaticSprite(vm, 2000), _mouseType(kMouseType433),
_mouseCursorResource(vm), _frameNum(0) {
-
+
_mouseRect = mouseRect;
init(fileHash);
if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 &&
@@ -43,7 +43,7 @@ Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect)
Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int16 x1, int16 x2)
: StaticSprite(vm, 2000), _mouseType(kMouseType435),
_mouseCursorResource(vm), _frameNum(0), _x1(x1), _x2(x2) {
-
+
init(fileHash);
if (_x <= _x1) {
_mouseCursorResource.setCursorNum(6);
@@ -69,8 +69,8 @@ Mouse::~Mouse() {
void Mouse::init(uint32 fileHash) {
_mouseCursorResource.load(fileHash);
- _x = _vm->getMouseX();
- _y = _vm->getMouseY();
+ _x = _vm->getMouseX();
+ _y = _vm->getMouseY();
createSurface(2000, 32, 32);
SetUpdateHandler(&Mouse::update);
SetMessageHandler(&Mouse::handleMessage);
@@ -99,7 +99,7 @@ void Mouse::update() {
_frameNum++;
if (_frameNum >= 6)
_frameNum = 0;
- _needRefresh = _frameNum % 2 == 0;
+ _needRefresh = _frameNum % 2 == 0;
}
uint32 Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -113,40 +113,40 @@ uint32 Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *s
case 1:
if (_x >= 320)
messageResult = 1;
- else
+ else
messageResult = 0;
break;
case 2:
default:
if (_x < 100)
messageResult = 0;
- else if (_x > 540)
+ else if (_x > 540)
messageResult = 1;
- else
+ else
messageResult = 2;
break;
case 3:
if (_x < 100)
messageResult = 0;
- else if (_x > 540)
+ else if (_x > 540)
messageResult = 1;
- else
+ else
messageResult = 4;
break;
case 4:
if (_x < 100)
messageResult = 0;
- else if (_x > 540)
+ else if (_x > 540)
messageResult = 1;
- else if (_y >= 150)
+ else if (_y >= 150)
messageResult = 2;
- else
+ else
messageResult = 3;
break;
case 5:
if (_y >= 240)
messageResult = 4;
- else
+ else
messageResult = 3;
break;
}
@@ -162,7 +162,7 @@ uint32 Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *s
}
void Mouse::updateCursor() {
-
+
if (!_surface)
return;
@@ -183,7 +183,7 @@ void Mouse::updateCursor() {
_drawOffset = _mouseCursorResource.getRect();
_surface->drawMouseCursorResource(_mouseCursorResource, _frameNum / 2);
Graphics::Surface *cursorSurface = _surface->getSurface();
- CursorMan.replaceCursor((const byte*)cursorSurface->pixels,
+ CursorMan.replaceCursor((const byte*)cursorSurface->getPixels(),
cursorSurface->w, cursorSurface->h, -_drawOffset.x, -_drawOffset.y, 0);
}
@@ -213,44 +213,44 @@ void Mouse::updateCursorNum() {
case 1:
if (_x >= 320)
_mouseCursorResource.setCursorNum(5);
- else
+ else
_mouseCursorResource.setCursorNum(6);
break;
case 2:
default:
if (_x < 100)
_mouseCursorResource.setCursorNum(6);
- else if (_x > 540)
+ else if (_x > 540)
_mouseCursorResource.setCursorNum(5);
- else
+ else
_mouseCursorResource.setCursorNum(0);
break;
case 3:
if (_x < 100)
_mouseCursorResource.setCursorNum(1);
- else if (_x > 540)
+ else if (_x > 540)
_mouseCursorResource.setCursorNum(1);
break;
case 4:
if (_x < 100)
_mouseCursorResource.setCursorNum(6);
- else if (_x > 540)
+ else if (_x > 540)
_mouseCursorResource.setCursorNum(5);
- else if (_y >= 150)
+ else if (_y >= 150)
_mouseCursorResource.setCursorNum(0);
- else
+ else
_mouseCursorResource.setCursorNum(3);
break;
case 5:
if (_y >= 240)
_mouseCursorResource.setCursorNum(2);
- else
+ else
_mouseCursorResource.setCursorNum(3);
break;
}
break;
}
-
+
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/mouse.h b/engines/neverhood/mouse.h
index 0b927de4df..d6f42b4071 100644
--- a/engines/neverhood/mouse.h
+++ b/engines/neverhood/mouse.h
@@ -52,7 +52,7 @@ protected:
int16 _x1;
int16 _x2;
int _type;
- void init(uint32 fileHash);
+ void init(uint32 fileHash);
void update();
void updateCursorNum();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
index 073d18f47b..51ab96ef37 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -35,19 +35,19 @@ NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint
_isWalkingForward(false), _isTurning(false), _smackerFileHash(0), _interactive(true), _leaveSceneAfter(false) {
_navigationList = _vm->_staticData->getNavigationList(navigationListId);
-
+
if (_navigationIndex < 0) {
_navigationIndex = (int)getGlobalVar(V_NAVIGATION_INDEX);
if (_navigationIndex >= (int)_navigationList->size())
- _navigationIndex = 0;
+ _navigationIndex = 0;
}
setGlobalVar(V_NAVIGATION_INDEX, _navigationIndex);
-
+
SetUpdateHandler(&NavigationScene::update);
SetMessageHandler(&NavigationScene::handleMessage);
-
- _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true));
-
+
+ _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true));
+
createMouseCursor();
_vm->_screen->clear();
@@ -99,7 +99,7 @@ void NavigationScene::update() {
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
sendMessage(_parentModule, 0x100A, _navigationIndex);
}
- }
+ }
Scene::update();
}
@@ -135,7 +135,7 @@ void NavigationScene::createMouseCursor() {
mouseCursorFileHash = navigationItem.mouseCursorFileHash;
if (mouseCursorFileHash == 0)
mouseCursorFileHash = 0x63A40028;
-
+
if (_itemsTypes)
areaType = _itemsTypes[_navigationIndex];
else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag)
@@ -152,7 +152,7 @@ void NavigationScene::handleNavigation(const NPoint &mousePos) {
bool oldIsWalkingForward = _isWalkingForward;
bool oldIsTurning = _isTurning;
uint32 direction = sendPointMessage(_mouseCursor, 0x2064, mousePos);
-
+
switch (direction) {
case 0:
if (navigationItem.leftSmackerFileHash != 0) {
@@ -203,7 +203,7 @@ void NavigationScene::handleNavigation(const NPoint &mousePos) {
}
break;
}
-
+
if (oldIsTurning != _isTurning)
_vm->_soundMan->setSoundThreePlayFlag(_isTurning);
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index e7c9f32d45..061e6d1279 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -104,9 +104,9 @@ Common::Error NeverhoodEngine::run() {
_soundMan = new SoundMan(this);
_audioResourceMan = new AudioResourceMan(this);
-
+
_gameModule = new GameModule(this);
-
+
_isSaveAllowed = true;
_updateSound = true;
@@ -122,15 +122,15 @@ Common::Error NeverhoodEngine::run() {
(*navigationList)[5].middleSmackerFileHash = 0;
(*navigationList)[5].middleFlag = 1;
}
-
+
if (ConfMan.hasKey("save_slot")) {
if (loadGameState(ConfMan.getInt("save_slot")).getCode() != Common::kNoError)
_gameModule->startup();
} else
_gameModule->startup();
-
+
mainLoop();
-
+
delete _gameModule;
delete _soundMan;
delete _audioResourceMan;
@@ -141,7 +141,7 @@ Common::Error NeverhoodEngine::run() {
delete _gameVars;
delete _staticData;
-
+
return Common::kNoError;
}
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 773e80df7d..5643e345ad 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -93,7 +93,7 @@ public:
AudioResourceMan *_audioResourceMan;
public:
-
+
/* Save/load */
enum kReadSaveHeaderError {
@@ -118,7 +118,7 @@ public:
bool canLoadGameStateCurrently() { return _isSaveAllowed; }
bool canSaveGameStateCurrently() { return _isSaveAllowed; }
-
+
Common::Error loadGameState(int slot);
Common::Error saveGameState(int slot, const Common::String &description);
Common::Error removeGameState(int slot);
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index d4b9b67f53..c381f46671 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -81,7 +81,7 @@ void Palette::addPalette(uint32 fileHash, int toIndex, int count, int fromIndex)
if (toIndex + count > 256)
count = 256 - toIndex;
paletteResource.load(fileHash);
- memcpy(_palette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4);
+ memcpy(_palette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4);
_vm->_screen->testPalette(_palette);
}
@@ -90,20 +90,20 @@ void Palette::addBasePalette(uint32 fileHash, int toIndex, int count, int fromIn
if (toIndex + count > 256)
count = 256 - toIndex;
paletteResource.load(fileHash);
- memcpy(_basePalette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4);
+ memcpy(_basePalette + toIndex * 4, paletteResource.palette() + fromIndex * 4, count * 4);
}
void Palette::copyPalette(const byte *palette, int toIndex, int count, int fromIndex) {
if (toIndex + count > 256)
count = 256 - toIndex;
- memcpy(_palette + toIndex * 4, palette + fromIndex * 4, count * 4);
+ memcpy(_palette + toIndex * 4, palette + fromIndex * 4, count * 4);
_vm->_screen->testPalette(_palette);
}
void Palette::copyBasePalette(int toIndex, int count, int fromIndex) {
if (toIndex + count > 256)
count = 256 - toIndex;
- memcpy(_basePalette + toIndex * 4, _palette + fromIndex * 4, count * 4);
+ memcpy(_basePalette + toIndex * 4, _palette + fromIndex * 4, count * 4);
}
void Palette::startFadeToBlack(int counter) {
@@ -115,7 +115,7 @@ void Palette::startFadeToBlack(int counter) {
_fadeToB = 0;
_palCounter = counter;
_fadeStep = 255 / counter;
- _status = 1;
+ _status = 1;
}
void Palette::startFadeToWhite(int counter) {
@@ -127,7 +127,7 @@ void Palette::startFadeToWhite(int counter) {
_fadeToB = 255;
_palCounter = counter;
_fadeStep = 255 / counter;
- _status = 1;
+ _status = 1;
}
void Palette::startFadeToPalette(int counter) {
@@ -136,7 +136,7 @@ void Palette::startFadeToPalette(int counter) {
counter = 1;
_palCounter = counter;
_fadeStep = 255 / counter;
- _status = 2;
+ _status = 2;
}
void Palette::fillBaseWhite(int index, int count) {
diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp
index 442713196e..a1a517f251 100644
--- a/engines/neverhood/resource.cpp
+++ b/engines/neverhood/resource.cpp
@@ -39,7 +39,7 @@ SpriteResource::~SpriteResource() {
void SpriteResource::draw(Graphics::Surface *destSurface, bool flipX, bool flipY) {
if (_pixels) {
- byte *dest = (byte*)destSurface->pixels;
+ byte *dest = (byte*)destSurface->getPixels();
const int destPitch = destSurface->pitch;
if (_rle)
unpackSpriteRle(_pixels, _dimensions.width, _dimensions.height, dest, destPitch, flipX, flipY);
@@ -57,7 +57,7 @@ bool SpriteResource::load(uint32 fileHash, bool doLoadPosition) {
const byte *spriteData = _resourceHandle.data();
NPoint *position = doLoadPosition ? &_position : NULL;
parseBitmapResource(spriteData, &_rle, &_dimensions, position, NULL, &_pixels);
- }
+ }
return _pixels != NULL;
}
@@ -116,7 +116,7 @@ AnimResource::~AnimResource() {
void AnimResource::draw(uint frameIndex, Graphics::Surface *destSurface, bool flipX, bool flipY) {
const AnimFrameInfo frameInfo = _frames[frameIndex];
- byte *dest = (byte*)destSurface->pixels;
+ byte *dest = (byte*)destSurface->getPixels();
const int destPitch = destSurface->pitch;
_currSpriteData = _spriteData + frameInfo.spriteDataOffs;
_width = frameInfo.drawOffset.width;
@@ -134,11 +134,11 @@ bool AnimResource::load(uint32 fileHash) {
return true;
unload();
-
+
_vm->_res->queryResource(fileHash, _resourceHandle);
if (!_resourceHandle.isValid() || _resourceHandle.type() != kResTypeAnimation)
return false;
-
+
const byte *resourceData, *animList, *frameList;
uint16 animInfoStartOfs, animListIndex, animListCount;
uint16 frameListStartOfs, frameCount;
@@ -146,20 +146,20 @@ bool AnimResource::load(uint32 fileHash) {
_vm->_res->loadResource(_resourceHandle);
resourceData = _resourceHandle.data();
-
+
animListCount = READ_LE_UINT16(resourceData);
animInfoStartOfs = READ_LE_UINT16(resourceData + 2);
spriteDataOfs = READ_LE_UINT32(resourceData + 4);
paletteDataOfs = READ_LE_UINT32(resourceData + 8);
-
+
animList = resourceData + 12;
for (animListIndex = 0; animListIndex < animListCount; animListIndex++) {
debug(8, "hash: %08X", READ_LE_UINT32(animList));
if (READ_LE_UINT32(animList) == fileHash)
break;
- animList += 8;
+ animList += 8;
}
-
+
if (animListIndex >= animListCount) {
_vm->_res->unloadResource(_resourceHandle);
return false;
@@ -168,12 +168,12 @@ bool AnimResource::load(uint32 fileHash) {
_spriteData = resourceData + spriteDataOfs;
if (paletteDataOfs > 0)
_paletteData = resourceData + paletteDataOfs;
-
+
frameCount = READ_LE_UINT16(animList + 4);
frameListStartOfs = READ_LE_UINT16(animList + 6);
-
+
debug(8, "frameCount = %d; frameListStartOfs = %04X; animInfoStartOfs = %04X", frameCount, frameListStartOfs, animInfoStartOfs);
-
+
frameList = resourceData + animInfoStartOfs + frameListStartOfs;
_frames.clear();
@@ -189,13 +189,13 @@ bool AnimResource::load(uint32 fileHash) {
frameInfo.drawOffset.height = READ_LE_UINT16(frameList + 12);
frameInfo.deltaX = READ_LE_UINT16(frameList + 14);
frameInfo.deltaY = READ_LE_UINT16(frameList + 16);
- frameInfo.collisionBoundsOffset.x = READ_LE_UINT16(frameList + 18);
- frameInfo.collisionBoundsOffset.y = READ_LE_UINT16(frameList + 20);
- frameInfo.collisionBoundsOffset.width = READ_LE_UINT16(frameList + 22);
+ frameInfo.collisionBoundsOffset.x = READ_LE_UINT16(frameList + 18);
+ frameInfo.collisionBoundsOffset.y = READ_LE_UINT16(frameList + 20);
+ frameInfo.collisionBoundsOffset.width = READ_LE_UINT16(frameList + 22);
frameInfo.collisionBoundsOffset.height = READ_LE_UINT16(frameList + 24);
frameInfo.spriteDataOffs = READ_LE_UINT32(frameList + 28);
- debug(8, "frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; collisionBoundsOffset = (%d,%d,%d,%d); spriteDataOffs = %08X",
- frameInfo.frameHash, frameInfo.counter,
+ debug(8, "frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; collisionBoundsOffset = (%d,%d,%d,%d); spriteDataOffs = %08X",
+ frameInfo.frameHash, frameInfo.counter,
frameInfo.drawOffset.x, frameInfo.drawOffset.y, frameInfo.drawOffset.width, frameInfo.drawOffset.height,
frameInfo.deltaX, frameInfo.deltaY,
frameInfo.collisionBoundsOffset.x, frameInfo.collisionBoundsOffset.y, frameInfo.collisionBoundsOffset.width, frameInfo.collisionBoundsOffset.height,
@@ -203,11 +203,11 @@ bool AnimResource::load(uint32 fileHash) {
frameList += 32;
_frames.push_back(frameInfo);
}
-
+
_fileHash = fileHash;
return true;
-
+
}
void AnimResource::unload() {
@@ -229,7 +229,7 @@ int16 AnimResource::getFrameIndex(uint32 frameHash) {
break;
}
debug(2, "AnimResource::getFrameIndex(%08X) -> %d", frameHash, frameIndex);
- return frameIndex;
+ return frameIndex;
}
void AnimResource::setRepl(byte oldColor, byte newColor) {
@@ -254,7 +254,7 @@ NDimensions AnimResource::loadSpriteDimensions(uint32 fileHash) {
// MouseCursorResource
-MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm)
+MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm)
: _cursorSprite(vm), _cursorNum(4), _currFileHash(0) {
_rect.width = 32;
@@ -265,7 +265,7 @@ void MouseCursorResource::load(uint32 fileHash) {
if (_currFileHash != fileHash) {
if (_cursorSprite.load(fileHash) && !_cursorSprite.isRle() &&
_cursorSprite.getDimensions().width == 96 && _cursorSprite.getDimensions().height == 224) {
- _currFileHash = fileHash;
+ _currFileHash = fileHash;
} else {
unload();
}
@@ -296,14 +296,14 @@ NDrawRect& MouseCursorResource::getRect() {
void MouseCursorResource::draw(int frameNum, Graphics::Surface *destSurface) {
if (_cursorSprite.getPixels()) {
const int sourcePitch = (_cursorSprite.getDimensions().width + 3) & 0xFFFC; // 4 byte alignment
- const int destPitch = destSurface->pitch;
+ const int destPitch = destSurface->pitch;
const byte *source = _cursorSprite.getPixels() + _cursorNum * (sourcePitch * 32) + frameNum * 32;
- byte *dest = (byte*)destSurface->pixels;
+ byte *dest = (byte*)destSurface->getPixels();
for (int16 yc = 0; yc < 32; yc++) {
memcpy(dest, source, 32);
source += sourcePitch;
dest += destPitch;
- }
+ }
}
}
@@ -311,7 +311,7 @@ void MouseCursorResource::draw(int frameNum, Graphics::Surface *destSurface) {
TextResource::TextResource(NeverhoodEngine *vm)
: _vm(vm), _textData(NULL), _count(0) {
-
+
}
TextResource::~TextResource() {
@@ -372,7 +372,7 @@ void DataResource::load(uint32 fileHash) {
dataS.seek(2 + i * 8);
DRDirectoryItem drDirectoryItem;
drDirectoryItem.nameHash = dataS.readUint32LE();
- drDirectoryItem.offset = dataS.readUint16LE();
+ drDirectoryItem.offset = dataS.readUint16LE();
drDirectoryItem.type = dataS.readUint16LE();
debug(2, "%03d nameHash = %08X; offset = %04X; type = %d", i, drDirectoryItem.nameHash, drDirectoryItem.offset, drDirectoryItem.type);
dataS.seek(itemStartOffs + drDirectoryItem.offset);
@@ -415,7 +415,7 @@ void DataResource::load(uint32 fileHash) {
hitRect.rect.y1 = dataS.readUint16LE();
hitRect.rect.x2 = dataS.readUint16LE();
hitRect.rect.y2 = dataS.readUint16LE();
- hitRect.type = dataS.readUint16LE() + 0x5001;
+ hitRect.type = dataS.readUint16LE() + 0x5001;
debug(3, "(%d, %d, %d, %d) -> %04d", hitRect.rect.x1, hitRect.rect.y1, hitRect.rect.x2, hitRect.rect.y2, hitRect.type);
hitRectList->push_back(hitRect);
}
@@ -491,7 +491,7 @@ void DataResource::load(uint32 fileHash) {
break;
}
}
- _directory.push_back(drDirectoryItem);
+ _directory.push_back(drDirectoryItem);
}
}
}
@@ -540,12 +540,12 @@ HitRectList *DataResource::getHitRectList() {
MessageList *DataResource::getMessageListAtPos(int16 klaymenX, int16 klaymenY, int16 mouseX, int16 mouseY) {
for (uint i = 0; i < _drRects.size(); i++) {
- if (klaymenX >= _drRects[i].rect.x1 && klaymenX <= _drRects[i].rect.x2 &&
+ if (klaymenX >= _drRects[i].rect.x1 && klaymenX <= _drRects[i].rect.x2 &&
klaymenY >= _drRects[i].rect.y1 && klaymenY <= _drRects[i].rect.y2) {
- DRSubRectList *drSubRectList = _drSubRectLists[_drRects[i].subRectIndex];
+ DRSubRectList *drSubRectList = _drSubRectLists[_drRects[i].subRectIndex];
for (uint j = 0; j < drSubRectList->size(); j++) {
DRSubRect &subRect = (*drSubRectList)[j];
- if (mouseX >= subRect.rect.x1 && mouseX <= subRect.rect.x2 &&
+ if (mouseX >= subRect.rect.x1 && mouseX <= subRect.rect.x2 &&
mouseY >= subRect.rect.y1 && mouseY <= subRect.rect.y2) {
return _messageLists[subRect.messageListItemIndex];
}
diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h
index 6a84a69ecd..40236d9d22 100644
--- a/engines/neverhood/resource.h
+++ b/engines/neverhood/resource.h
@@ -168,7 +168,7 @@ protected:
struct DRDirectoryItem {
uint32 nameHash;
- uint16 offset;
+ uint16 offset;
uint16 type;
};
@@ -195,7 +195,7 @@ protected:
Common::Array<MessageList*> _messageLists;
Common::Array<DRRect> _drRects;
Common::Array<DRSubRectList*> _drSubRectLists;
- DataResource::DRDirectoryItem *findDRDirectoryItem(uint32 nameHash, uint16 type);
+ DataResource::DRDirectoryItem *findDRDirectoryItem(uint32 nameHash, uint16 type);
};
uint32 calcHash(const char *value);
diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp
index d5e7786c17..37089a5bd6 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -49,7 +49,7 @@ void ResourceMan::addArchive(const Common::String &filename) {
if (archiveEntry->timeStamp > entry->archiveEntry->timeStamp) {
entry->archive = archive;
entry->archiveEntry = archiveEntry;
- }
+ }
} else {
ResourceFileEntry newEntry;
newEntry.resourceHandle = -1;
diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp
index ae93a0cea4..01988769e6 100644
--- a/engines/neverhood/saveload.cpp
+++ b/engines/neverhood/saveload.cpp
@@ -78,7 +78,7 @@ bool NeverhoodEngine::savegame(const char *filename, const char *description) {
byte descriptionLen = strlen(description);
out->writeByte(descriptionLen);
out->write(description, descriptionLen);
-
+
Graphics::saveThumbnail(*out);
// Not used yet, reserved for future usage
@@ -96,7 +96,7 @@ bool NeverhoodEngine::savegame(const char *filename, const char *description) {
_gameVars->setGlobalVar(V_CURRENT_SCENE_WHICH, _gameState.which);
_gameVars->saveState(out);
-
+
out->finalize();
delete out;
return true;
@@ -112,17 +112,17 @@ bool NeverhoodEngine::loadgame(const char *filename) {
SaveHeader header;
kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
-
+
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
delete in;
return false;
}
-
+
g_engine->setTotalPlayTime(header.playTime * 1000);
_gameVars->loadState(in);
-
+
_gameState.sceneNum = _gameVars->getGlobalVar(V_CURRENT_SCENE);
_gameState.which = _gameVars->getGlobalVar(V_CURRENT_SCENE_WHICH);
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 80a2b69169..c8d7490753 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -28,7 +28,7 @@ namespace Neverhood {
Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
: Entity(vm, 0), _parentModule(parentModule), _dataResource(vm), _hitRects(NULL),
_mouseCursorWasVisible(true) {
-
+
_isKlaymenBusy = false;
_doConvertMessages = false;
_messageList = NULL;
@@ -50,10 +50,10 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
_smackerPlayer = NULL;
_isMessageListBusy = false;
_messageValue = -1;
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene::handleMessage);
-
+
_vm->_screen->clearRenderQueue();
}
@@ -71,7 +71,7 @@ Scene::~Scene() {
delete *iter;
// Don't delete surfaces since they always belong to an entity
-
+
// Purge the resources after each scene
_vm->_res->purgeResources();
@@ -84,7 +84,7 @@ void Scene::draw() {
} else {
for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++)
(*iter)->draw();
- }
+ }
}
void Scene::addEntity(Entity *entity) {
@@ -99,7 +99,7 @@ void Scene::addEntity(Entity *entity) {
if (insertIndex >= 0)
_entities.insert_at(insertIndex, entity);
else
- _entities.push_back(entity);
+ _entities.push_back(entity);
}
bool Scene::removeEntity(Entity *entity) {
@@ -108,7 +108,7 @@ bool Scene::removeEntity(Entity *entity) {
_entities.remove_at(index);
return true;
}
- return false;
+ return false;
}
void Scene::addSurface(BaseSurface *surface) {
@@ -124,7 +124,7 @@ void Scene::addSurface(BaseSurface *surface) {
if (insertIndex >= 0)
_surfaces.insert_at(insertIndex, surface);
else
- _surfaces.push_back(surface);
+ _surfaces.push_back(surface);
}
}
@@ -135,7 +135,7 @@ bool Scene::removeSurface(BaseSurface *surface) {
return true;
}
}
- return false;
+ return false;
}
void Scene::printSurfaces(Console *con) {
@@ -212,7 +212,7 @@ Sprite *Scene::insertStaticSprite(uint32 fileHash, int surfacePriority) {
}
void Scene::insertScreenMouse(uint32 fileHash, const NRect *mouseRect) {
- NRect rect(-1, -1, -1, -1);
+ NRect rect = NRect::make(-1, -1, -1, -1);
if (mouseRect)
rect = *mouseRect;
insertMouse(new Mouse(_vm, fileHash, rect));
@@ -246,12 +246,12 @@ void Scene::update() {
if (_mouseClicked) {
if (_klaymen) {
if (_canAcceptInput &&
- _klaymen->hasMessageHandler() &&
+ _klaymen->hasMessageHandler() &&
sendMessage(_klaymen, 0x1008, 0) != 0 &&
queryPositionSprite(_mouseClickPos.x, _mouseClickPos.y)) {
_mouseClicked = false;
} else if (_canAcceptInput &&
- _klaymen->hasMessageHandler() &&
+ _klaymen->hasMessageHandler() &&
sendMessage(_klaymen, 0x1008, 0) != 0) {
_mouseClicked = !queryPositionRectList(_mouseClickPos.x, _mouseClickPos.y);
}
@@ -262,7 +262,7 @@ void Scene::update() {
processMessageList();
- // Update all entities
+ // Update all entities
for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++)
(*iter)->handleUpdate();
@@ -283,7 +283,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
_mouseClickPos = param.asPoint();
break;
case 0x0006:
- sendMessage(_parentModule, 0x1009, param);
+ sendMessage(_parentModule, 0x1009, param);
break;
case 0x1006:
// Sent by Klaymen when its animation sequence has finished
@@ -332,7 +332,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
bool Scene::queryPositionSprite(int16 mouseX, int16 mouseY) {
for (uint i = 0; i < _collisionSprites.size(); i++) {
Sprite *sprite = _collisionSprites[i];
- if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) &&
+ if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) &&
sendPointMessage(sprite, 0x1011, _mouseClickPos) != 0) {
return true;
}
@@ -412,8 +412,8 @@ void Scene::processMessageList() {
_messageList2 = NULL;
_messageListStatus = 0;
}
-
- if (_messageList && _klaymen) {
+
+ if (_messageList && _klaymen) {
#if 0
debug("MessageList: %p, %d", (void*)_messageList, _messageList->size());
@@ -423,11 +423,11 @@ void Scene::processMessageList() {
}
debug("--------------------------------");
#endif
-
+
while (_messageList && _messageListIndex < _messageListCount && !_isKlaymenBusy) {
uint32 messageNum = (*_messageList)[_messageListIndex].messageNum;
uint32 messageParam = (*_messageList)[_messageListIndex].messageValue;
-
+
++_messageListIndex;
if (_messageListIndex == _messageListCount)
sendMessage(_klaymen, 0x1021, 0);
@@ -460,7 +460,7 @@ void Scene::processMessageList() {
if (_klaymen->hasMessageHandler() && sendMessage(_klaymen, messageNum, messageParam) != 0) {
_isKlaymenBusy = false;
}
- }
+ }
if (_messageListIndex == _messageListCount) {
_canAcceptInput = true;
_messageList = NULL;
@@ -469,7 +469,7 @@ void Scene::processMessageList() {
}
_isMessageListBusy = false;
-
+
}
void Scene::cancelMessageList() {
@@ -531,7 +531,7 @@ uint16 Scene::convertMessageNum(uint32 messageNum) {
case 0x42002200:
return 0x4004;
case 0x428D4894:
- return 0x101A;
+ return 0x101A;
}
return 0x1000;
}
@@ -546,7 +546,7 @@ HitRect *Scene::findHitRectAtPos(int16 x, int16 y) {
for (HitRectList::iterator it = _hitRects->begin(); it != _hitRects->end(); it++)
if ((*it).rect.contains(x, y))
return &(*it);
- return &kDefaultHitRect;
+ return &kDefaultHitRect;
}
void Scene::addCollisionSprite(Sprite *sprite) {
@@ -561,7 +561,7 @@ void Scene::addCollisionSprite(Sprite *sprite) {
if (insertIndex >= 0)
_collisionSprites.insert_at(insertIndex, sprite);
else
- _collisionSprites.push_back(sprite);
+ _collisionSprites.push_back(sprite);
}
void Scene::removeCollisionSprite(Sprite *sprite) {
@@ -583,7 +583,7 @@ void Scene::checkCollision(Sprite *sprite, uint16 flags, int messageNum, uint32
if ((sprite->getFlags() & flags) && collSprite->checkCollision(sprite->getCollisionBounds())) {
sprite->sendMessage(collSprite, messageNum, messageParam);
}
- }
+ }
}
void Scene::insertMouse(Mouse *mouseCursor) {
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 813ffba0bb..5e42e34418 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -76,89 +76,89 @@ public:
void checkCollision(Sprite *sprite, uint16 flags, int messageNum, uint32 messageParam);
// Some crazy templated functions to make the logic code smaller/simpler (imo!)
// insertKlaymen
- template<class T>
+ template<class T>
void insertKlaymen() {
_klaymen = (T*)addSprite(new T(_vm, this));
}
- template<class T, class Arg1>
+ template<class T, class Arg1>
void insertKlaymen(Arg1 arg1) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1));
}
- template<class T, class Arg1, class Arg2>
+ template<class T, class Arg1, class Arg2>
void insertKlaymen(Arg1 arg1, Arg2 arg2) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2));
}
- template<class T, class Arg1, class Arg2, class Arg3>
+ template<class T, class Arg1, class Arg2, class Arg3>
void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5, arg6));
}
// insertSprite
- template<class T>
+ template<class T>
T* insertSprite() {
return (T*)addSprite(new T(_vm));
}
- template<class T, class Arg1>
+ template<class T, class Arg1>
T* insertSprite(Arg1 arg1) {
return (T*)addSprite(new T(_vm, arg1));
}
- template<class T, class Arg1, class Arg2>
+ template<class T, class Arg1, class Arg2>
T* insertSprite(Arg1 arg1, Arg2 arg2) {
return (T*)addSprite(new T(_vm, arg1, arg2));
}
- template<class T, class Arg1, class Arg2, class Arg3>
+ template<class T, class Arg1, class Arg2, class Arg3>
T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
return (T*)addSprite(new T(_vm, arg1, arg2, arg3));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5));
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6));
}
// createSprite
- template<class T>
+ template<class T>
T* createSprite() {
return new T(_vm);
}
- template<class T, class Arg1>
+ template<class T, class Arg1>
T* createSprite(Arg1 arg1) {
return new T(_vm, arg1);
}
- template<class T, class Arg1, class Arg2>
+ template<class T, class Arg1, class Arg2>
T* createSprite(Arg1 arg1, Arg2 arg2) {
return new T(_vm, arg1, arg2);
}
- template<class T, class Arg1, class Arg2, class Arg3>
+ template<class T, class Arg1, class Arg2, class Arg3>
T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
return new T(_vm, arg1, arg2, arg3);
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
return new T(_vm, arg1, arg2, arg3, arg4);
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
return new T(_vm, arg1, arg2, arg3, arg4, arg5);
}
- template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
+ template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
return new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6);
}
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index 5a748cfab4..4c8dd9add0 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -28,16 +28,16 @@ namespace Neverhood {
Screen::Screen(NeverhoodEngine *vm)
: _vm(vm), _paletteData(NULL), _paletteChanged(false), _smackerDecoder(NULL),
_yOffset(0), _fullRefresh(false) {
-
+
_ticks = _vm->_system->getMillis();
-
+
_backScreen = new Graphics::Surface();
_backScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8());
-
+
_renderQueue = new RenderQueue();
_prevRenderQueue = new RenderQueue();
_microTiles = new MicroTileArray(640, 480);
-
+
}
Screen::~Screen() {
@@ -54,7 +54,7 @@ void Screen::update() {
if (_fullRefresh) {
// NOTE When playing a fullscreen/doubled Smacker video usually a full screen refresh is needed
- _vm->_system->copyRectToScreen((const byte*)_backScreen->pixels, _backScreen->pitch, 0, 0, 640, 480);
+ _vm->_system->copyRectToScreen((const byte*)_backScreen->getPixels(), _backScreen->pitch, 0, 0, 640, 480);
_fullRefresh = false;
return;
}
@@ -72,13 +72,13 @@ void Screen::update() {
}
}
}
-
+
for (RenderQueue::iterator jt = _prevRenderQueue->begin(); jt != _prevRenderQueue->end(); ++jt) {
RenderItem &prevRenderItem = (*jt);
if (prevRenderItem._refresh)
_microTiles->addRect(Common::Rect(prevRenderItem._destX, prevRenderItem._destY, prevRenderItem._destX + prevRenderItem._width, prevRenderItem._destY + prevRenderItem._height));
}
-
+
for (RenderQueue::iterator it = _renderQueue->begin(); it != _renderQueue->end(); ++it) {
RenderItem &renderItem = (*it);
if (renderItem._refresh)
@@ -93,7 +93,7 @@ void Screen::update() {
for (RectangleList::iterator ri = updateRects->begin(); ri != updateRects->end(); ++ri)
blitRenderItem(renderItem, *ri);
}
-
+
SWAP(_renderQueue, _prevRenderQueue);
_renderQueue->clear();
@@ -174,7 +174,7 @@ void Screen::updatePalette() {
}
void Screen::clear() {
- memset(_backScreen->pixels, 0, _backScreen->pitch * _backScreen->h);
+ memset(_backScreen->getPixels(), 0, _backScreen->pitch * _backScreen->h);
_fullRefresh = true;
clearRenderQueue();
}
@@ -202,12 +202,12 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect,
destX = drawRect.x;
ddRect.x1 = 0;
}
-
+
if (drawRect.y + drawRect.height >= clipRect.y2)
ddRect.y2 = clipRect.y2 - drawRect.y;
else
ddRect.y2 = drawRect.height;
-
+
if (drawRect.y < clipRect.y1) {
destY = clipRect.y1;
ddRect.y1 = clipRect.y1 - drawRect.y;
@@ -215,7 +215,7 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect,
destY = drawRect.y;
ddRect.y1 = 0;
}
-
+
queueBlit(surface, destX, destY, ddRect, transparent, version, shadowSurface);
}
@@ -224,12 +224,12 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND
int16 destX, destY;
NRect ddRect;
-
+
if (x + drawRect.width >= clipRect.x2)
ddRect.x2 = clipRect.x2 - drawRect.x - x;
else
ddRect.x2 = drawRect.x + drawRect.width;
-
+
if (x < clipRect.x1) {
destX = clipRect.x1;
ddRect.x1 = clipRect.x1 + drawRect.x - x;
@@ -242,7 +242,7 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND
ddRect.y2 = clipRect.y2 + drawRect.y - y;
else
ddRect.y2 = drawRect.y + drawRect.height;
-
+
if (y < clipRect.y1) {
destY = clipRect.y1;
ddRect.y1 = clipRect.y1 + drawRect.y - y;
@@ -250,14 +250,14 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND
destY = y;
ddRect.y1 = drawRect.y;
}
-
+
queueBlit(surface, destX, destY, ddRect, transparent, version);
}
void Screen::drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect) {
- const byte *source = (const byte*)surface->getBasePtr(0, 0);
+ const byte *source = (const byte*)surface->getPixels();
byte *dest = (byte*)_backScreen->getBasePtr(drawRect.x, drawRect.y);
for (int16 yc = 0; yc < surface->h; yc++) {
@@ -270,13 +270,13 @@ void Screen::drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &dra
dest += _backScreen->pitch;
dest += _backScreen->pitch;
}
-
+
_fullRefresh = true; // See Screen::update
}
void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent, byte version) {
-
+
int16 x, y;
bool xflag, yflag;
NDrawRect newDrawRect;
@@ -292,26 +292,26 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra
y = y % sysRect.height;
if (y < 0)
y += sysRect.height;
-
+
xflag = x <= 0;
yflag = y <= 0;
-
+
newDrawRect.x = x;
newDrawRect.width = sysRect.width - x;
if (drawRect.width < newDrawRect.width) {
xflag = true;
newDrawRect.width = drawRect.width;
}
-
+
newDrawRect.y = y;
newDrawRect.height = sysRect.height - y;
if (drawRect.height < newDrawRect.height) {
yflag = true;
newDrawRect.height = drawRect.height;
}
-
+
drawSurface3(surface, drawRect.x, drawRect.y, newDrawRect, clipRect, transparent, version);
-
+
if (!xflag) {
newDrawRect.x = 0;
newDrawRect.y = y;
@@ -321,7 +321,7 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra
newDrawRect.height = drawRect.height;
drawSurface3(surface, sysRect.width + drawRect.x - x, drawRect.y, newDrawRect, clipRect, transparent, version);
}
-
+
if (!yflag) {
newDrawRect.x = x;
newDrawRect.y = 0;
@@ -331,7 +331,7 @@ void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDra
newDrawRect.width = drawRect.width;
drawSurface3(surface, drawRect.x, sysRect.height + drawRect.y - y, newDrawRect, clipRect, transparent, version);
}
-
+
if (!xflag && !yflag) {
newDrawRect.x = 0;
newDrawRect.y = 0;
@@ -350,13 +350,13 @@ void Screen::drawSurfaceClipRects(const Graphics::Surface *surface, NDrawRect &d
void Screen::queueBlit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent, byte version,
const Graphics::Surface *shadowSurface) {
-
+
const int width = ddRect.x2 - ddRect.x1;
const int height = ddRect.y2 - ddRect.y1;
if (width <= 0 || height <= 0)
return;
-
+
RenderItem renderItem;
renderItem._surface = surface;
renderItem._shadowSurface = shadowSurface;
@@ -369,7 +369,7 @@ void Screen::queueBlit(const Graphics::Surface *surface, int16 destX, int16 dest
renderItem._transparent = transparent;
renderItem._version = version;
_renderQueue->push_back(renderItem);
-
+
}
void Screen::blitRenderItem(const RenderItem &renderItem, const Common::Rect &clipRect) {
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index 21d8851f48..187939faee 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -79,22 +79,22 @@ void SmackerDoubleSurface::draw() {
void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) {
if (!isVideoLoaded())
return;
-
+
if (frame >= getFrameCount())
error("Can't force Smacker seek to invalid frame %d", frame);
-
+
if (_header.audioInfo[0].hasAudio)
error("Can't force Smacker frame seek with audio");
if (!rewind())
error("Failed to rewind");
-
+
SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);
uint32 offset = 0;
for (uint32 i = 0; i < frame; i++) {
videoTrack->increaseCurFrame();
offset += _frameSizes[i] & ~3;
}
-
+
_fileStream->seek(offset, SEEK_CUR);
}
@@ -124,7 +124,7 @@ SmackerPlayer::~SmackerPlayer() {
void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
debug(0, "SmackerPlayer::open(%08X)", fileHash);
-
+
_fileHash = fileHash;
_keepLastFrame = keepLastFrame;
@@ -136,13 +136,13 @@ void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
_smackerDecoder = new NeverhoodSmackerDecoder();
_smackerDecoder->loadStream(_stream);
-
+
_palette = new Palette(_vm);
_palette->usePalette();
if (!_paused)
_smackerDecoder->start();
-
+
}
void SmackerPlayer::close() {
@@ -212,7 +212,7 @@ void SmackerPlayer::update() {
_videoDone = false;
}
}
-
+
}
void SmackerPlayer::updateFrame() {
@@ -240,7 +240,7 @@ void SmackerPlayer::updateFrame() {
if (_smackerDecoder->hasDirtyPalette())
updatePalette();
-
+
}
void SmackerPlayer::updatePalette() {
diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h
index f13b653757..dd7199dd6d 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -62,7 +62,7 @@ public:
void close();
void gotoFrame(int frameNumber);
uint32 getFrameCount();
- uint32 getFrameNumber();
+ uint32 getFrameNumber();
uint getStatus();
void setDrawPos(int16 x, int16 y);
void rewind();
diff --git a/engines/neverhood/smackerscene.cpp b/engines/neverhood/smackerscene.cpp
index 115aafe5be..d9d032a3b5 100644
--- a/engines/neverhood/smackerscene.cpp
+++ b/engines/neverhood/smackerscene.cpp
@@ -31,16 +31,16 @@ SmackerScene::SmackerScene(NeverhoodEngine *vm, Module *parentModule, bool doubl
debug(0, "SmackerScene::SmackerScene(%d, %d, %d)", doubleSurface, canSkip, canAbort);
// NOTE: Merged from SmackerScene::init, maybe split again if needed (incl. parameter flags)
-
+
if (getGlobalVar(V_SMACKER_CAN_ABORT)) {
_canSkip = true;
_canAbort = true;
}
-
+
if (!_doubleSurface)
_vm->_screen->clear();
- _fileHash[0] = 0;
+ _fileHash[0] = 0;
_fileHash[1] = 0;
SetUpdateHandler(&SmackerScene::update);
@@ -67,7 +67,7 @@ void SmackerScene::nextVideo() {
debug(0, "SmackerScene::nextVideo()");
_fileHashListIndex++;
-
+
if (_fileHashList && _fileHashList[_fileHashListIndex] != 0) {
uint32 smackerFileHash = _fileHashList[_fileHashListIndex];
ResourceHandle resourceHandle;
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index 46ec8007b0..c3bc3501b5 100644
--- a/engines/neverhood/sound.cpp
+++ b/engines/neverhood/sound.cpp
@@ -35,7 +35,7 @@ SoundResource::~SoundResource() {
unload();
}
-bool SoundResource::isPlaying() {
+bool SoundResource::isPlaying() {
AudioResourceManSoundItem *soundItem = getSoundItem();
return soundItem ? soundItem->isPlaying() : false;
}
@@ -94,7 +94,7 @@ MusicResource::MusicResource(NeverhoodEngine *vm)
bool MusicResource::isPlaying() {
AudioResourceManMusicItem *musicItem = getMusicItem();
- return musicItem && musicItem->isPlaying();
+ return musicItem && musicItem->isPlaying();
}
void MusicResource::load(uint32 fileHash) {
@@ -134,7 +134,7 @@ AudioResourceManMusicItem *MusicResource::getMusicItem() {
MusicItem::MusicItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 musicFileHash)
: _vm(vm), _musicResource(NULL) {
-
+
_groupNameHash = groupNameHash;
_fileHash = musicFileHash;
_play = false;
@@ -187,7 +187,7 @@ SoundItem::SoundItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 soundFile
_playOnceAfterRandomCountdown(false), _minCountdown(0), _maxCountdown(0),
_playOnceAfterCountdown(playOnceAfterCountdown), _initialCountdown(initialCountdown),
_playLooping(false), _currCountdown(currCountdown) {
-
+
_soundResource = new SoundResource(vm);
_soundResource->load(soundFileHash);
}
@@ -200,7 +200,7 @@ SoundItem::~SoundItem() {
void SoundItem::setSoundParams(bool playOnceAfterRandomCountdown, int16 minCountdown, int16 maxCountdown,
int16 firstMinCountdown, int16 firstMaxCountdown) {
-
+
_playOnceAfterCountdown = false;
_playLooping = false;
_playOnceAfterRandomCountdown = playOnceAfterRandomCountdown;
@@ -361,7 +361,7 @@ void SoundMan::setSoundVolume(uint32 soundFileHash, int volume) {
}
void SoundMan::update() {
-
+
for (uint i = 0; i < _soundItems.size(); ++i) {
SoundItem *soundItem = _soundItems[i];
if (soundItem)
@@ -456,7 +456,7 @@ void SoundMan::playSoundThree(uint32 groupNameHash, uint32 soundFileHash) {
SoundItem *soundItem = new SoundItem(_vm, groupNameHash, soundFileHash, false, 0, 0, false, _initialCountdown3, false, 0);
_soundIndex3 = addSoundItem(soundItem);
}
-
+
}
void SoundMan::setTwoSoundsPlayFlag(bool playOnceAfterCountdown) {
@@ -530,16 +530,16 @@ NeverhoodAudioStream::~NeverhoodAudioStream() {
int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesLeft = numSamples;
-
+
while (samplesLeft > 0 && !_endOfData) {
const int maxSamples = MIN<int>(kSampleBufferLength, samplesLeft);
const int bytesToRead = maxSamples * (_isCompressed ? 1 : 2);
int bytesRead = _stream->read(_buffer, bytesToRead);
int samplesRead = bytesRead / (_isCompressed ? 1 : 2);
-
+
samplesLeft -= samplesRead;
-
+
const byte *src = _buffer;
if (_isCompressed) {
while (samplesRead--) {
@@ -694,7 +694,7 @@ void AudioResourceManMusicItem::update() {
_start = false;
_isPlaying = true;
}
-
+
if (_vm->_mixer->isSoundHandleActive(_soundHandle)) {
if (_isFadingIn) {
_fadeVolume += _fadeVolumeStep;
@@ -787,11 +787,11 @@ int16 AudioResourceMan::loadMusic(uint32 fileHash) {
return i;
}
}
-
+
int16 musicIndex = _musicItems.size();
_musicItems.push_back(musicItem);
return musicIndex;
-
+
}
void AudioResourceMan::updateMusic() {
diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h
index aa5da284ea..0733346daa 100644
--- a/engines/neverhood/sound.h
+++ b/engines/neverhood/sound.h
@@ -70,7 +70,7 @@ public:
void setVolume(int16 volume);
protected:
NeverhoodEngine *_vm;
- int16 _musicIndex;
+ int16 _musicIndex;
AudioResourceManMusicItem *getMusicItem();
};
@@ -83,7 +83,7 @@ public:
void update();
uint32 getGroupNameHash() const { return _groupNameHash; }
uint32 getFileHash() const { return _fileHash; }
-protected:
+protected:
NeverhoodEngine *_vm;
uint32 _groupNameHash;
uint32 _fileHash;
@@ -110,7 +110,7 @@ public:
uint32 getGroupNameHash() const { return _groupNameHash; }
uint32 getFileHash() const { return _fileHash; }
int16 getCurrCountdown() const { return _currCountdown; }
-protected:
+protected:
NeverhoodEngine *_vm;
uint32 _groupNameHash;
uint32 _fileHash;
@@ -136,7 +136,7 @@ public:
void deleteMusic(uint32 musicFileHash);
void startMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep);
void stopMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep);
-
+
// Sound
void addSound(uint32 groupNameHash, uint32 soundFileHash);
void addSoundList(uint32 groupNameHash, const uint32 *soundFileHashList);
@@ -148,7 +148,7 @@ public:
void playSoundLooping(uint32 soundFileHash);
void stopSound(uint32 soundFileHash);
void setSoundVolume(uint32 soundFileHash, int volume);
-
+
// Misc
void update();
void deleteGroup(uint32 groupNameHash);
@@ -161,25 +161,25 @@ public:
protected:
NeverhoodEngine *_vm;
-
+
// TODO Find out what these special sounds are used for (door sounds?)
int _soundIndex1, _soundIndex2;
int16 _initialCountdown;
bool _playOnceAfterCountdown;
-
+
int _soundIndex3;
int16 _initialCountdown3;
bool _playOnceAfterCountdown3;
Common::Array<MusicItem*> _musicItems;
Common::Array<SoundItem*> _soundItems;
-
+
MusicItem *getMusicItemByHash(uint32 musicFileHash);
SoundItem *getSoundItemByHash(uint32 soundFileHash);
int16 addMusicItem(MusicItem *musicItem);
int16 addSoundItem(SoundItem *soundItem);
void deleteSoundByIndex(int index);
-
+
};
class NeverhoodAudioStream : public Audio::AudioStream {
@@ -209,7 +209,7 @@ private:
// TODO Rename these
class AudioResourceManSoundItem {
-public:
+public:
AudioResourceManSoundItem(NeverhoodEngine *vm, uint32 fileHash);
void loadSound();
void unloadSound();
@@ -218,7 +218,7 @@ public:
void playSound(bool looping);
void stopSound();
bool isPlaying();
-protected:
+protected:
NeverhoodEngine *_vm;
uint32 _fileHash;
ResourceHandle _resourceHandle;
@@ -243,7 +243,7 @@ public:
bool canRestart() const { return _canRestart; }
bool isTerminated() const { return _terminate; }
uint32 getFileHash() const { return _fileHash; }
-protected:
+protected:
NeverhoodEngine *_vm;
uint32 _fileHash;
bool _isPlaying;
@@ -263,7 +263,7 @@ class AudioResourceMan {
public:
AudioResourceMan(NeverhoodEngine *vm);
~AudioResourceMan();
-
+
void stopAllSounds();
int16 addSound(uint32 fileHash);
@@ -271,10 +271,10 @@ public:
int16 loadMusic(uint32 fileHash);
void updateMusic();
-
+
AudioResourceManSoundItem *getSoundItem(int16 index);
AudioResourceManMusicItem *getMusicItem(int16 index);
-
+
protected:
NeverhoodEngine *_vm;
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 50880089f9..3c158ff7e3 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -28,11 +28,11 @@ namespace Neverhood {
// Sprite
Sprite::Sprite(NeverhoodEngine *vm, int objectPriority)
- : Entity(vm, objectPriority), _x(0), _y(0), _spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL),
+ : Entity(vm, objectPriority), _x(0), _y(0), _spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL),
_dataResource(vm), _doDeltaX(false), _doDeltaY(false), _needRefresh(false), _flags(0), _surface(NULL) {
SetMessageHandler(&Sprite::handleMessage);
-
+
}
Sprite::~Sprite() {
@@ -71,7 +71,7 @@ bool Sprite::isPointInside(int16 x, int16 y) {
}
bool Sprite::checkCollision(NRect &rect) {
- return (_collisionBounds.x1 < rect.x2) && (rect.x1 < _collisionBounds.x2) && (_collisionBounds.y1 < rect.y2) && (rect.y1 < _collisionBounds.y2);
+ return (_collisionBounds.x1 < rect.x2) && (rect.x1 < _collisionBounds.x2) && (_collisionBounds.y1 < rect.y2) && (rect.y1 < _collisionBounds.y2);
}
uint32 Sprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -153,13 +153,13 @@ void StaticSprite::updatePosition() {
if (!_surface)
return;
-
+
if (_doDeltaX) {
_surface->getDrawRect().x = filterX(_x - _drawOffset.x - _drawOffset.width + 1);
} else {
_surface->getDrawRect().x = filterX(_x + _drawOffset.x);
}
-
+
if (_doDeltaY) {
_surface->getDrawRect().y = filterY(_y - _drawOffset.y - _drawOffset.height + 1);
} else {
@@ -261,7 +261,7 @@ void AnimatedSprite::updateAnim() {
}
if (_newAnimFileHash == 0 && _currFrameIndex != _currStickFrameIndex) {
if (_currFrameTicks != 0 && (--_currFrameTicks == 0) && _animResource.getFrameCount() != 0) {
-
+
if (_nextAnimFileHash != 0) {
if (_animResource.load(_nextAnimFileHash)) {
_currAnimFileHash = _nextAnimFileHash;
@@ -270,7 +270,7 @@ void AnimatedSprite::updateAnim() {
_currAnimFileHash = 0;
}
if (_replOldColor != _replNewColor) {
- _animResource.setRepl(_replOldColor, _replNewColor);
+ _animResource.setRepl(_replOldColor, _replNewColor);
}
_nextAnimFileHash = 0;
if (_animStatus != 0) {
@@ -278,17 +278,17 @@ void AnimatedSprite::updateAnim() {
_lastFrameIndex = _plLastFrameHash != 0 ? MAX<int16>(0, _animResource.getFrameIndex(_plLastFrameHash)) : _animResource.getFrameCount() - 1;
} else {
_currFrameIndex = _plFirstFrameIndex != -1 ? _plFirstFrameIndex : _animResource.getFrameCount() - 1;
- _lastFrameIndex = _plLastFrameIndex != -1 ? _plLastFrameIndex : _animResource.getFrameCount() - 1;
+ _lastFrameIndex = _plLastFrameIndex != -1 ? _plLastFrameIndex : _animResource.getFrameCount() - 1;
}
} else {
updateFrameIndex();
}
if (_newAnimFileHash == 0)
updateFrameInfo();
- }
+ }
}
}
-
+
if (_newAnimFileHash != 0) {
if (_animStatus == 2) {
_currStickFrameIndex = _currFrameIndex;
@@ -301,7 +301,7 @@ void AnimatedSprite::updateAnim() {
_currAnimFileHash = 0;
}
if (_replOldColor != _replNewColor) {
- _animResource.setRepl(_replOldColor, _replNewColor);
+ _animResource.setRepl(_replOldColor, _replNewColor);
}
_newAnimFileHash = 0;
_currFrameIndex = _plFirstFrameHash != 0 ? MAX<int16>(0, _animResource.getFrameIndex(_plFirstFrameHash)) : 0;
@@ -314,7 +314,7 @@ void AnimatedSprite::updateAnim() {
_currAnimFileHash = 0;
}
if (_replOldColor != _replNewColor) {
- _animResource.setRepl(_replOldColor, _replNewColor);
+ _animResource.setRepl(_replOldColor, _replNewColor);
}
_newAnimFileHash = 0;
_currFrameIndex = _plFirstFrameIndex != -1 ? _plFirstFrameIndex : _animResource.getFrameCount() - 1;
diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp
index 3f89c2236f..006992641a 100644
--- a/engines/neverhood/staticdata.cpp
+++ b/engines/neverhood/staticdata.cpp
@@ -33,13 +33,13 @@ StaticData::~StaticData() {
void StaticData::load(const char *filename) {
Common::File fd;
-
+
if (!fd.open(filename))
error("StaticData::load() Could not open %s", filename);
-
- fd.readUint32LE(); // magic
+
+ fd.readUint32LE(); // magic
fd.readUint32LE(); // version
-
+
// Load message lists
uint32 messageListsCount = fd.readUint32LE();
debug(3, "messageListsCount: %d", messageListsCount);
@@ -84,7 +84,7 @@ void StaticData::load(const char *filename) {
}
_rectLists[id] = rectList;
}
-
+
// Load hit rects
uint32 hitRectListsCount = fd.readUint32LE();
debug(3, "hitRectListsCount: %d", hitRectListsCount);
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index 3135c3e8c5..f648f4b9a1 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -225,7 +225,7 @@ void DosDisk_br::loadBitmap(Common::SeekableReadStream &stream, Graphics::Surfac
}
surf.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- stream.read(surf.pixels, width * height);
+ stream.read(surf.getPixels(), width * height);
}
Frames* DosDisk_br::loadPointer(const char *name) {
@@ -449,7 +449,7 @@ void AmigaDisk_br::init() {
void AmigaDisk_br::adjustForPalette(Graphics::Surface &surf, int transparentColor) {
uint size = surf.w * surf.h;
- byte *data = (byte *)surf.pixels;
+ byte *data = (byte *)surf.getPixels();
for (uint i = 0; i < size; i++, data++) {
if (transparentColor == -1 || transparentColor != *data)
*data += 16;
@@ -552,7 +552,7 @@ MaskBuffer *AmigaDisk_br::loadMask(const char *name, uint32 w, uint32 h) {
MaskBuffer *buffer = new MaskBuffer;
// surface width was shrunk to 1/4th of the bitmap width due to the pixel packing
buffer->create(decoder.getSurface()->w * 4, decoder.getSurface()->h);
- memcpy(buffer->data, decoder.getSurface()->pixels, buffer->size);
+ memcpy(buffer->data, decoder.getSurface()->getPixels(), buffer->size);
buffer->bigEndian = true;
finalpass(buffer->data, buffer->size);
return buffer;
@@ -612,7 +612,7 @@ GfxObj* AmigaDisk_br::loadStatic(const char* name) {
stream->read(shadow, shadowSize);
for (int32 i = 0; i < surf->h; ++i) {
byte *src = shadow + shadowWidth * i;
- byte *dst = (byte *)surf->pixels + surf->pitch * i;
+ byte *dst = (byte *)surf->getPixels() + surf->pitch * i;
for (int32 j = 0; j < surf->w; ++j, ++dst) {
byte bit = src[j/8] & (1 << (7 - (j & 7)));
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 4c4893ec61..ae28e864a9 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -482,7 +482,7 @@ void DosDisk_ns::loadBackground(BackgroundInfo& info, const char *filename) {
// read bitmap, mask and path data and extract them into the 3 buffers
info.bg.create(info.width, info.height, Graphics::PixelFormat::createFormatCLUT8());
createMaskAndPathBuffers(info);
- unpackBackground(stream, (byte *)info.bg.pixels, info._mask->data, info._path->data);
+ unpackBackground(stream, (byte *)info.bg.getPixels(), info._mask->data, info._path->data);
delete stream;
}
@@ -976,7 +976,7 @@ void AmigaDisk_ns::loadMask_internal(BackgroundInfo& info, const char *name) {
info._mask = new MaskBuffer;
// surface width was shrunk to 1/4th of the bitmap width due to the pixel packing
info._mask->create(decoder.getSurface()->w * 4, decoder.getSurface()->h);
- memcpy(info._mask->data, decoder.getSurface()->pixels, info._mask->size);
+ memcpy(info._mask->data, decoder.getSurface()->getPixels(), info._mask->size);
info._mask->bigEndian = true;
}
@@ -998,7 +998,7 @@ void AmigaDisk_ns::loadPath_internal(BackgroundInfo& info, const char *name) {
info._path = new PathBuffer;
// surface width was shrunk to 1/8th of the bitmap width due to the pixel packing
info._path->create(decoder.getSurface()->w * 8, decoder.getSurface()->h);
- memcpy(info._path->data, decoder.getSurface()->pixels, info._path->size);
+ memcpy(info._path->data, decoder.getSurface()->getPixels(), info._path->size);
info._path->bigEndian = true;
}
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 3ea4332e50..816f220b1f 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -126,9 +126,7 @@ DECLARE_INSTRUCTION_OPCODE(put) {
inst->_a->getFrameRect(r);
Graphics::Surface v18;
- v18.w = r.width();
- v18.h = r.height();
- v18.pixels = inst->_a->getFrameData();
+ v18.init(r.width(), r.height(), r.width(), inst->_a->getFrameData(), Graphics::PixelFormat::createFormatCLUT8());
int16 x = inst->_opA.getValue();
int16 y = inst->_opB.getValue();
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index b8a8ceb61f..3f36d56420 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -332,7 +332,7 @@ void Gfx::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int
void Gfx::clearScreen() {
if (_doubleBuffering) {
- if (_backBuffer.pixels) {
+ if (_backBuffer.getPixels()) {
Common::Rect r(_backBuffer.w, _backBuffer.h);
_backBuffer.fillRect(r, 0);
}
@@ -419,13 +419,13 @@ void Gfx::updateScreen() {
// is needed
_overlayMode = false;
- bool skipBackground = (_backgroundInfo->bg.pixels == 0); // don't render frame if background is missing
+ bool skipBackground = (_backgroundInfo->bg.getPixels() == 0); // don't render frame if background is missing
if (!skipBackground) {
// background may not cover the whole screen, so adjust bulk update size
uint w = _backgroundInfo->width;
uint h = _backgroundInfo->height;
- byte *backgroundData = (byte *)_backgroundInfo->bg.getBasePtr(0, 0);
+ byte *backgroundData = (byte *)_backgroundInfo->bg.getPixels();
uint16 backgroundPitch = _backgroundInfo->bg.pitch;
copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo->_x, _backgroundInfo->_y, w, h);
}
@@ -450,7 +450,7 @@ void Gfx::applyHalfbriteEffect_NS(Graphics::Surface &surf) {
return;
}
- byte *buf = (byte *)surf.pixels;
+ byte *buf = (byte *)surf.getPixels();
for (int i = 0; i < surf.w*surf.h; i++) {
*buf++ |= 0x20;
}
@@ -493,7 +493,7 @@ void Gfx::patchBackground(Graphics::Surface &surf, int16 x, int16 y, bool mask)
r.moveTo(x, y);
uint16 z = (mask) ? _backgroundInfo->getMaskLayer(y) : LAYER_FOREGROUND;
- blt(r, (byte *)surf.pixels, &_backgroundInfo->bg, z, 100, 0);
+ blt(r, (byte *)surf.getPixels(), &_backgroundInfo->bg, z, 100, 0);
}
void Gfx::fillBackground(const Common::Rect& r, byte color) {
@@ -536,12 +536,12 @@ GfxObj *Gfx::renderFloatingLabel(Font *font, char *text) {
setupLabelSurface(*cnv, w, h);
font->setColor((_gameType == GType_BRA) ? 0 : 7);
- font->drawString((byte *)cnv->pixels + 1, cnv->w, text);
- font->drawString((byte *)cnv->pixels + 1 + cnv->w * 2, cnv->w, text);
- font->drawString((byte *)cnv->pixels + cnv->w, cnv->w, text);
- font->drawString((byte *)cnv->pixels + 2 + cnv->w, cnv->w, text);
+ font->drawString((byte *)cnv->getBasePtr(1, 0), cnv->w, text);
+ font->drawString((byte *)cnv->getBasePtr(1, 2), cnv->w, text);
+ font->drawString((byte *)cnv->getBasePtr(0, 1), cnv->w, text);
+ font->drawString((byte *)cnv->getBasePtr(2, 1), cnv->w, text);
font->setColor((_gameType == GType_BRA) ? 11 : 1);
- font->drawString((byte *)cnv->pixels + 1 + cnv->w, cnv->w, text);
+ font->drawString((byte *)cnv->getBasePtr(1, 1), cnv->w, text);
} else {
w = font->getStringWidth(text);
h = font->height();
@@ -704,7 +704,7 @@ void Gfx::unregisterLabel(GfxObj *label) {
void Gfx::copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surface &dst) {
byte *s = (byte *)src.getBasePtr(r.left, r.top);
- byte *d = (byte *)dst.getBasePtr(0, 0);
+ byte *d = (byte *)dst.getPixels();
for (uint16 i = 0; i < r.height(); i++) {
memcpy(d, s, r.width());
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index bf7cdc439d..a445ce0138 100644
--- a/engines/parallaction/input.cpp
+++ b/engines/parallaction/input.cpp
@@ -499,7 +499,7 @@ void Input::initCursors() {
// TODO: scale mouse cursor (see staticres.cpp)
Graphics::Surface *surf2 = new Graphics::Surface;
surf2->create(32, 16, Graphics::PixelFormat::createFormatCLUT8());
- memcpy(surf2->pixels, _resMouseArrow_BR_Amiga, 32*16);
+ memcpy(surf2->getPixels(), _resMouseArrow_BR_Amiga, 32*16);
_mouseArrow = new SurfaceToFrames(surf2);
}
break;
diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h
index a3b7bf953f..d5cf8badf0 100644
--- a/engines/parallaction/inventory.h
+++ b/engines/parallaction/inventory.h
@@ -108,7 +108,7 @@ public:
void highlightItem(ItemPosition pos, byte color);
void drawItem(ItemName name, byte *buffer, uint pitch);
- byte* getData() const { return (byte *)_surf.pixels; }
+ byte *getData() { return (byte *)_surf.getPixels(); }
void getRect(Common::Rect &r) const;
int16 getNumLines() const;
diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp
index 897d31d7bd..ad0d2c2d7d 100644
--- a/engines/pegasus/cursor.cpp
+++ b/engines/pegasus/cursor.cpp
@@ -85,9 +85,9 @@ void Cursor::setCurrentFrameIndex(int32 index) {
if (_info[index].surface->format.bytesPerPixel == 1) {
CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount);
- CursorMan.replaceCursor(_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0);
+ CursorMan.replaceCursor(_info[index].surface->getPixels(), _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0);
} else {
- CursorMan.replaceCursor(_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false, &_info[index].surface->format);
+ CursorMan.replaceCursor(_info[index].surface->getPixels(), _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false, &_info[index].surface->format);
}
((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty();
@@ -203,7 +203,7 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) {
// PixMap data
if (pixMap.pixelSize == 8) {
cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
- cicnStream->read(cursorInfo.surface->pixels, pixMap.rowBytes * pixMap.bounds.height());
+ cicnStream->read(cursorInfo.surface->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
// While this looks sensible, it actually doesn't work for some cursors
// (ie. the 'can grab' hand)
diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp
index 8dbd678809..5475108abd 100644
--- a/engines/pegasus/graphics.cpp
+++ b/engines/pegasus/graphics.cpp
@@ -318,7 +318,7 @@ void GraphicsManager::shakeTheWorld(TimeValue duration, TimeScale scale) {
}
if (lastOffset.x != 0 || lastOffset.y != 0) {
- g_system->copyRectToScreen((byte *)oldScreen.pixels, oldScreen.pitch, 0, 0, 640, 480);
+ g_system->copyRectToScreen((byte *)oldScreen.getPixels(), oldScreen.pitch, 0, 0, 640, 480);
g_system->updateScreen();
}
diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
index 9a378a6728..0b3e1ee040 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
@@ -200,7 +200,7 @@ void Caldoria::start() {
const Graphics::Surface *frame = pullbackMovie->decodeNextFrame();
assert(frame);
assert(frame->format == g_system->getScreenFormat());
- g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, 64, 112, frame->w, frame->h);
+ g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 64, 112, frame->w, frame->h);
_vm->_gfx->doFadeInSync(kTwoSeconds * kFifteenTicksPerSecond, kFifteenTicksPerSecond);
bool saveAllowed = _vm->swapSaveAllowed(false);
@@ -216,7 +216,7 @@ void Caldoria::start() {
frame = pullbackMovie->decodeNextFrame();
if (frame) {
- g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, 64, 112, frame->w, frame->h);
+ g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 64, 112, frame->w, frame->h);
g_system->updateScreen();
}
}
diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp
index 38366c4ba2..3116bd7978 100644
--- a/engines/pegasus/neighborhood/neighborhood.cpp
+++ b/engines/pegasus/neighborhood/neighborhood.cpp
@@ -1364,7 +1364,7 @@ void Neighborhood::setUpAIRules() {
if (g_AIArea) {
g_AIArea->forceAIUnlocked();
- if (!_vm->isDemo() && (getObjectID() == kPrehistoricID || getObjectID() == kNoradAlphaID ||
+ if (!_vm->isOldDemo() && (getObjectID() == kPrehistoricID || getObjectID() == kNoradAlphaID ||
getObjectID() == kNoradDeltaID || getObjectID() == kMarsID || getObjectID() == kWSCID)) {
AIEnergyMonitorCondition *condition50 = new AIEnergyMonitorCondition(kWorriedEnergy);
diff --git a/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp b/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
index 169f75f7d2..3491f161c7 100644
--- a/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
+++ b/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
@@ -201,7 +201,7 @@ void NoradAlphaFillingStation::showIntakeInProgress(uint16 numSeconds) {
if (item->getObjectID() == kGasCanister) {
GameState.setNoradGassed(true);
- ((NoradAlpha *)getOwner())->loadAmbientLoops();
+ ((NoradAlpha *)getOwner())->checkAirMask();
getOwner()->restoreStriding(kNorad03, kEast, kAltNoradAlphaNormal);
}
} else {
diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
index e4a5e26473..6a24113465 100644
--- a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
+++ b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
@@ -576,7 +576,7 @@ void NoradAlpha::takeItemFromRoom(Item *item) {
if (_fillingStationItem == item) {
_fillingStationItem = 0;
GameState.setNoradGassed(false);
- loadAmbientLoops();
+ checkAirMask();
((NoradAlphaFillingStation *)_currentInteraction)->newFillingItem(0);
forceStridingStop(kNorad03, kEast, kAltNoradAlphaNormal);
}
diff --git a/engines/pegasus/neighborhood/norad/norad.cpp b/engines/pegasus/neighborhood/norad/norad.cpp
index 578f062dea..53b3ff9add 100644
--- a/engines/pegasus/neighborhood/norad/norad.cpp
+++ b/engines/pegasus/neighborhood/norad/norad.cpp
@@ -241,7 +241,9 @@ void Norad::setUpAirMask() {
}
void Norad::checkAirMask() {
- if (g_airMask && g_airMask->isAirFilterOn()) {
+ // WORKAROUND: The original game forgot to handle the case where the canister would
+ // be removed, leading to the timer remaining active.
+ if (!GameState.getNoradGassed() || (g_airMask && g_airMask->isAirFilterOn())) {
_airMaskTimer.stop();
} else if (GameState.getNoradGassed() && !_airMaskTimer.isRunning()) {
_airMaskTimer.setTime(0);
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index 463e81e52e..3bd29ce8dd 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -313,7 +313,7 @@ void PegasusEngine::runIntro() {
const Graphics::Surface *frame = video->decodeNextFrame();
if (frame) {
- _system->copyRectToScreen((byte *)frame->pixels, frame->pitch, 0, 0, frame->w, frame->h);
+ _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
_system->updateScreen();
}
}
@@ -1367,7 +1367,7 @@ bool PegasusEngine::playMovieScaled(Video::VideoDecoder *video, uint16 x, uint16
if (frame->w <= 320 && frame->h <= 240) {
drawScaledFrame(frame, x, y);
} else {
- _system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
_system->updateScreen();
}
}
@@ -2270,11 +2270,11 @@ void PegasusEngine::drawScaledFrame(const Graphics::Surface *frame, uint16 x, ui
scaledFrame.create(frame->w * 2, frame->h * 2, frame->format);
if (frame->format.bytesPerPixel == 2)
- scaleFrame<uint16>((uint16 *)frame->pixels, (uint16 *)scaledFrame.pixels, frame->w, frame->h, frame->pitch);
+ scaleFrame<uint16>((const uint16 *)frame->getPixels(), (uint16 *)scaledFrame.getPixels(), frame->w, frame->h, frame->pitch);
else
- scaleFrame<uint32>((uint32 *)frame->pixels, (uint32 *)scaledFrame.pixels, frame->w, frame->h, frame->pitch);
+ scaleFrame<uint32>((const uint32 *)frame->getPixels(), (uint32 *)scaledFrame.getPixels(), frame->w, frame->h, frame->pitch);
- _system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+ _system->copyRectToScreen((byte *)scaledFrame.getPixels(), scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
_system->updateScreen();
scaledFrame.free();
}
diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp
index 50cc9bc6d8..8463d866e8 100644
--- a/engines/pegasus/timers.cpp
+++ b/engines/pegasus/timers.cpp
@@ -115,7 +115,7 @@ void TimeBase::stop() {
void TimeBase::pause() {
if (isRunning() && !_paused) {
_pausedRate = getRate();
- stop();
+ _rate = 0;
_paused = true;
_pauseStart = g_system->getMillis();
}
@@ -123,7 +123,7 @@ void TimeBase::pause() {
void TimeBase::resume() {
if (_paused) {
- setRate(_pausedRate);
+ _rate = _pausedRate;
_paused = false;
if (isRunning())
diff --git a/engines/pegasus/transition.cpp b/engines/pegasus/transition.cpp
index 1ae212df85..b736b115ee 100644
--- a/engines/pegasus/transition.cpp
+++ b/engines/pegasus/transition.cpp
@@ -70,7 +70,7 @@ void ScreenFader::setFaderValue(const int32 value) {
if (value != getFaderValue()) {
Fader::setFaderValue(value);
- if (_screen->pixels) {
+ if (_screen->getPixels()) {
// The original game does a gamma fade here using the Mac API. In order to do
// that, it would require an immense amount of CPU processing. This does a
// linear fade instead, which looks fairly well, IMO.
diff --git a/engines/plugins_table.h b/engines/plugins_table.h
index 5c2309e919..ee7713bb76 100644
--- a/engines/plugins_table.h
+++ b/engines/plugins_table.h
@@ -47,6 +47,9 @@ LINK_PLUGIN(HUGO)
#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
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index fd602ff4fb..df8283b4c2 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -185,7 +185,7 @@ int Anim::playCutaway(int cut, bool fade) {
event.time = (40 / 3) * 1000 / _cutawayList[cut].frameRate;
if (fade)
- eventColumns = _vm->_events->chain(eventColumns, event);
+ _vm->_events->chain(eventColumns, event);
else
_vm->_events->queue(event);
}
@@ -501,7 +501,7 @@ void Anim::play(uint16 animId, int vectorTime, bool playing) {
}
anim = getAnimation(animId);
- displayBuffer = (byte *)_vm->_render->getBackGroundSurface()->pixels;
+ displayBuffer = (byte *)_vm->_render->getBackGroundSurface()->getPixels();
if (playing) {
anim->state = ANIM_PLAYING;
diff --git a/engines/saga/gfx.h b/engines/saga/gfx.h
index c677b76324..c68160e907 100644
--- a/engines/saga/gfx.h
+++ b/engines/saga/gfx.h
@@ -201,7 +201,7 @@ public:
// Whenever it gets called, the corresponding caller must take care
// to add the corresponding dirty rectangle itself
byte *getBackBufferPixels() {
- return (byte *)_backBuffer.pixels;
+ return (byte *)_backBuffer.getPixels();
}
uint16 getBackBufferWidth() {
diff --git a/engines/saga/introproc_ihnm.cpp b/engines/saga/introproc_ihnm.cpp
index 6015e6757a..7922d56425 100644
--- a/engines/saga/introproc_ihnm.cpp
+++ b/engines/saga/introproc_ihnm.cpp
@@ -212,7 +212,7 @@ bool Scene::playTitle(int title, int time, int mode) {
break;
case 2: // display background
- _vm->_system->copyRectToScreen(backBufferSurface->pixels, backBufferSurface->w, 0, 0,
+ _vm->_system->copyRectToScreen(backBufferSurface->getPixels(), backBufferSurface->w, 0, 0,
backBufferSurface->w, backBufferSurface->h);
phase++;
startTime = curTime;
@@ -247,7 +247,7 @@ bool Scene::playTitle(int title, int time, int mode) {
frameTime = curTime;
- _vm->_system->copyRectToScreen(backBufferSurface->pixels, backBufferSurface->w, 0, 0,
+ _vm->_system->copyRectToScreen(backBufferSurface->getPixels(), backBufferSurface->w, 0, 0,
backBufferSurface->w, backBufferSurface->h);
}
@@ -273,8 +273,8 @@ bool Scene::playTitle(int title, int time, int mode) {
_vm->_anim->endVideo();
- memset((byte *)backBufferSurface->pixels, 0, backBufferSurface->w * backBufferSurface->h);
- _vm->_system->copyRectToScreen(backBufferSurface->pixels, backBufferSurface->w, 0, 0,
+ memset((byte *)backBufferSurface->getPixels(), 0, backBufferSurface->w * backBufferSurface->h);
+ _vm->_system->copyRectToScreen(backBufferSurface->getPixels(), backBufferSurface->w, 0, 0,
backBufferSurface->w, backBufferSurface->h);
return interrupted;
diff --git a/engines/saga/introproc_saga2.cpp b/engines/saga/introproc_saga2.cpp
index 260eca98e6..e61dfbf161 100644
--- a/engines/saga/introproc_saga2.cpp
+++ b/engines/saga/introproc_saga2.cpp
@@ -108,7 +108,7 @@ void Scene::playMovie(const char *filename) {
if (smkDecoder->needsUpdate()) {
const Graphics::Surface *frame = smkDecoder->decodeNextFrame();
if (frame) {
- _vm->_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
if (smkDecoder->hasDirtyPalette())
_vm->_system->getPaletteManager()->setPalette(smkDecoder->getPalette(), 0, 256);
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 812d967b9f..3ac89bc2c2 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -364,7 +364,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
// Load MIDI/XMI resource data
if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
- // Load the external music file for Mac IHNM
+ // Load the external music file for Mac IHNM
_player->playQuickTime(Common::String::format("Music/Music%02x", resourceId), flags & MUSIC_LOOP);
} else {
if (_currentMusicBuffer == &_musicBuffer[1]) {
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index 75876b1c90..eff31cf98b 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -468,7 +468,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
pal = decoder.getPalette();
rect.setWidth(decoder.getSurface()->w);
rect.setHeight(decoder.getSurface()->h);
- _vm->_gfx->drawRegion(rect, (const byte *)decoder.getSurface()->pixels);
+ _vm->_gfx->drawRegion(rect, (const byte *)decoder.getSurface()->getPixels());
for (int j = 0; j < PAL_ENTRIES; j++) {
cPal[j].red = *pal++;
cPal[j].green = *pal++;
@@ -1120,9 +1120,9 @@ void Scene::draw() {
_vm->_render->getBackGroundSurface()->getRect(rect);
rect.bottom = (_sceneClip.bottom < rect.bottom) ? getHeight() : rect.bottom;
if (_vm->_render->isFullRefresh())
- _vm->_gfx->drawRegion(rect, (const byte *)_vm->_render->getBackGroundSurface()->pixels);
+ _vm->_gfx->drawRegion(rect, (const byte *)_vm->_render->getBackGroundSurface()->getPixels());
else
- _vm->_gfx->drawBgRegion(rect, (const byte *)_vm->_render->getBackGroundSurface()->pixels);
+ _vm->_gfx->drawBgRegion(rect, (const byte *)_vm->_render->getBackGroundSurface()->getPixels());
}
}
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 09c348f273..883a4d965b 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -105,9 +105,8 @@ static const PlainGameDescriptor s_sciGameTitles[] = {
// === SCI2.1 games ========================================================
{"chest", "Inside the Chest"}, // aka Behind the Developer's Shield
{"gk2", "The Beast Within: A Gabriel Knight Mystery"},
- // TODO: Inside The Chest/Behind the Developer's Shield
{"kq7", "King's Quest VII: The Princeless Bride"},
- // TODO: King's Questions
+ {"kquestions", "King's Questions"},
{"lsl6hires", "Leisure Suit Larry 6: Shape Up or Slip Out!"},
{"mothergoosehires","Mixed-Up Mother Goose Deluxe"},
{"phantasmagoria", "Phantasmagoria"},
@@ -161,6 +160,7 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = {
{ "kq5", GID_KQ5 },
{ "kq6", GID_KQ6 },
{ "kq7", GID_KQ7 },
+ { "kquestions", GID_KQUESTIONS },
{ "laurabow", GID_LAURABOW },
{ "laurabow2", GID_LAURABOW2 },
{ "lighthouse", GID_LIGHTHOUSE },
@@ -242,6 +242,7 @@ static const OldNewIdTableEntry s_oldNewTable[] = {
// kq5 is the same
// kq6 is the same
{ "kq7cd", "kq7", SCI_VERSION_NONE },
+ { "quizgame-demo", "kquestions", SCI_VERSION_NONE },
{ "mm1", "laurabow", SCI_VERSION_NONE },
{ "cb1", "laurabow", SCI_VERSION_NONE },
{ "lb2", "laurabow2", SCI_VERSION_NONE },
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 66164a1937..92e77cead9 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -1054,6 +1054,23 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
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
+ {"jones", "CD", {
+ {"resource.map", 0, "4344ff3f796707843b992adec2c87663", 4878},
+ {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652062},
+ AD_LISTEND},
+ 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
+ // General MIDI music tracks in the Windows version
+ {"jones", "CD", {
+ {"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) },
+
// King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.003.007"
// SCI interpreter version 0.001.010
@@ -1639,6 +1656,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
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) },
+ // King's Questions mini-game from the King's Quest Collection
+ // SCI interpreter version 2.000.000
+ {"kquestions", "", {
+ {"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) },
+
#endif // ENABLE_SCI32
// Laura Bow - English Amiga
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index 6005ac50be..c26c787fbd 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -467,9 +467,9 @@ bool GameFeatures::autoDetectSci21KernelType() {
// seen it happen in the RAMA demo, thus we can assume that the
// game is using a SCI2.1 table
- // HACK: The Inside the Chest Demo doesn't have sounds at all, but
- // it's using a SCI2 kernel
- if (g_sci->getGameId() == GID_CHEST) {
+ // HACK: The Inside the Chest Demo and King's Questions minigame
+ // don't have sounds at all, but they're using a SCI2 kernel
+ if (g_sci->getGameId() == GID_CHEST || g_sci->getGameId() == GID_KQUESTIONS) {
_sci21KernelType = SCI_VERSION_2;
return true;
}
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index 64793efa6c..3c223bebbe 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -1966,7 +1966,7 @@ static bool isVertexCovered(const Patch &p, unsigned int wi) {
// ---w1--1----p----w2--2----
// ^ \ (inside)
if (wi > p.indexw1 && wi <= p.indexw2)
- return true;
+ return true;
// v / (outside)
// ---w2--2----p----w1--1----
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 15a9f54996..d72b1d1772 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -551,7 +551,7 @@ reg_t kMessage(EngineState *s, int argc, reg_t *argv) {
// NOTE: To fix a corrupted jar object, type "send Glass_Jar message 52"
// in the debugger.
if (g_sci->getGameId() == GID_PEPPER && func == 0 && argc >= 6 && module == 894 &&
- tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 &&
+ tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 &&
!s->_msgState->getMessage(module, tuple, NULL_REG))
tuple.verb = 0;
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 9b0cb38f51..3964ccc1f8 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -103,10 +103,10 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) {
if (frame) {
if (scaleBuffer) {
// TODO: Probably should do aspect ratio correction in e.g. GK1 Windows
- g_sci->_gfxScreen->scale2x((byte *)frame->pixels, scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight(), bytesPerPixel);
+ g_sci->_gfxScreen->scale2x((const byte *)frame->getPixels(), scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight(), bytesPerPixel);
g_system->copyRectToScreen(scaleBuffer, pitch, x, y, width, height);
} else {
- g_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, width, height);
+ g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, width, height);
}
if (videoDecoder->hasDirtyPalette()) {
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 20c5c52178..d4dddb6faf 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -953,10 +953,10 @@ const uint16 qfg1vgaPatchDialogHeader[] = {
// When clicking on the crusher in room 331, Ego approaches him to talk to him,
// an action that is handled by moveToCrusher::changeState in script 331. The
-// scripts set Ego to move close to the crusher, but when Ego is running instead
+// scripts set Ego to move close to the crusher, but when Ego is sneaking instead
// of walking, the target coordinates specified by script 331 are never reached,
// as Ego is making larger steps, and never reaches the required spot. This is an
-// edge case that can occur when Ego is set to run. Normally, when clicking on
+// 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.
@@ -976,6 +976,25 @@ const uint16 qfg1vgaPatchMoveToCrusher[] = {
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)
+ PATCH_END
+};
+
// script, description, magic DWORD, adjust
const SciScriptSignature qfg1vgaSignatures[] = {
{ 215, "fight event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
@@ -983,6 +1002,7 @@ const SciScriptSignature qfg1vgaSignatures[] = {
{ 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 },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index 27015d9be4..5327dd1a2e 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -28,12 +28,12 @@
namespace Sci {
-reg_t reg_t::lookForWorkaround(const reg_t right) const {
+reg_t reg_t::lookForWorkaround(const reg_t right, const char *operation) const {
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, arithmeticWorkarounds, &originReply);
if (solution.type == WORKAROUND_NONE)
- error("Invalid arithmetic operation (params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
- PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
+ error("Invalid arithmetic operation (%s - params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
+ operation, PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
originReply.methodName.c_str(), g_sci->getEngineState()->currentRoomNumber(), originReply.scriptNr,
originReply.localCallOffset);
assert(solution.type == WORKAROUND_FAKE);
@@ -55,7 +55,7 @@ reg_t reg_t::operator+(const reg_t right) const {
case SEG_TYPE_DYNMEM:
return make_reg(getSegment(), getOffset() + right.toSint16());
default:
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
} else if (isNumber() && right.isPointer()) {
// Adding a pointer to a number, flip the order
@@ -64,7 +64,7 @@ reg_t reg_t::operator+(const reg_t right) const {
// Normal arithmetics
return make_reg(0, toSint16() + right.toSint16());
} else {
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
}
@@ -82,14 +82,14 @@ reg_t reg_t::operator*(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toSint16() * right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "multiplication");
}
reg_t reg_t::operator/(const reg_t right) const {
if (isNumber() && right.isNumber() && !right.isNull())
return make_reg(0, toSint16() / right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "division");
}
reg_t reg_t::operator%(const reg_t right) const {
@@ -109,21 +109,21 @@ reg_t reg_t::operator%(const reg_t right) const {
result += modulo;
return make_reg(0, result);
} else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "modulo");
}
reg_t reg_t::operator>>(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() >> right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift right");
}
reg_t reg_t::operator<<(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() << right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift left");
}
reg_t reg_t::operator+(int16 right) const {
@@ -140,7 +140,7 @@ uint16 reg_t::requireUint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toUint16();
+ return lookForWorkaround(NULL_REG, "require unsigned number").toUint16();
}
int16 reg_t::requireSint16() const {
@@ -149,28 +149,28 @@ int16 reg_t::requireSint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toSint16();
+ return lookForWorkaround(NULL_REG, "require signed number").toSint16();
}
reg_t reg_t::operator&(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() & right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise AND");
}
reg_t reg_t::operator|(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() | right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise OR");
}
reg_t reg_t::operator^(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() ^ right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise XOR");
}
int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
@@ -184,7 +184,7 @@ int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
} else if (right.pointerComparisonWithInteger(*this)) {
return -1;
} else
- return lookForWorkaround(right).toSint16();
+ return lookForWorkaround(right, "comparison").toSint16();
}
bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index 9a7589e9a7..22bd8beaa1 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -156,7 +156,7 @@ private:
* - a negative number if *this < right
*/
int cmp(const reg_t right, bool treatAsUnsigned) const;
- reg_t lookForWorkaround(const reg_t right) const;
+ reg_t lookForWorkaround(const reg_t right, const char *operation) const;
bool pointerComparisonWithInteger(const reg_t right) const;
};
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 6f0b34b457..154ac8f8b4 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -37,6 +37,7 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = {
{ 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_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
@@ -50,6 +51,7 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = {
// 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_CNICK_KQ, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering the control menu, like in hoyle 3
@@ -74,9 +76,11 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ 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_HOYLE4, 700, 718, 0, "compete_tree", "doit", -1, 75, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge - bug #3292332
- { GID_HOYLE4, 700, 716, 0, "other1_tree", "doit", -1, 46, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
- { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
+ { 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, -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, 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
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index bf1ce6da64..76510fa53b 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -532,7 +532,7 @@ void GfxFrameout::showVideo() {
if (videoDecoder->needsUpdate()) {
const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
if (frame) {
- g_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
if (videoDecoder->hasDirtyPalette())
g_system->getPaletteManager()->setPalette(videoDecoder->getPalette(), 0, 256);
@@ -745,7 +745,7 @@ void GfxFrameout::kernelFrameout() {
// Process global scaling, if needed.
// TODO: Seems like SCI32 always processes global scaling for scaled objects
// TODO: We can only process symmetrical scaling for now (i.e. same value for scaleX/scaleY)
- if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) &&
+ if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) &&
!(itemEntry->scaleSignal & kScaleSignalDisableGlobalScaling32) &&
(itemEntry->scaleX == itemEntry->scaleY) &&
itemEntry->scaleX != 128)
@@ -779,6 +779,14 @@ void GfxFrameout::kernelFrameout() {
_coordAdjuster->fromDisplayToScript(nsRect.bottom, nsRect.right);
g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect);
}
+
+ // TODO: For some reason, the top left nsRect coordinates get
+ // swapped in the GK1 inventory screen, investigate why.
+ // HACK: Fix the coordinates by explicitly setting them here.
+ Common::Rect objNSRect = g_sci->_gfxCompare->getNSRect(itemEntry->object);
+ if (objNSRect.top == nsRect.left && objNSRect.left == nsRect.top && nsRect.top != 0 && nsRect.left != 0) {
+ g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect);
+ }
}
// Don't attempt to draw sprites that are outside the visible
diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp
index dfb50b0edb..4df80b289f 100644
--- a/engines/sci/graphics/maciconbar.cpp
+++ b/engines/sci/graphics/maciconbar.cpp
@@ -129,7 +129,7 @@ void GfxMacIconBar::drawIcon(uint16 iconIndex, bool selected) {
void GfxMacIconBar::drawEnabledImage(Graphics::Surface *surface, const Common::Rect &rect) {
if (surface)
- g_system->copyRectToScreen(surface->pixels, surface->pitch, rect.left, rect.top, rect.width(), rect.height());
+ g_system->copyRectToScreen(surface->getPixels(), surface->pitch, rect.left, rect.top, rect.width(), rect.height());
}
void GfxMacIconBar::drawDisabledImage(Graphics::Surface *surface, const Common::Rect &rect) {
@@ -153,7 +153,7 @@ void GfxMacIconBar::drawDisabledImage(Graphics::Surface *surface, const Common::
*((byte *)newSurf.getBasePtr(j, i)) = 0;
}
- g_system->copyRectToScreen(newSurf.pixels, newSurf.pitch, rect.left, rect.top, rect.width(), rect.height());
+ g_system->copyRectToScreen(newSurf.getPixels(), newSurf.pitch, rect.left, rect.top, rect.width(), rect.height());
newSurf.free();
}
@@ -224,7 +224,7 @@ Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected)
}
void GfxMacIconBar::remapColors(Graphics::Surface *surf, const byte *palette) {
- byte *pixels = (byte *)surf->pixels;
+ byte *pixels = (byte *)surf->getPixels();
// Remap to the screen palette
for (uint16 i = 0; i < surf->w * surf->h; i++) {
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index af372640da..91c72456a8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -236,7 +236,9 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
byte *ptr = NULL;
byte *headerPtr = inbuffer + headerPos;
byte *rlePtr = inbuffer + rlePos;
- int16 displaceX, displaceY;
+ // 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 clearColor;
bool compression = true;
@@ -251,8 +253,8 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
// Width/height here are always LE, even in Mac versions
width = READ_LE_UINT16(headerPtr + 0);
height = READ_LE_UINT16(headerPtr + 2);
- displaceX = (signed char)headerPtr[4];
- displaceY = (unsigned char)headerPtr[5];
+ //displaceX = (signed char)headerPtr[4];
+ //displaceY = (unsigned char)headerPtr[5];
if (_resourceType == SCI_PICTURE_TYPE_SCI11)
// SCI1.1 uses hardcoded clearcolor for pictures, even if cel header specifies otherwise
clearColor = _screen->getColorWhite();
@@ -262,16 +264,16 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
} else {
width = READ_SCI11ENDIAN_UINT16(headerPtr + 0);
height = READ_SCI11ENDIAN_UINT16(headerPtr + 2);
- displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
- displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
+ //displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
+ //displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
clearColor = headerPtr[8];
if (headerPtr[9] == 0)
compression = false;
}
#endif
- if (displaceX || displaceY)
- error("unsupported embedded cel-data in picture");
+ //if (displaceX || displaceY)
+ // error("unsupported embedded cel-data in picture");
// We will unpack cel-data into a temporary buffer and then plot it to screen
// That needs to be done cause a mirrored picture may be requested
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 74503c0c77..7b92bc89eb 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -170,14 +170,14 @@ void GfxScreen::copyToScreen() {
void GfxScreen::copyFromScreen(byte *buffer) {
// TODO this ignores the pitch
Graphics::Surface *screen = g_system->lockScreen();
- memcpy(buffer, screen->pixels, _displayPixels);
+ memcpy(buffer, screen->getPixels(), _displayPixels);
g_system->unlockScreen();
}
void GfxScreen::kernelSyncWithFramebuffer() {
// TODO this ignores the pitch
Graphics::Surface *screen = g_system->lockScreen();
- memcpy(_displayScreen, screen->pixels, _displayPixels);
+ memcpy(_displayScreen, screen->getPixels(), _displayPixels);
g_system->unlockScreen();
}
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 3b9844b326..0a75e115fd 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -138,6 +138,7 @@ enum SciGameId {
GID_KQ5,
GID_KQ6,
GID_KQ7,
+ GID_KQUESTIONS,
GID_LAURABOW,
GID_LAURABOW2,
GID_LIGHTHOUSE,
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 9546b1503f..9653d9ccff 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -57,6 +57,7 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) :
_signalToSet = 0;
_dataincAdd = false;
_dataincToAdd = 0;
+ _jumpToHoldTick = false;
_resetOnPause = false;
_pSnd = 0;
}
@@ -452,6 +453,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
debugC(4, kDebugLevelSound, "signal %04x", _signalToSet);
}
+ if (_jumpToHoldTick) {
+ _jumpToHoldTick = false;
+ jumpToTick(_loopTick, false, false);
+ }
info.start = _position._playPos;
info.delta = 0;
@@ -486,6 +491,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
// though, so ignoring these signals in SCI0 games will result
// in glitches (e.g. the intro of LB1 Amiga gets stuck - bug
// #3297883). Refer to MusicEntry::setSignal() in sound/music.cpp.
+ // FIXME: SSCI doesn't start playing at the very beginning
+ // of the stream, but at a fixed location a few commands later.
+ // That is probably why this signal isn't triggered
+ // immediately there.
if (_soundVersion <= SCI_VERSION_0_LATE ||
_position._playTick || info.delta) {
_signalSet = true;
@@ -531,10 +540,15 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
// Check if the hold ID marker is the same as the hold ID
// marker set for that song by cmdSetSoundHold.
// If it is, loop back, but don't stop notes when jumping.
+ // We need to wait for the delta of the current event before
+ // jumping, thus the jump will be performed on the next
+ // parseNextEvent() call, like with the signal set events.
+ // In LSL6, room 360, song 381, this ends up jumping forward
+ // one tick (the hold marker occurs at playtick 27, with
+ // _loopTick being 15 and the event itself having a delta of
+ // 13, total = 28) - bug #3614566.
if (info.basic.param2 == _pSnd->hold) {
- uint32 extraDelta = info.delta;
- jumpToTick(_loopTick, false, false);
- _nextEvent.delta += extraDelta;
+ _jumpToHoldTick = true;
}
break;
case kUpdateCue:
@@ -637,7 +651,14 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
// (e.g. song 110, during the intro). The original interpreter
// treats this case as an infinite loop (bug #3311911).
if (_pSnd->loop || _pSnd->hold > 0) {
- // We need to play it again...
+ // TODO: this jump is also vulnerable to the same lockup as
+ // the MIDI hold one above. However, we can't perform the
+ // jump on the next tick like with the MIDI hold jump above,
+ // as there aren't any subsequent MIDI events after this one.
+ // This assert is here to detect cases where the song ends
+ // up jumping forward, like with bug #3614566 (see above).
+ assert(_loopTick + info.delta < _position._playTick);
+
uint32 extraDelta = info.delta;
jumpToTick(_loopTick);
_nextEvent.delta += extraDelta;
diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h
index d3fd337644..7bd68994c8 100644
--- a/engines/sci/sound/midiparser_sci.h
+++ b/engines/sci/sound/midiparser_sci.h
@@ -110,6 +110,7 @@ protected:
int16 _signalToSet;
bool _dataincAdd;
int16 _dataincToAdd;
+ bool _jumpToHoldTick;
bool _resetOnPause;
bool _channelUsed[16];
diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index 0337a8d306..a567ece2ea 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -210,7 +210,7 @@ void RobotDecoder::readNextPacket() {
// Copy over the decompressed frame
byte *inFrame = decompressedFrame;
- byte *outFrame = (byte *)surface->pixels;
+ byte *outFrame = (byte *)surface->getPixels();
// Black out the surface
memset(outFrame, 0, surface->w * surface->h);
diff --git a/engines/sci/video/seq_decoder.cpp b/engines/sci/video/seq_decoder.cpp
index a7b6346eca..54603ec1f1 100644
--- a/engines/sci/video/seq_decoder.cpp
+++ b/engines/sci/video/seq_decoder.cpp
@@ -119,7 +119,7 @@ const Graphics::Surface *SEQDecoder::SEQVideoTrack::decodeNextFrame() {
_fileStream->seek(offset);
if (frameType == kSeqFrameFull) {
- byte *dst = (byte *)_surface->pixels + frameTop * SEQ_SCREEN_WIDTH + frameLeft;
+ byte *dst = (byte *)_surface->getBasePtr(frameLeft, frameTop);
byte *linebuf = new byte[frameWidth];
@@ -133,7 +133,7 @@ const Graphics::Surface *SEQDecoder::SEQVideoTrack::decodeNextFrame() {
} else {
byte *buf = new byte[frameSize];
_fileStream->read(buf, frameSize);
- decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, (byte *)_surface->pixels + SEQ_SCREEN_WIDTH * frameTop, frameLeft, frameWidth, frameHeight, colorKey);
+ decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, (byte *)_surface->getBasePtr(0, frameTop), frameLeft, frameWidth, frameHeight, colorKey);
delete[] buf;
}
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 5c148a7b57..4e14473921 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1485,7 +1485,7 @@ void ScummEngine::playActorSounds() {
int sound;
for (i = 1; i < _numActors; i++) {
- if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom() && _actors[i]->_sound) {
+ if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom()) {
_currentScript = 0xFF;
if (_game.version == 0) {
sound = v0ActorSounds[i - 1] & 0x3F;
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp
index b6acf01050..481c4af432 100644
--- a/engines/scumm/akos.cpp
+++ b/engines/scumm/akos.cpp
@@ -994,7 +994,7 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {
if (_draw_bottom < rect.bottom)
_draw_bottom = rect.bottom;
- v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x * _vm->_bytesPerPixel;
+ v1.destptr = (byte *)_out.getBasePtr(v1.x, v1.y);
codec1_genericDecode(v1);
@@ -1288,7 +1288,7 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
int32 numskip_before = skip_x + (skip_y * _width);
int32 numskip_after = _width - cur_x;
- byte *dst = (byte *)_out.pixels + height_unk * _out.pitch + width_unk * _vm->_bytesPerPixel;
+ byte *dst = (byte *)_out.getBasePtr(width_unk, height_unk);
akos16Decompress(dst, _out.pitch, _srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, clip.left, clip.top, _zbuf);
return 0;
@@ -1358,7 +1358,7 @@ byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
}
- byte *dstPtr = (byte *)_out.pixels + dst.top * _out.pitch + dst.left * _vm->_bytesPerPixel;
+ byte *dstPtr = (byte *)_out.getBasePtr(dst.left, dst.top);
if (_shadow_mode == 3) {
Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, xmap, _vm->_bytesPerPixel);
} else {
diff --git a/engines/scumm/base-costume.cpp b/engines/scumm/base-costume.cpp
index 46c68c81b0..e1a8688bb9 100644
--- a/engines/scumm/base-costume.cpp
+++ b/engines/scumm/base-costume.cpp
@@ -32,13 +32,15 @@ byte BaseCostumeRenderer::drawCostume(const VirtScreen &vs, int numStrips, const
_out = vs;
if (drawToBackBuf)
- _out.pixels = vs.getBackPixels(0, 0);
+ _out.setPixels(vs.getBackPixels(0, 0));
else
- _out.pixels = vs.getPixels(0, 0);
+ _out.setPixels(vs.getPixels(0, 0));
_actorX += _vm->_virtscr[kMainVirtScreen].xstart & 7;
_out.w = _out.pitch / _vm->_bytesPerPixel;
- _out.pixels = (byte *)_out.pixels - (_vm->_virtscr[kMainVirtScreen].xstart & 7);
+ // We do not use getBasePtr here because the offset to pixels never used
+ // _vm->_bytesPerPixel, but it seems unclear why.
+ _out.setPixels((byte *)_out.getPixels() - (_vm->_virtscr[kMainVirtScreen].xstart & 7));
_numStrips = numStrips;
diff --git a/engines/scumm/bomp.cpp b/engines/scumm/bomp.cpp
index 845cf70722..5b87f3042c 100644
--- a/engines/scumm/bomp.cpp
+++ b/engines/scumm/bomp.cpp
@@ -231,7 +231,10 @@ void drawBomp(const BompDrawData &bd) {
}
src = bd.src;
- dst = (byte *)bd.dst.pixels + bd.y * bd.dst.pitch + (bd.x + clip.left);
+ // FIXME: This gets passed a const destination Surface. Intuitively this
+ // should never get written to. But sadly it does... For now we simply
+ // cast the const qualifier away.
+ dst = (byte *)const_cast<void *>(bd.dst.getBasePtr((bd.x + clip.left), bd.y));
const byte maskbit = revBitMask((bd.x + clip.left) & 7);
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 9ae75b6683..dd79aff2da 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -799,7 +799,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
if (ignoreCharsetMask || !vs->hasTwoBuffers) {
dstPtr = vs->getPixels(0, 0);
} else {
- dstPtr = (byte *)_vm->_textSurface.pixels;
+ dstPtr = (byte *)_vm->_textSurface.getPixels();
}
if (_blitAlso && vs->hasTwoBuffers) {
@@ -829,7 +829,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
dstPtr = vs->getPixels(_left, drawTop);
} else {
dstSurface = _vm->_textSurface;
- dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier;
+ dstPtr = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, (_top - _vm->_screenTop) * _vm->_textSurfaceMultiplier);
}
if (_blitAlso && vs->hasTwoBuffers) {
@@ -907,7 +907,7 @@ bool CharsetRendererClassic::prepareDraw(uint16 chr) {
void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int y) {
if (!prepareDraw(chr))
return;
- byte *dst = (byte *)s.pixels + y * s.pitch + x;
+ byte *dst = (byte *)s.getBasePtr(x, y);
drawBitsN(s, dst, _charPtr, *_fontPtr, y, _width, _height);
}
@@ -1242,7 +1242,7 @@ void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) {
if (ignoreCharsetMask) {
VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen];
s = *vs;
- s.pixels = vs->getPixels(0, 0);
+ s.setPixels(vs->getPixels(0, 0));
} else {
s = _vm->_textSurface;
drawTop -= _vm->_screenTop;
@@ -1401,7 +1401,7 @@ void CharsetRendererTownsClassic::drawBitsN(const Graphics::Surface&, byte *dst,
}
bool scale2x = (_vm->_textSurfaceMultiplier == 2);
- dst = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier;
+ dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, (_top - _vm->_screenTop) * _vm->_textSurfaceMultiplier);
int y, x;
int color;
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 4ebdd00fdc..85c60f9a40 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -293,7 +293,7 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
return 2;
}
- v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x * _vm->_bytesPerPixel;
+ v1.destptr = (byte *)_out.getBasePtr(v1.x, v1.y);
v1.mask_ptr = _vm->getMaskBuffer(0, v1.y, _zbuf);
@@ -826,7 +826,7 @@ byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) {
int my = _actorY + y + ty;
int mx = _actorX + x + tx;
if (!(_zbuf && (maskBuf[my * _numStrips + mx / 8] & revBitMask(mx & 7))))
- *((byte *)_out.pixels + my * _out.pitch + mx) = palette[c];
+ *((byte *)_out.getBasePtr(mx, my)) = palette[c];
}
}
}
@@ -1238,7 +1238,7 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) {
int destY = ypos + y;
if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) {
- byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX;
+ byte *dst = (byte *)_out.getBasePtr(destX, destY);
byte *mask = _vm->getMaskBuffer(0, destY, _zbuf);
if (a0->_limb_flipped[limb]) {
LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6);
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 269ae9e10a..721644b554 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -139,7 +139,7 @@ void ScummEngine_v6::grabCursor(int x, int y, int w, int h) {
return;
}
- setCursorFromBuffer((byte *)vs->pixels + (y - vs->topline) * vs->pitch + x, w, h, vs->pitch);
+ setCursorFromBuffer((byte *)vs->getBasePtr(x, y - vs->topline), w, h, vs->pitch);
}
void ScummEngine_v6::setDefaultCursor() {
@@ -417,13 +417,11 @@ void ScummEngine_v5::redefineBuiltinCursorFromChar(int index, int chr) {
Graphics::Surface s;
byte buf[16*17];
memset(buf, 123, 16*17);
- s.pixels = buf;
- s.w = _charset->getCharWidth(chr);
- s.h = _charset->getFontHeight();
- s.pitch = s.w;
+ s.init(_charset->getCharWidth(chr), _charset->getFontHeight(),
+ _charset->getCharWidth(chr), buf,
+ Graphics::PixelFormat::createFormatCLUT8());
// s.h = 17 for FM-TOWNS Loom Japanese. Fixes bug #1166917
assert(s.w <= 16 && s.h <= 17);
- s.format = Graphics::PixelFormat::createFormatCLUT8();
_charset->drawChar(chr, s, 0, 0);
diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp
index 9b6dd1e687..872293f821 100644
--- a/engines/scumm/debugger.cpp
+++ b/engines/scumm/debugger.cpp
@@ -641,7 +641,7 @@ static void hlineColor(ScummEngine *scumm, int x1, int x2, int y, byte color) {
x2 = right - 1;
- ptr = (byte *)vs->pixels + x1 + y * vs->pitch;
+ ptr = (byte *)vs->getBasePtr(x1, y);
while (x1++ <= x2) {
*ptr++ = color;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index cb807997e9..6717ea9b06 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -299,7 +299,11 @@ static const GameSettings gameVariantsTable[] = {
// Changed o_getResourceSize to cover all resource types
{"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttzoo", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "", 0, GID_PUTTZOO, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 98.5", 0, GID_PUTTZOO, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 99", 0, GID_PUTTZOO, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 100", 0, GID_PUTTZOO, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added VAR_PLATFORM variable
{"jungle", "", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -385,7 +389,8 @@ static const GameSettings gameVariantsTable[] = {
{"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// U32 code required, for testing only
- {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"moonbase", "1.0", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"moonbase", "1.1", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// HE100 games, which use older o72_debugInput code
@@ -758,6 +763,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "pajama2", "PYJAMADB", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama2", "PyjamaDBMN", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama2", "PyjamaDBMN", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
+ { "pajama2", "PyjamaHM", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "pajama2", "PyjamaHM", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
{ "pajama2", "PYJAMA2", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "pajama2", "Pyjama Pit 2", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
@@ -858,6 +864,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "Putt-Putt Saves the Zoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "game", kGenHEPC, Common::EN_ANY, Common::kPlatformIOS, 0 },
+ { "puttzoo", "pp3_unlocked", kGenHEPC, Common::EN_ANY, Common::kPlatformWindows, 0 },
{ "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
{ "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 50ff0b3988..1bb4a28f65 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -421,8 +421,8 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int
}
_res->createResource(rtBuffer, slot + 1, size);
- vs->pixels = getResourceAddress(rtBuffer, slot + 1);
- memset(vs->pixels, 0, size); // reset background
+ vs->setPixels(getResourceAddress(rtBuffer, slot + 1));
+ memset(vs->getBasePtr(0, 0), 0, size); // reset background
if (twobufs) {
vs->backBuf = _res->createResource(rtBuffer, slot + 5, size);
@@ -612,7 +612,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
// Some paranoia checks
assert(top >= 0 && bottom <= vs->h);
assert(x >= 0 && width <= vs->pitch);
- assert(_textSurface.pixels);
+ assert(_textSurface.getPixels());
// Perform some clipping
if (width > vs->w - x)
@@ -1135,7 +1135,7 @@ void ScummEngine::clearTextSurface() {
_townsScreen->fillLayerRect(1, 0, 0, _textSurface.w, _textSurface.h, 0);
#endif
- fill((byte *)_textSurface.pixels, _textSurface.pitch,
+ fill((byte *)_textSurface.getPixels(), _textSurface.pitch,
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
_game.platform == Common::kPlatformFMTowns ? 0 :
#endif
@@ -1590,7 +1590,7 @@ void GdiV2::prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
if (vs->hasTwoBuffers)
dst = vs->backBuf + y * vs->pitch + x * 8;
else
- dst = (byte *)vs->pixels + y * vs->pitch + x * 8;
+ dst = (byte *)vs->getBasePtr(x * 8, y);
mask_ptr = getMaskBuffer(x, y, 1);
@@ -1769,11 +1769,8 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
// Check whether lights are turned on or not
const bool lightsOn = _vm->isLightOn();
- if (_vm->_game.features & GF_SMALL_HEADER) {
+ if ((_vm->_game.features & GF_SMALL_HEADER) || _vm->_game.version == 8) {
smap_ptr = ptr;
- } else if (_vm->_game.version == 8) {
- // Skip to the BSTR->WRAP->OFFS chunk
- smap_ptr = ptr + 24;
} else {
smap_ptr = _vm->findResource(MKTAG('S','M','A','P'), ptr);
assert(smap_ptr);
@@ -1827,7 +1824,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
if (vs->hasTwoBuffers)
dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel);
else
- dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel);
+ dstPtr = (byte *)vs->getBasePtr(x * 8, y);
transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr);
@@ -1836,7 +1833,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
transpStrip = true;
if (vs->hasTwoBuffers) {
- byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel);
+ byte *frontBuf = (byte *)vs->getBasePtr(x * 8, y);
if (lightsOn)
copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->format.bytesPerPixel);
else
@@ -1887,8 +1884,14 @@ bool Gdi::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width,
smapLen = READ_LE_UINT32(smap_ptr);
if (stripnr * 4 + 4 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 4);
+ } else if (_vm->_game.version == 8) {
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
+ // Skip to the BSTR->WRAP->OFFS chunk
+ smap_ptr += 24;
+ if (stripnr * 4 + 8 < smapLen)
+ offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
} else {
- smapLen = READ_BE_UINT32(smap_ptr);
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
if (stripnr * 4 + 8 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
}
@@ -2262,7 +2265,7 @@ void Gdi::resetBackground(int top, int bottom, int strip) {
vs->bdirty[strip] = bottom;
bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->format.bytesPerPixel;
- backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->format.bytesPerPixel;
+ backbuff_ptr = (byte *)vs->getBasePtr((strip + vs->xstart/8) * 8, top);
numLinesToProcess = bottom - top;
if (numLinesToProcess) {
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index f86a4e56d5..0aed181afd 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -34,7 +34,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
if (width <= 0 || height <= 0)
return;
- assert(_textSurface.pixels);
+ assert(_textSurface.getPixels());
int m = _textSurfaceMultiplier;
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp
index be17a3b305..d01b456c8b 100644
--- a/engines/scumm/he/animation_he.cpp
+++ b/engines/scumm/he/animation_he.cpp
@@ -90,7 +90,7 @@ void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint
if (!surface)
return;
- byte *src = (byte *)surface->pixels;
+ const byte *src = (const byte *)surface->getPixels();
if (_video->hasDirtyPalette())
_vm->setPaletteFromPtr(_video->getPalette(), 256);
@@ -119,7 +119,7 @@ void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint
dst += y * pitch + x * 2;
do {
for (uint i = 0; i < w; i++) {
- uint16 color = *((uint16 *)src + i);
+ uint16 color = *((const uint16 *)src + i);
switch (dstType) {
case kDstScreen:
WRITE_UINT16(dst + i * 2, color);
diff --git a/engines/scumm/he/logic/moonbase.cpp b/engines/scumm/he/logic/moonbase.cpp
index fac2ea27ff..5b4618a4ad 100644
--- a/engines/scumm/he/logic/moonbase.cpp
+++ b/engines/scumm/he/logic/moonbase.cpp
@@ -39,6 +39,8 @@ public:
int LogicHEmoonbase::versionID() {
if (_vm->_game.features & GF_DEMO)
return -100;
+ else if (strcmp(_vm->_game.variant, "1.1") == 0)
+ return 110;
else
return 100;
}
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index b024154c7f..987f74957c 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2148,7 +2148,7 @@ void ScummEngine_v100he::o100_systemOps() {
break;
case 132:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 133:
quitGame();
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index adb2fcac2e..9259e0db2f 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -309,7 +309,7 @@ void ScummEngine_v70he::o70_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index b9f454de0f..42bf9a4bb6 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -158,7 +158,7 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
@@ -1199,7 +1199,7 @@ void ScummEngine_v72he::o72_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
@@ -1779,8 +1779,11 @@ void ScummEngine_v72he::copyArray(int array1, int a1_dim2start, int a1_dim2end,
copyArrayHelper(ah, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
copyArrayHelper(ah, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
} else {
+ // start at the end, so we copy backwards (in case the indices overlap)
copyArrayHelper(ah, a1_dim2end, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
copyArrayHelper(ah, a2_dim2end, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
+ dstPitch = -dstPitch;
+ srcPitch = -srcPitch;
}
for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
memcpy(dst, src, rowSize);
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index eb62b650a4..ae43d714ad 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -23,7 +23,7 @@
#ifdef ENABLE_HE
#include "common/archive.h"
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/config-manager.h"
#include "common/macresman.h"
#include "common/savefile.h"
@@ -180,7 +180,7 @@ void ScummEngine_v80he::o80_readConfigFile() {
}
} else {
// Normal Windows INI files
- Common::ConfigFile confFile;
+ Common::INIFile confFile;
if (!strcmp((char *)filename + r, "map.ini"))
confFile.loadFromFile((const char *)filename + r);
else
@@ -250,7 +250,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
memcpy(section, "BluesTreasureHunt-Disc2\0", 24);
}
- Common::ConfigFile ConfFile;
+ Common::INIFile ConfFile;
ConfFile.loadFromSaveFile((const char *)filename + r);
ConfFile.setKey((char *)option, (char *)section, (char *)string);
ConfFile.saveToSaveFile((const char *)filename + r);
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index 7f771a0265..0e96952a48 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -1509,7 +1509,7 @@ void IMuseInternal::initGM(MidiDriver *midi) {
midi->sysEx(buffer, 9);
debug(2, "GS SysEx: GS Reset");
_system->delayMillis(200);
-
+
// Set global Master Tune to 442.0kHz, as on the MT-32
memcpy(&buffer[4], "\x40\x00\x00\x00\x04\x04\x0F\x29", 8);
midi->sysEx(buffer, 12);
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index ee2de49475..d1786dfb60 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -535,7 +535,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
openMainMenuDialog(); // Display global main menu
- if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
+ if (VAR_SAVELOAD_SCRIPT2 != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT2), 0, 0, 0);
} else if (restartKeyEnabled && (lastKeyHit.keycode == Common::KEYCODE_F8 && lastKeyHit.hasFlags(0))) {
diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp
index fa6d4264ec..d711b63342 100644
--- a/engines/scumm/insane/insane_enemy.cpp
+++ b/engines/scumm/insane/insane_enemy.cpp
@@ -1519,8 +1519,7 @@ void Insane::chooseEnemyWeaponAnim(int32 buttons) {
case INV_BOOT:
case INV_HAND:
case INV_DUST:
- _actor[1].act[2].state = 0;
- switchEnemyWeapon();
+ // fallthrough
default:
switchEnemyWeapon();
}
@@ -2437,6 +2436,7 @@ void Insane::actor12Reaction(int32 buttons) {
smlayer_setActorFacing(1, 2, 6, 180);
smlayer_setActorLayer(1, 2, 25);
_actor[1].act[2].state = 103;
+ break;
case 103:
_actor[1].kicking = false;
diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp
index 048b29d68b..d9f0b412e1 100644
--- a/engines/scumm/nut_renderer.cpp
+++ b/engines/scumm/nut_renderer.cpp
@@ -357,7 +357,10 @@ void NutRenderer::drawFrame(byte *dst, int c, int x, int y) {
}
void NutRenderer::drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color) {
- byte *dst = (byte *)s.pixels + y * s.pitch + x;
+ // FIXME: This gets passed a const destination Surface. Intuitively this
+ // should never get written to. But sadly it does... For now we simply
+ // cast the const qualifier away.
+ byte *dst = (byte *)const_cast<void *>(s.getBasePtr(x, y));
const int width = MIN((int)_chars[c].width, s.w - x);
const int height = MIN((int)_chars[c].height, s.h - y);
const byte *src = unpackChar(c);
@@ -391,7 +394,10 @@ void NutRenderer::drawChar(const Graphics::Surface &s, byte c, int x, int y, byt
}
void NutRenderer::draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color) {
- byte *dst = (byte *)s.pixels + y * s.pitch + x;
+ // FIXME: This gets passed a const destination Surface. Intuitively this
+ // should never get written to. But sadly it does... For now we simply
+ // cast the const qualifier away.
+ byte *dst = (byte *)const_cast<void *>(s.getBasePtr(x, y));
const int width = _vm->_2byteWidth;
const int height = MIN(_vm->_2byteHeight, s.h - y);
const byte *src = _vm->get2byteCharPtr(c);
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index ed77a863cd..d266183f85 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -1715,7 +1715,7 @@ void ScummEngine_v6::drawBlastObject(BlastObject *eo) {
error("object %d is not a blast object", eo->number);
bdd.dst = *vs;
- bdd.dst.pixels = vs->getPixels(0, 0);
+ bdd.dst.setPixels(vs->getPixels(0, 0));
bdd.x = eo->rect.left;
bdd.y = eo->rect.top;
diff --git a/engines/scumm/player_mac.cpp b/engines/scumm/player_mac.cpp
index c16c85bff3..a60736df5e 100644
--- a/engines/scumm/player_mac.cpp
+++ b/engines/scumm/player_mac.cpp
@@ -289,12 +289,16 @@ uint32 Player_Mac::durationToSamples(uint16 duration) {
// (duration * 473 * _sampleRate) / (4 * 480 * 480)
//
// But that's likely to cause integer overflow, so we do it in two
- // steps and hope that the rounding error won't be noticeable.
+ // steps using bitwise operations to perform
+ // ((duration * 473 * _sampleRate) / 4096) without overflowing,
+ // then divide this by 225
+ // (note that 4 * 480 * 480 == 225 * 4096 == 225 << 12)
//
// The original code is a bit unclear on if it should be 473 or 437,
// but since the comments indicated 473 I'm assuming 437 was a typo.
- uint32 samples = (duration * _sampleRate) / (4 * 480);
- samples = (samples * 473) / 480;
+ uint32 samples = (duration * _sampleRate);
+ samples = (samples >> 12) * 473 + (((samples & 4095) * 473) >> 12);
+ samples = samples / 225;
return samples;
}
diff --git a/engines/scumm/player_v3m.cpp b/engines/scumm/player_v3m.cpp
index 0f222d84fe..bf65ec797f 100644
--- a/engines/scumm/player_v3m.cpp
+++ b/engines/scumm/player_v3m.cpp
@@ -124,7 +124,7 @@ bool Player_V3M::checkMusicAvailable() {
return true;
}
}
-
+
GUI::MessageDialog dialog(_(
"Could not find the 'Loom' Macintosh executable to read the\n"
"instruments from. Music will be disabled."), _("OK"));
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index a75e864e7a..6983c51f30 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -394,7 +394,7 @@ ScummEngine_v6::ArrayHeader *ScummEngine_v6::getArray(int array) {
int ScummEngine_v6::readArray(int array, int idx, int base) {
ArrayHeader *ah = getArray(array);
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
// WORKAROUND bug #645711. This is clearly a script bug, as this script
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index db8da21bbc..979573c5f5 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sun Jun 23 22:18:47 2013
+ This file was generated by the md5table tool on Thu Aug 15 12:47:39 2013
DO NOT EDIT MANUALLY!
*/
@@ -328,6 +328,7 @@ static const MD5Table md5table[] = {
{ "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS },
{ "7410a8ba9795020cd42f171c4320659e", "pajama3", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", "HE 90", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
+ { "7477bc23d0383516c5e310cd8771dcc9", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "74da3494fbe1a7d20213b0afe0954755", "catalog", "HE CUP", "Preview", 10841544, Common::FR_FRA, Common::kPlatformUnknown },
{ "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS },
@@ -343,6 +344,7 @@ static const MD5Table md5table[] = {
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine },
+ { "7b4ee071eecadc2d8cd0c3509110825c", "puttzoo", "HE 100", "Remastered", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown },
{ "7c8100e360e8ef05f88069d4cfa0afd1", "puttrace", "HE 99", "Demo", 13108, Common::EN_GRB, Common::kPlatformWindows },
@@ -535,7 +537,7 @@ static const MD5Table md5table[] = {
{ "ce7733f185b838e248927c7ba1a04204", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "ce7fd0c382389a6791fc3e199c117ef4", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "cea91e3dd47f2518ea418e41611aa77f", "spyfox2", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
- { "cf400d20769fb70eb21766582f4924f7", "moonbase", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "cf400d20769fb70eb21766582f4924f7", "moonbase", "1.0", "1.0", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "cf4ef315214c7d8cdab6302cdb7e50db", "freddi", "HE 73", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "cf8d13446ec6cb6222287a925fd47c1d", "baseball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "cf8ef3a1fb483c5c4b1c584d1167b2c4", "freddi", "HE 73", "", -1, Common::DE_DEU, Common::kPlatformWindows },
@@ -583,6 +585,7 @@ static const MD5Table md5table[] = {
{ "e03ed1474ec14de78359970e0457a820", "freddi4", "HE 99", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "e144f5f49d9241d2a9dee2576b3d09cb", "airport", "", "Demo", 51152, Common::EN_ANY, Common::kPlatformWindows },
{ "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "e1c9998826ce7fa8bde5cc3a5023edec", "moonbase", "1.1", "1.1", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index a77c1c0141..ca05c90936 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -240,6 +240,7 @@ enum ScummGameId {
GID_FBEAR,
GID_PUTTMOON,
GID_FUNPACK,
+ GID_PUTTZOO,
GID_FREDDI3,
GID_BIRTHDAYRED,
GID_BIRTHDAYYELLOW,
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 77c7daa0df..9c90d7575d 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -714,6 +714,12 @@ void ScummEngine_v99he::resetScummVars() {
VAR(140) = 0;
#endif
}
+
+ if (_game.id == GID_PUTTZOO && _game.heversion == 100 && _game.platform == Common::kPlatformWindows) {
+ // Specific to Nimbus Games version.
+ VAR(156) = 1;
+ VAR(157) = 0;
+ }
}
#endif
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 79ec060bc1..742aac1a53 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -314,7 +314,7 @@ bool MoviePlayer::playVideo() {
if (_decoderType == kVideoDecoderPSX)
drawFramePSX(frame);
else
- _vm->_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
}
if (_decoder->hasDirtyPalette()) {
@@ -407,7 +407,7 @@ bool MoviePlayer::playVideo() {
}
Graphics::Surface *screen = _vm->_system->lockScreen();
- performPostProcessing((byte *)screen->pixels);
+ performPostProcessing((byte *)screen->getPixels());
_vm->_system->unlockScreen();
_vm->_system->updateScreen();
}
@@ -498,7 +498,7 @@ void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
- _vm->_system->copyRectToScreen(scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+ _vm->_system->copyRectToScreen(scaledFrame.getPixels(), scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
scaledFrame.free();
}
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 713120ad43..92fa9d0e44 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -334,7 +334,7 @@ bool MoviePlayer::playVideo() {
if (_decoderType == kVideoDecoderPSX)
drawFramePSX(frame);
else
- _vm->_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
}
if (_decoder->hasDirtyPalette()) {
@@ -403,7 +403,7 @@ void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
- _vm->_system->copyRectToScreen(scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+ _vm->_system->copyRectToScreen(scaledFrame.getPixels(), scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
scaledFrame.free();
}
diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp
index a95532ec65..3cdce1b493 100644
--- a/engines/sword25/fmv/movieplayer.cpp
+++ b/engines/sword25/fmv/movieplayer.cpp
@@ -130,10 +130,10 @@ void MoviePlayer::update() {
assert(s->format.bytesPerPixel == 4);
#ifdef THEORA_INDIRECT_RENDERING
- const byte *frameData = (const byte *)s->getBasePtr(0, 0);
+ const byte *frameData = (const byte *)s->getPixels();
_outputBitmap->setContent(frameData, s->pitch * s->h, 0, s->pitch);
#else
- g_system->copyRectToScreen(s->getBasePtr(0, 0), s->pitch, _outX, _outY, MIN(s->w, _backSurface->w), MIN(s->h, _backSurface->h));
+ g_system->copyRectToScreen(s->getPixels(), s->pitch, _outX, _outY, MIN(s->w, _backSurface->w), MIN(s->h, _backSurface->h));
g_system->updateScreen();
#endif
}
diff --git a/engines/sword25/gfx/dynamicbitmap.cpp b/engines/sword25/gfx/dynamicbitmap.cpp
index 242508bf85..1f3d2d063d 100644
--- a/engines/sword25/gfx/dynamicbitmap.cpp
+++ b/engines/sword25/gfx/dynamicbitmap.cpp
@@ -53,7 +53,7 @@ DynamicBitmap::DynamicBitmap(InputPersistenceBlock &reader, RenderObjectPtr<Rend
bool DynamicBitmap::createRenderedImage(uint width, uint height) {
bool result = false;
_image.reset(new RenderedImage(width, height, result));
-
+
_originalWidth = _width = width;
_originalHeight = _height = height;
@@ -77,7 +77,7 @@ bool DynamicBitmap::doRender(RectangleList *updateRects) {
// Get the frame buffer object
GraphicEngine *pGfx = Kernel::getInstance()->getGfx();
assert(pGfx);
-
+
// Draw the bitmap
bool result;
if (_scaleFactorX == 1.0f && _scaleFactorY == 1.0f) {
diff --git a/engines/sword25/gfx/image/image.h b/engines/sword25/gfx/image/image.h
index 9d7fc43251..8db54e7c54 100644
--- a/engines/sword25/gfx/image/image.h
+++ b/engines/sword25/gfx/image/image.h
@@ -205,7 +205,7 @@ public:
@brief Returns true, if the content of the BS_Image is allowed to be replaced by call of SetContent().
*/
virtual bool isSetContentAllowed() const = 0;
-
+
virtual bool isSolid() const { return false; }
//@}
diff --git a/engines/sword25/gfx/image/imgloader.cpp b/engines/sword25/gfx/image/imgloader.cpp
index e103626416..9006a596b4 100644
--- a/engines/sword25/gfx/image/imgloader.cpp
+++ b/engines/sword25/gfx/image/imgloader.cpp
@@ -50,7 +50,7 @@ bool ImgLoader::decodePNGImage(const byte *fileDataPtr, uint fileSize, byte *&un
width = pngSurface->w;
height = pngSurface->h;
uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h];
- memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h);
+ memcpy(uncompressedDataPtr, (byte *)pngSurface->getPixels(), pngSurface->pitch * pngSurface->h);
pngSurface->free();
delete pngSurface;
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 81a29c727f..346b46f3b4 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -251,14 +251,10 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
// Create an encapsulating surface for the data
Graphics::Surface srcImage;
// TODO: Is the data really in the screen format?
- srcImage.format = g_system->getScreenFormat();
- srcImage.pitch = _width * 4;
- srcImage.w = _width;
- srcImage.h = _height;
- srcImage.pixels = _data;
+ srcImage.init(_width, _height, _width * 4, _data, g_system->getScreenFormat());
if (pPartRect) {
- srcImage.pixels = &_data[pPartRect->top * srcImage.pitch + pPartRect->left * 4];
+ srcImage.setPixels(&_data[pPartRect->top * srcImage.pitch + pPartRect->left * 4]);
srcImage.w = pPartRect->right - pPartRect->left;
srcImage.h = pPartRect->bottom - pPartRect->top;
@@ -287,14 +283,14 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
if ((width != srcImage.w) || (height != srcImage.h)) {
// Scale the image
img = imgScaled = scale(srcImage, width, height);
- savedPixels = (byte *)img->pixels;
+ savedPixels = (byte *)img->getPixels();
} else {
img = &srcImage;
}
for (RectangleList::iterator it = updateRects->begin(); it != updateRects->end(); ++it) {
const Common::Rect &clipRect = *it;
-
+
int skipLeft = 0, skipTop = 0;
int drawX = posX, drawY = posY;
int drawWidth = img->w;
@@ -306,7 +302,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
drawWidth -= skipLeft;
drawX = clipRect.left;
}
-
+
if (drawY < clipRect.top) {
skipTop = clipRect.top - drawY;
drawHeight -= skipTop;
@@ -315,13 +311,13 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
if (drawX + drawWidth >= clipRect.right)
drawWidth = clipRect.right - drawX;
-
+
if (drawY + drawHeight >= clipRect.bottom)
drawHeight = clipRect.bottom - drawY;
-
+
if ((drawWidth > 0) && (drawHeight > 0)) {
int xp = 0, yp = 0;
-
+
int inStep = 4;
int inoStep = img->pitch;
if (flipping & Image::FLIP_V) {
@@ -330,14 +326,14 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
} else {
xp = skipLeft;
}
-
+
if (flipping & Image::FLIP_H) {
inoStep = -inoStep;
yp = img->h - 1 - skipTop;
} else {
yp = skipTop;
}
-
+
byte *ino = (byte *)img->getBasePtr(xp, yp);
byte *outo = (byte *)_backSurface->getBasePtr(drawX, drawY);
@@ -351,7 +347,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
ino += inoStep;
}
} else
-#endif
+#endif
{
byte *in, *out;
for (int i = 0; i < drawHeight; i++) {
@@ -361,7 +357,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
uint32 pix = *(uint32 *)in;
int a = (pix >> 24) & 0xff;
in += inStep;
-
+
if (ca != 255) {
a = a * ca >> 8;
}
@@ -371,11 +367,11 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
out += 4;
continue;
}
-
+
int b = (pix >> 0) & 0xff;
int g = (pix >> 8) & 0xff;
int r = (pix >> 16) & 0xff;
-
+
if (a == 255) {
#if defined(SCUMM_LITTLE_ENDIAN)
if (cb != 255)
@@ -460,11 +456,11 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
}
}
-
+
}
if (imgScaled) {
- imgScaled->pixels = savedPixels;
+ imgScaled->setPixels(savedPixels);
imgScaled->free();
delete imgScaled;
}
diff --git a/engines/sword25/gfx/panel.cpp b/engines/sword25/gfx/panel.cpp
index 931b9cdbe7..b9bb8b087d 100644
--- a/engines/sword25/gfx/panel.cpp
+++ b/engines/sword25/gfx/panel.cpp
@@ -84,7 +84,7 @@ bool Panel::doRender(RectangleList *updateRects) {
gfxPtr->fill(&intersectionRect, _color);
}
}
-
+
return true;
}
diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp
index 807c1eb64b..1dd6f4590f 100644
--- a/engines/sword25/gfx/renderobject.cpp
+++ b/engines/sword25/gfx/renderobject.cpp
@@ -183,7 +183,7 @@ bool RenderObject::updateObjectState() {
// Die Bounding-Box neu berechnen und Update-Regions registrieren.
updateBoxes();
-
+
++_version;
// Änderungen Validieren
diff --git a/engines/sword25/gfx/renderobject.h b/engines/sword25/gfx/renderobject.h
index 7e0334ee88..1116c3284c 100644
--- a/engines/sword25/gfx/renderobject.h
+++ b/engines/sword25/gfx/renderobject.h
@@ -236,7 +236,7 @@ public:
@brief Löscht alle Kinderobjekte.
*/
void deleteAllChildren();
-
+
// Accessor-Methoden
// -----------------
/**
@@ -305,11 +305,11 @@ public:
int getZ() const {
return _z;
}
-
+
int getAbsoluteZ() const {
return _absoluteZ;
}
-
+
/**
@brief Gibt die Breite des Objektes zurück.
*/
@@ -363,11 +363,11 @@ public:
return _handle;
}
- // Get the RenderObjects current version
+ // Get the RenderObjects current version
int getVersion() const {
return _version;
}
-
+
bool isSolid() const {
return _isSolid;
}
@@ -410,7 +410,7 @@ protected:
bool _oldVisible;
static int _nextGlobalVersion;
-
+
int _version;
// This should be set to true if the RenderObject is NOT alpha-blended to optimize drawing
@@ -509,9 +509,9 @@ private:
@brief Berechnet die absolute Position des Objektes.
*/
int calcAbsoluteY() const;
-
+
int calcAbsoluteZ() const;
-
+
/**
@brief Sortiert alle Kinderobjekte nach ihrem Renderang.
*/
diff --git a/engines/sword25/gfx/renderobjectmanager.cpp b/engines/sword25/gfx/renderobjectmanager.cpp
index 994d9367ab..77f944c9e0 100644
--- a/engines/sword25/gfx/renderobjectmanager.cpp
+++ b/engines/sword25/gfx/renderobjectmanager.cpp
@@ -113,7 +113,7 @@ bool RenderObjectManager::render() {
RectangleList *updateRects = _uta->getRectangles();
Common::Array<int> updateRectsMinZ;
-
+
updateRectsMinZ.reserve(updateRects->size());
// Calculate the minimum drawing Z value of each update rectangle
@@ -144,9 +144,9 @@ bool RenderObjectManager::render() {
}
delete updateRects;
-
+
SWAP(_currQueue, _prevQueue);
-
+
return true;
}
diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp
index 0ea4bff906..7b56a6e9f3 100644
--- a/engines/sword25/gfx/screenshot.cpp
+++ b/engines/sword25/gfx/screenshot.cpp
@@ -40,7 +40,7 @@ namespace Sword25 {
bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream) {
// Convert the RGBA data to RGB
- const byte *pSrc = (const byte *)data->getBasePtr(0, 0);
+ const byte *pSrc = (const byte *)data->getPixels();
// Write our own custom header
stream->writeUint32BE(MKTAG('S','C','R','N')); // SCRN, short for "Screenshot"
@@ -85,7 +85,7 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data)
uint x, y;
x = y = 0;
- for (byte *pDest = (byte *)thumbnail.pixels; pDest < ((byte *)thumbnail.pixels + thumbnail.pitch * thumbnail.h); ) {
+ for (byte *pDest = (byte *)thumbnail.getPixels(); pDest < ((byte *)thumbnail.getBasePtr(0, thumbnail.h)); ) {
// Get an average over a 4x4 pixel block in the source image
int alpha, red, green, blue;
alpha = red = green = blue = 0;
diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp
index 91b93e8910..bb57fa3a03 100644
--- a/engines/sword25/gfx/staticbitmap.cpp
+++ b/engines/sword25/gfx/staticbitmap.cpp
@@ -71,7 +71,7 @@ bool StaticBitmap::initBitmapResource(const Common::String &filename) {
// RenderObject Eigenschaften aktualisieren
_originalWidth = _width = bitmapPtr->getWidth();
_originalHeight = _height = bitmapPtr->getHeight();
-
+
_isSolid = bitmapPtr->isSolid();
// Bild-Resource freigeben
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
index b7f5e30340..b7a8fd3c8b 100644
--- a/engines/sword25/util/pluto/pluto.cpp
+++ b/engines/sword25/util/pluto/pluto.cpp
@@ -1,6 +1,6 @@
/* $Id$ */
-/* Pluto - Heavy-duty persistence for Lua
+/* Tamed Pluto - Heavy-duty persistence for Lua
* Copyright (C) 2004 by Ben Sunshine-Hill, and released into the public
* domain. People making use of this software as part of an application
* are politely requested to email the author at sneftel@gmail.com
@@ -14,11 +14,17 @@
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
*/
+#include "config.h"
#include "sword25/util/lua/lua.h"
#include "pluto.h"
+#undef TOTEXT
+
#define USE_PDEP
#ifdef USE_PDEP
@@ -42,10 +48,20 @@
#include <string.h>
+/* Define this if you want size_t values to be written in 64-bit
+ (even on 32-bit systems). Should eliminate at least one source of
+ 32/64 bit incompatibility. */
+#define SIZES64
+
/* #define PLUTO_DEBUG */
+#ifdef SIZES64
+#define VERSION "Tamed Pluto 1.0 with SIZES64 flag"
+#else
+#define VERSION "Tamed Pluto 1.0"
+#endif
#ifdef PLUTO_DEBUG
@@ -56,6 +72,23 @@
#define verify(x) { int v = (int)((x)); v=v; lua_assert(v); }
+#define NUMTYPES 9
+static const char* typenames[] = {
+ "nil",
+ "boolean",
+ "lightuserdata",
+ "number",
+ "string",
+ "table",
+ "function",
+ "userdata",
+ "thread"
+};
+
+static int humanReadable = 0;
+#define hrBufSize 200
+static char hrBuf[hrBufSize];
+
typedef struct PersistInfo_t {
lua_State *L;
int counter;
@@ -76,6 +109,77 @@ void printindent(int indent)
}
#endif
+/* lua_Chunkwriter signature: (lua_State *L, const void *p, size_t sz, void *ud).
+ ud is a pointer to the WriterInfo struct (holds the buffer pointer)
+*/
+
+static void pi_write(PersistInfo *pi, const void *p, size_t size, void *ud) {
+ if (humanReadable) {
+ uint i;
+ snprintf(hrBuf, hrBufSize, " pi_write %d ", (int) size);
+ pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
+ for (i = 0; i < size; i++) {
+ char b = ((char *)p)[i];
+ snprintf(hrBuf, hrBufSize, "%X%X", (b >> 4) & 0xF, b & 0xF);
+ pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
+ }
+ snprintf(hrBuf, hrBufSize, "\n");
+ pi->writer(pi->L, hrBuf, strlen(hrBuf), ud);
+ } else {
+ pi->writer(pi->L, p, size, ud);
+ }
+#ifdef TOTEXT
+ int i;
+ printf(" pi_write %d ", (int) size);
+ for (i = 0; i < size; i++) {
+ char b = ((char *)p)[i];
+ printf("%X%X", (b >> 4) & 0xF, b & 0xF);
+ }
+ printf("\n");
+#endif
+}
+
+static void hrOut(PersistInfo *pi) {
+ pi->writer(pi->L, hrBuf, strlen(hrBuf), pi->ud);
+}
+
+static void write_size(PersistInfo *pi, size_t *val)
+{
+#ifdef SIZES64
+ int64 longval; /* yeah, you really need long long to get 8 bytes on win32... duh. */
+ longval = *val;
+ pi_write(pi, &longval, 8, pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "write_size64 %ld\n", longval);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("write_size64 %ld\n", longval);
+#endif
+#else
+ pi_write(pi, val, sizeof(size_t), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "write_size %ld\n", *((size_t *)val));
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("write_size %ld\n", *val);
+#endif
+#endif
+}
+
+static void read_size(ZIO *zio, size_t *val)
+{
+#ifdef SIZES64
+ int64 longval;
+ verify(LIF(Z,read)(zio, &longval, 8) == 0);
+ *val = longval;
+#else
+ verify(LIF(Z,read)(zio, val, sizeof(size_t)) == 0);
+#endif
+}
+
+
/* Mutual recursion requires prototype */
static void persist(PersistInfo *pi);
@@ -107,7 +211,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
if(defaction) {
{
int zero = 0;
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistspecialobject_write_zero\n");
+#endif
}
return 0;
} else {
@@ -127,7 +238,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
if(defaction) {
{
int zero = 0;
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero2\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistspecialobject_write_zero2\n");
+#endif
}
return 0;
} else {
@@ -143,7 +261,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
/* perms reftbl sptbl ... obj */
{
int zero = 0;
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistspecialobject_write_zero3\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistspecialobject_write_zero3\n");
+#endif
}
return 0;
} else {
@@ -176,7 +301,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
/* perms reftbl ... obj mt func */
{
int one = 1;
- pi->writer(pi->L, &one, sizeof(int), pi->ud);
+ pi_write(pi, &one, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistspecialobject_write_one\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistspecialobject_write_one\n");
+#endif
}
persist(pi);
/* perms reftbl ... obj mt func */
@@ -187,6 +319,14 @@ static int persistspecialobject(PersistInfo *pi, int defaction)
static void persisttable(PersistInfo *pi)
{
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persisttable\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persisttable\n");
+#endif
+
/* perms reftbl ... tbl */
lua_checkstack(pi->L, 3);
if(persistspecialobject(pi, 1)) {
@@ -235,8 +375,15 @@ static void persistuserdata(PersistInfo *pi) {
} else {
/* Use literal persistence */
size_t length = uvalue(getobject(pi->L, -1))->len;
- pi->writer(pi->L, &length, sizeof(size_t), pi->ud);
- pi->writer(pi->L, lua_touserdata(pi->L, -1), length, pi->ud);
+ write_size(pi, &length);
+ pi_write(pi, lua_touserdata(pi->L, -1), length, pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistuserdata %ld\n", (long) length);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistuserdata %ld\n", (long) length);
+#endif
if(!lua_getmetatable(pi->L, -1)) {
/* perms reftbl ... udata */
lua_pushnil(pi->L);
@@ -269,8 +416,8 @@ static void pushproto(lua_State *L, Proto *proto)
#define setuvvalue(L,obj,x) \
{ TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \
- checkliveness(G(L),i_o); }
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUPVAL; \
+ checkliveness(G(L),i_o); }
static void pushupval(lua_State *L, UpVal *upval)
{
@@ -309,7 +456,14 @@ static void persistfunction(PersistInfo *pi)
{
/* We don't really _NEED_ the number of upvals,
* but it'll simplify things a bit */
- pi->writer(pi->L, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
+ pi_write(pi, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistfunction_number_upvalues %d\n", (int) cl->l.p->nups);
+#endif
}
/* Persist prototype */
{
@@ -401,7 +555,14 @@ static void persistproto(PersistInfo *pi)
/* Persist constant refs */
{
int i;
- pi->writer(pi->L, &p->sizek, sizeof(int), pi->ud);
+ pi_write(pi, &p->sizek, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_sizek %d\n", p->sizek);
+ hrOut(pi);
+ }
+ #ifdef TOTEXT
+ printf("persistproto_sizek %d\n", p->sizek);
+ #endif
for(i=0; i<p->sizek; i++) {
LIF(A,pushobject)(pi->L, &p->k[i]);
/* perms reftbl ... proto const */
@@ -415,7 +576,14 @@ static void persistproto(PersistInfo *pi)
/* serialize inner Proto refs */
{
int i;
- pi->writer(pi->L, &p->sizep, sizeof(int), pi->ud);
+ pi_write(pi, &p->sizep, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_sizep %d\n", p->sizep);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_sizep %d\n", p->sizep);
+#endif
for(i=0; i<p->sizep; i++)
{
pushproto(pi->L, p->p[i]);
@@ -429,14 +597,37 @@ static void persistproto(PersistInfo *pi)
/* Serialize code */
{
- pi->writer(pi->L, &p->sizecode, sizeof(int), pi->ud);
- pi->writer(pi->L, p->code, sizeof(Instruction) * p->sizecode, pi->ud);
+ int len;
+ pi_write(pi, &p->sizecode, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_sizecode %d\n", p->sizecode);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_sizecode %d\n", p->sizecode);
+#endif
+ len = sizeof(Instruction) * p->sizecode;
+ pi_write(pi, p->code, len, pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_code %d\n", len);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_code %d\n", len);
+#endif
}
/* Serialize upvalue names */
{
int i;
- pi->writer(pi->L, &p->sizeupvalues, sizeof(int), pi->ud);
+ pi_write(pi, &p->sizeupvalues, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_upvalues %d\n", p->sizeupvalues);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_upvalues %d\n", p->sizeupvalues);
+#endif
for(i=0; i<p->sizeupvalues; i++)
{
pushstring(pi->L, p->upvalues[i]);
@@ -447,15 +638,36 @@ static void persistproto(PersistInfo *pi)
/* Serialize local variable infos */
{
int i;
- pi->writer(pi->L, &p->sizelocvars, sizeof(int), pi->ud);
+ pi_write(pi, &p->sizelocvars, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_sizelocvars %d\n", p->sizelocvars);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_sizelocvars %d\n", p->sizelocvars);
+#endif
for(i=0; i<p->sizelocvars; i++)
{
pushstring(pi->L, p->locvars[i].varname);
persist(pi);
lua_pop(pi->L, 1);
- pi->writer(pi->L, &p->locvars[i].startpc, sizeof(int), pi->ud);
- pi->writer(pi->L, &p->locvars[i].endpc, sizeof(int), pi->ud);
+ pi_write(pi, &p->locvars[i].startpc, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_startpc %d\n", p->locvars[i].startpc);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_startpc %d\n", p->locvars[i].startpc);
+#endif
+ pi_write(pi, &p->locvars[i].endpc, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_endpc %d\n", p->locvars[i].endpc);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_endpc %d\n", p->locvars[i].endpc);
+#endif
}
}
@@ -466,23 +678,81 @@ static void persistproto(PersistInfo *pi)
/* Serialize line numbers */
{
- pi->writer(pi->L, &p->sizelineinfo, sizeof(int), pi->ud);
+ pi_write(pi, &p->sizelineinfo, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_sizelineinfo %d\n", p->sizelineinfo);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_sizelineinfo %d\n", p->sizelineinfo);
+#endif
if (p->sizelineinfo)
{
- pi->writer(pi->L, p->lineinfo, sizeof(int) * p->sizelineinfo, pi->ud);
+ int len;
+ len = sizeof(int) * p->sizelineinfo;
+ pi_write(pi, p->lineinfo, len, pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_lineinfo %d\n", len);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_lineinfo %d\n", len);
+#endif
}
}
/* Serialize linedefined and lastlinedefined */
- pi->writer(pi->L, &p->linedefined, sizeof(int), pi->ud);
- pi->writer(pi->L, &p->lastlinedefined, sizeof(int), pi->ud);
+ pi_write(pi, &p->linedefined, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_linedefined %d\n", p->linedefined);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_linedefined %d\n", p->linedefined);
+#endif
+ pi_write(pi, &p->lastlinedefined, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_lastlinedefined %d\n", p->lastlinedefined);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_lastlinedefined %d\n", p->lastlinedefined);
+#endif
/* Serialize misc values */
{
- pi->writer(pi->L, &p->nups, sizeof(lu_byte), pi->ud);
- pi->writer(pi->L, &p->numparams, sizeof(lu_byte), pi->ud);
- pi->writer(pi->L, &p->is_vararg, sizeof(lu_byte), pi->ud);
- pi->writer(pi->L, &p->maxstacksize, sizeof(lu_byte), pi->ud);
+ pi_write(pi, &p->nups, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_nups %d\n", (int) p->nups);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_nups %d\n", (int) p->nups);
+#endif
+ pi_write(pi, &p->numparams, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_numparams %d\n", (int) p->numparams);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_numparams %d\n", (int) p->numparams);
+#endif
+ pi_write(pi, &p->is_vararg, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_is_vararg %d\n", (int) p->is_vararg);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_is_vararg %d\n", (int) p->is_vararg);
+#endif
+ pi_write(pi, &p->maxstacksize, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistproto_maxstacksize %d\n", (int) p->maxstacksize);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistproto_maxstacksize %d\n", (int) p->maxstacksize);
+#endif
}
/* We do not currently persist upvalue names, local variable names,
* variable lifetimes, line info, or source code. */
@@ -518,7 +788,7 @@ static void persistthread(PersistInfo *pi)
/* Persist the stack */
posremaining = revappendstack(L2, pi->L);
/* perms reftbl ... thr (rev'ed contents of L2) */
- pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud);
+ write_size(pi, &posremaining);
for(; posremaining > 0; posremaining--) {
persist(pi);
lua_pop(pi->L, 1);
@@ -527,7 +797,7 @@ static void persistthread(PersistInfo *pi)
/* Now, persist the CallInfo stack. */
{
size_t i, numframes = (L2->ci - L2->base_ci) + 1;
- pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud);
+ write_size(pi, &numframes);
for(i=0; i<numframes; i++) {
CallInfo *ci = L2->base_ci + i;
size_t stackbase = ci->base - L2->stack;
@@ -536,11 +806,18 @@ static void persistthread(PersistInfo *pi)
size_t savedpc = (ci != L2->base_ci) ?
ci->savedpc - ci_func(ci)->l.p->code :
0;
- pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud);
- pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud);
- pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud);
- pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud);
- pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud);
+ write_size(pi, &stackbase);
+ write_size(pi, &stackfunc);
+ write_size(pi, &stacktop);
+ pi_write(pi, &ci->nresults, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistthread %d\n", ci->nresults);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistthread %d\n", ci->nresults);
+#endif
+ write_size(pi, &savedpc);
}
}
@@ -549,10 +826,18 @@ static void persistthread(PersistInfo *pi)
size_t stackbase = L2->base - L2->stack;
size_t stacktop = L2->top - L2->stack;
lua_assert(L2->nCcalls <= 1);
- pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud);
- pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud);
- pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud);
- pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
+ pi_write(pi, &L2->status, sizeof(lu_byte), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistthread_status %d\n", (int) L2->status);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistthread_status %d\n", (int) L2->status);
+#endif
+ write_size(pi, &stackbase);
+ write_size(pi, &stacktop);
+ pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
+ //write_size(pi, (size_t *)&L2->errfunc);
}
/* Finally, record upvalues which need to be reopened */
@@ -573,7 +858,7 @@ static void persistthread(PersistInfo *pi)
lua_pop(pi->L, 1);
/* perms reftbl ... thr */
stackpos = uv->v - L2->stack;
- pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud);
+ write_size(pi, &stackpos);
}
/* perms reftbl ... thr */
lua_pushnil(pi->L);
@@ -588,26 +873,62 @@ static void persistthread(PersistInfo *pi)
static void persistboolean(PersistInfo *pi)
{
int b = lua_toboolean(pi->L, -1);
- pi->writer(pi->L, &b, sizeof(int), pi->ud);
+ pi_write(pi, &b, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistboolean %d\n", b);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistboolean %d\n", b);
+#endif
}
static void persistlightuserdata(PersistInfo *pi)
{
void *p = lua_touserdata(pi->L, -1);
- pi->writer(pi->L, &p, sizeof(void *), pi->ud);
+ pi_write(pi, &p, sizeof(void *), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistlightuserdata %p\n", p);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistlightuserdata %d\n", (int) p);
+#endif
}
static void persistnumber(PersistInfo *pi)
{
lua_Number n = lua_tonumber(pi->L, -1);
- pi->writer(pi->L, &n, sizeof(lua_Number), pi->ud);
+ pi_write(pi, &n, sizeof(lua_Number), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persistnumber %d (%d)\n", (int) n, (int) sizeof(lua_Number));
+#endif
}
static void persiststring(PersistInfo *pi)
{
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persiststring\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persiststring\n");
+#endif
size_t length = lua_strlen(pi->L, -1);
- pi->writer(pi->L, &length, sizeof(size_t), pi->ud);
- pi->writer(pi->L, lua_tostring(pi->L, -1), length, pi->ud);
+ write_size(pi, &length);
+ const char* s = lua_tostring(pi->L, -1);
+ pi_write(pi, s, length, pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persiststring %d \"%s\"\n", (int)length, s);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persiststring %d \"%s\"\n", length, s);
+#endif
}
/* Top-level delegating persist function
@@ -630,8 +951,22 @@ static void persist(PersistInfo *pi)
// since size_t is supposedly the same size as a pointer on most
// (modern) architectures.
int ref = (int)(size_t)lua_touserdata(pi->L, -1);
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
- pi->writer(pi->L, &ref, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_seenobject\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_seenobject\n");
+#endif
+ pi_write(pi, &ref, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_touserdata_ref %d\n", ref);
+#endif
lua_pop(pi->L, 1);
/* perms reftbl ... obj ref */
#ifdef PLUTO_DEBUG
@@ -647,9 +982,16 @@ static void persist(PersistInfo *pi)
if(lua_isnil(pi->L, -1)) {
int zero = 0;
/* firsttime */
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
/* ref */
- pi->writer(pi->L, &zero, sizeof(int), pi->ud);
+ pi_write(pi, &zero, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_nil (last 2 lines)\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_nil (last 2 lines)\n");
+#endif
#ifdef PLUTO_DEBUG
printindent(pi->level);
printf("0 0\n");
@@ -659,7 +1001,14 @@ static void persist(PersistInfo *pi)
{
/* indicate that it's the first time */
int one = 1;
- pi->writer(pi->L, &one, sizeof(int), pi->ud);
+ pi_write(pi, &one, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_newobject\n");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_newobject\n");
+#endif
}
lua_pushvalue(pi->L, -1);
/* perms reftbl ... obj obj */
@@ -668,7 +1017,14 @@ static void persist(PersistInfo *pi)
lua_rawset(pi->L, 2);
/* perms reftbl ... obj */
- pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud);
+ pi_write(pi, &pi->counter, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_counter %d\n", pi->counter);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_counter %d\n", pi->counter);
+#endif
/* At this point, we'll give the permanents table a chance to play. */
@@ -685,7 +1041,14 @@ static void persist(PersistInfo *pi)
printf("1 %d PERM\n", pi->counter);
pi->level++;
#endif
- pi->writer(pi->L, &type, sizeof(int), pi->ud);
+ pi_write(pi, &type, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist_permtype %d\n", type);
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist_permtype %d\n", type);
+#endif
persist(pi);
lua_pop(pi->L, 1);
/* perms reftbl ... obj */
@@ -702,7 +1065,14 @@ static void persist(PersistInfo *pi)
}
{
int type = lua_type(pi->L, -1);
- pi->writer(pi->L, &type, sizeof(int), pi->ud);
+ pi_write(pi, &type, sizeof(int), pi->ud);
+ if (humanReadable) {
+ snprintf(hrBuf, hrBufSize, "persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
+ hrOut(pi);
+ }
+#ifdef TOTEXT
+ printf("persist %s\n", type >= 0 && type < NUMTYPES ? typenames[type] : "?");
+#endif
#ifdef PLUTO_DEBUG
printindent(pi->level);
@@ -798,8 +1168,8 @@ typedef struct WriterInfo_t {
size_t buflen;
} WriterInfo;
-static int bufwriter (lua_State *L, const void* p, size_t sz, void* ud) {
- const char* cp = (const char*)p;
+static int bufwriter (lua_State *L, const void *p, size_t sz, void *ud) {
+ const char *cp = (const char *)p;
WriterInfo *wi = (WriterInfo *)ud;
LIF(M,reallocvector)(L, wi->buf, wi->buflen, wi->buflen+sz, char);
@@ -819,7 +1189,7 @@ int persist_l(lua_State *L)
wi.buf = NULL;
wi.buflen = 0;
-
+
lua_settop(L, 2);
/* perms? rootobj? */
luaL_checktype(L, 1, LUA_TTABLE);
@@ -895,10 +1265,13 @@ static void unpersistnumber(UnpersistInfo *upi)
static void unpersiststring(UnpersistInfo *upi)
{
/* perms reftbl sptbl ref */
+ /*int length;*/
size_t length;
char* string;
lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);
+ /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);*/
+ /*verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);*/
+ read_size(&upi->zio, &length);
string = pdep_newvector(upi->L, length, char);
verify(LIF(Z,read)(&upi->zio, string, length) == 0);
lua_pushlstring(upi->L, string, length);
@@ -1312,7 +1685,7 @@ static void unpersistthread(int ref, UnpersistInfo *upi)
/* First, deserialize the object stack. */
{
size_t i, stacksize;
- verify(LIF(Z,read)(&upi->zio, &stacksize, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &stacksize);
LIF(D,growstack)(L2, (int)stacksize);
/* Make sure that the first stack element (a nil, representing
* the imaginary top-level C function) is written to the very,
@@ -1331,16 +1704,16 @@ static void unpersistthread(int ref, UnpersistInfo *upi)
/* Now, deserialize the CallInfo stack. */
{
size_t i, numframes;
- verify(LIF(Z,read)(&upi->zio, &numframes, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &numframes);
LIF(D,reallocCI)(L2,numframes*2);
for(i=0; i<numframes; i++) {
CallInfo *ci = L2->base_ci + i;
size_t stackbase, stackfunc, stacktop, savedpc;
- verify(LIF(Z,read)(&upi->zio, &stackbase, sizeof(size_t)) == 0);
- verify(LIF(Z,read)(&upi->zio, &stackfunc, sizeof(size_t)) == 0);
- verify(LIF(Z,read)(&upi->zio, &stacktop, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &stackbase);
+ read_size(&upi->zio, &stackfunc);
+ read_size(&upi->zio, &stacktop);
verify(LIF(Z,read)(&upi->zio, &ci->nresults, sizeof(int)) == 0);
- verify(LIF(Z,read)(&upi->zio, &savedpc, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &savedpc);
if(stacklimit < stacktop)
stacklimit = stacktop;
@@ -1363,9 +1736,10 @@ static void unpersistthread(int ref, UnpersistInfo *upi)
size_t stackbase, stacktop;
L2->savedpc = L2->ci->savedpc;
verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0);
- verify(LIF(Z,read)(&upi->zio, &stackbase, sizeof(size_t)) == 0);
- verify(LIF(Z,read)(&upi->zio, &stacktop, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &stackbase);
+ read_size(&upi->zio, &stacktop);
verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0);
+ //read_size(&upi->zio, (size_t *)&L2->errfunc);
L2->base = L2->stack + stackbase;
L2->top = L2->stack + stacktop;
}
@@ -1391,7 +1765,7 @@ static void unpersistthread(int ref, UnpersistInfo *upi)
lua_pop(upi->L, 1);
/* perms reftbl ... thr */
- verify(LIF(Z,read)(&upi->zio, &stackpos, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &stackpos);
uv->v = L2->stack + stackpos;
gcunlink(upi->L, (GCObject *)uv);
uv->marked = luaC_white(g);
@@ -1443,7 +1817,7 @@ static void unpersistuserdata(int ref, UnpersistInfo *upi)
/* perms reftbl ... udata */
} else {
size_t length;
- verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);
+ read_size(&upi->zio, &length);
lua_newuserdata(upi->L, length);
/* perms reftbl ... udata */
@@ -1611,8 +1985,8 @@ void pluto_unpersist(lua_State *L, lua_Chunkreader reader, void *ud)
}
typedef struct LoadInfo_t {
- char *buf;
- size_t size;
+ char *buf;
+ size_t size;
} LoadInfo;
@@ -1653,9 +2027,41 @@ int unpersist_l(lua_State *L)
return 1;
}
+/* Stefan's first C function for Lua! :)
+ Returns a string describing the Pluto version you're using. */
+
+int version_l(lua_State *L)
+{
+ const char *version = VERSION;
+
+ lua_settop(L, 0);
+ /* (empty) */
+ lua_pushlstring(L, version, strlen(version));
+ /* str */
+ return 1;
+}
+
+/* Set human-readable output on or off. */
+int human_l(lua_State *L)
+{
+ /* flag? ...? */
+ lua_settop(L, 1);
+ /* flag? */
+ /*luaL_checktype(L, 1, LUA_TBOOLEAN);*/
+ /* flag */
+
+ humanReadable = lua_toboolean(L, 1);
+
+ lua_settop(L, 0);
+ /* (empty) */
+ return 0;
+}
+
static luaL_reg pluto_reg[] = {
{ "persist", persist_l },
{ "unpersist", unpersist_l },
+ { "version", version_l },
+ { "human", human_l },
{ NULL, NULL }
};
diff --git a/engines/teenagent/callbacks.cpp b/engines/teenagent/callbacks.cpp
index 2de81abb37..3e6e40a8fa 100644
--- a/engines/teenagent/callbacks.cpp
+++ b/engines/teenagent/callbacks.cpp
@@ -294,7 +294,7 @@ bool TeenAgentEngine::fnRobotSafeAlreadyUnlockedCheck() {
}
void TeenAgentEngine::fnRobotSafeUnlockCheck() {
- if (CHECK_FLAG(dsAddr_MansionRobotSafeVoiceTestPassedFlag, 1) &&
+ if (CHECK_FLAG(dsAddr_MansionRobotSafeVoiceTestPassedFlag, 1) &&
CHECK_FLAG(dsAddr_MansionRobotSafeScentTestPassedFlag, 1) &&
CHECK_FLAG(dsAddr_MansionRobotSafeViewTestPassedFlag, 1)) {
waitLanAnimationFrame(1, 1);
@@ -546,7 +546,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
break;
case 0x4056:
- // FIXME - This is the bird use callback in the first act at
+ // FIXME - This is the bird use callback in the first act at
// the mudpool. Current Code based on behaviour. Need to analyse cseg data.
dialog->popMark(scene, dsAddr_dialogStackMudpoolBird);
break;
@@ -1603,7 +1603,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
break;
case 0x5b44:
- // FIXME - This is the doorbell use callback on House #2
+ // FIXME - This is the doorbell use callback on House #2
// i.e. Granny and Anne's House. Need to analyse cseg data properly.
// Current code inferred from behaviour.
// FIXME - Add animation call for Ego pushing doorbell.
diff --git a/engines/teenagent/dialog.cpp b/engines/teenagent/dialog.cpp
index 870aca6400..312757a462 100644
--- a/engines/teenagent/dialog.cpp
+++ b/engines/teenagent/dialog.cpp
@@ -28,7 +28,7 @@ namespace TeenAgent {
void Dialog::show(uint16 dialogNum, Scene *scene, uint16 animation1, uint16 animation2, byte color1, byte color2, byte slot1, byte slot2) {
uint16 addr = _vm->res->getDialogAddr(dialogNum);
- // WORKAROUND: For Dialog 163, The usage of this in the engine overlaps the previous dialog i.e. the
+ // WORKAROUND: For Dialog 163, The usage of this in the engine overlaps the previous dialog i.e. the
// starting offset used is two bytes early, thus implicitly changing the first command of this dialog
// from NEW_LINE to CHANGE_CHARACTER.
// FIXME: Unsure if this is correct behaviour or if this is a regression from the original. Check this.
diff --git a/engines/teenagent/font.cpp b/engines/teenagent/font.cpp
index 47f52ff90f..9d85328f20 100644
--- a/engines/teenagent/font.cpp
+++ b/engines/teenagent/font.cpp
@@ -65,7 +65,7 @@ uint Font::render(Graphics::Surface *surface, int x, int y, char c, byte color)
byte *glyph = _data + READ_LE_UINT16(_data + idx * 2);
int h = glyph[0], w = glyph[1];
- if (surface == NULL || surface->pixels == NULL || y + h <= 0 || y >= kScreenHeight || x + w <= 0 || x >= kScreenWidth)
+ if (surface == NULL || surface->getPixels() == NULL || y + h <= 0 || y >= kScreenHeight || x + w <= 0 || x >= kScreenWidth)
return w - _widthPack;
int i0 = 0, j0 = 0;
diff --git a/engines/teenagent/resources.cpp b/engines/teenagent/resources.cpp
index 442d0abf16..cdbdcf9655 100644
--- a/engines/teenagent/resources.cpp
+++ b/engines/teenagent/resources.cpp
@@ -160,7 +160,7 @@ void Resources::loadOff(Graphics::Surface &surface, byte *palette, int id) {
off.read(id, buf, bufferSize);
byte *src = buf;
- byte *dst = (byte *)surface.pixels;
+ byte *dst = (byte *)surface.getPixels();
memcpy(dst, src, 64000);
memcpy(palette, buf + 64000, 768);
@@ -206,16 +206,19 @@ Common::SeekableReadStream *Resources::loadLan000(uint32 id) const {
if (dseg.get_byte(dsAddr_birdOnBarRadioAntennaFlag) == 1) {
return lan500.getStream(380);
}
+ break;
case 30:
if (dseg.get_byte(dsAddr_birdOnBarRadioAntennaFlag) == 1) {
return lan500.getStream(381);
}
+ break;
case 42:
if (dseg.get_byte(dsAddr_johnNotyOutsideMansionDoorFlag) == 1) {
return lan500.getStream(400);
}
+ break;
}
return lan000.getStream(id);
}
diff --git a/engines/teenagent/scene.cpp b/engines/teenagent/scene.cpp
index bdeb11a841..f36a60932c 100644
--- a/engines/teenagent/scene.cpp
+++ b/engines/teenagent/scene.cpp
@@ -48,7 +48,6 @@ Scene::Scene(TeenAgentEngine *vm) : _vm(vm), intro(false), _id(0), ons(0),
onEnabled = true;
memset(palette, 0, sizeof(palette));
- background.pixels = 0;
FilePack varia;
varia.open("varia.res");
@@ -74,8 +73,7 @@ Scene::Scene(TeenAgentEngine *vm) : _vm(vm), intro(false), _id(0), ons(0),
}
Scene::~Scene() {
- if (background.pixels)
- background.free();
+ background.free();
delete[] ons;
ons = 0;
@@ -372,7 +370,7 @@ void Scene::init(int id, const Common::Point &pos) {
for (byte i = 0; i < 4; ++i)
customAnimation[i].free();
- if (background.pixels == NULL)
+ if (background.getPixels() == NULL)
background.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
warp(pos);
@@ -416,7 +414,7 @@ void Scene::init(int id, const Common::Point &pos) {
if (nowPlaying != _vm->res->dseg.get_byte(dsAddr_currentMusic))
_vm->music->load(_vm->res->dseg.get_byte(dsAddr_currentMusic));
- _vm->_system->copyRectToScreen(background.pixels, background.pitch, 0, 0, background.w, background.h);
+ _vm->_system->copyRectToScreen(background.getPixels(), background.pitch, 0, 0, background.w, background.h);
setPalette(0);
}
@@ -642,8 +640,8 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
return true;
}
- if (background.pixels && debugFeatures.feature[DebugFeatures::kShowBack]) {
- _vm->_system->copyRectToScreen(background.pixels, background.pitch, 0, 0, background.w, background.h);
+ if (background.getPixels() && debugFeatures.feature[DebugFeatures::kShowBack]) {
+ _vm->_system->copyRectToScreen(background.getPixels(), background.pitch, 0, 0, background.w, background.h);
} else
_vm->_system->fillScreen(0);
diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp
index 0b48a18b26..e73f1100d6 100644
--- a/engines/teenagent/teenagent.cpp
+++ b/engines/teenagent/teenagent.cpp
@@ -399,7 +399,7 @@ bool TeenAgentEngine::showLogo() {
return true;
}
- _system->copyRectToScreen(s.pixels, s.w, s.x, s.y, s.w, s.h);
+ _system->copyRectToScreen(s.getPixels(), s.w, s.x, s.y, s.w, s.h);
_system->updateScreen();
_system->delayMillis(100);
diff --git a/engines/testbed/config.cpp b/engines/testbed/config.cpp
index 6b56616c9b..a40d239ebf 100644
--- a/engines/testbed/config.cpp
+++ b/engines/testbed/config.cpp
@@ -213,22 +213,22 @@ void TestbedConfigManager::parseConfigFile() {
return;
}
_configFileInterface.loadFromStream(*rs);
- Common::ConfigFile::SectionList sections = _configFileInterface.getSections();
+ Common::INIFile::SectionList sections = _configFileInterface.getSections();
Testsuite *currTS = 0;
- for (Common::ConfigFile::SectionList::const_iterator i = sections.begin(); i != sections.end(); i++) {
+ for (Common::INIFile::SectionList::const_iterator i = sections.begin(); i != sections.end(); i++) {
if (i->name.equalsIgnoreCase("Global")) {
// Global params may be directly queried, ignore them
} else {
// A testsuite, process it.
currTS = getTestsuiteByName(i->name);
- Common::ConfigFile::SectionKeyList kList = i->getKeys();
+ Common::INIFile::SectionKeyList kList = i->getKeys();
if (!currTS) {
Testsuite::logPrintf("Warning! Error in config: Testsuite %s not found\n", i->name.c_str());
continue;
}
- for (Common::ConfigFile::SectionKeyList::const_iterator j = kList.begin(); j != kList.end(); j++) {
+ for (Common::INIFile::SectionKeyList::const_iterator j = kList.begin(); j != kList.end(); j++) {
if (j->key.equalsIgnoreCase("this")) {
currTS->enable(stringToBool(j->value));
} else {
diff --git a/engines/testbed/config.h b/engines/testbed/config.h
index fd5588aa31..d611ae4ec3 100644
--- a/engines/testbed/config.h
+++ b/engines/testbed/config.h
@@ -24,7 +24,7 @@
#include "common/array.h"
-#include "common/config-file.h"
+#include "common/ini-file.h"
#include "common/str-array.h"
#include "common/tokenizer.h"
@@ -62,7 +62,7 @@ public:
private:
Common::Array<Testsuite *> &_testsuiteList;
Common::String _configFileName;
- Common::ConfigFile _configFileInterface;
+ Common::INIFile _configFileInterface;
void parseConfigFile();
};
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 590e6c6d81..26e073d407 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -927,17 +927,29 @@ TestExitStatus GFXtests::overlayGraphics() {
Graphics::PixelFormat pf = g_system->getOverlayFormat();
- OverlayColor buffer[50 * 100];
- OverlayColor value = pf.RGBToColor(0, 255, 0);
+ byte *buffer = new byte[50 * 100 * pf.bytesPerPixel];
+ const uint32 value = pf.RGBToColor(0, 255, 0);
- for (int i = 0; i < 50 * 100; i++) {
- buffer[i] = value;
+ if (pf.bytesPerPixel == 2) {
+ uint16 *dst = (uint16 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else if (pf.bytesPerPixel == 4) {
+ uint32 *dst = (uint32 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else {
+ error("GFXtests::overlayGraphics: Unsupported color depth: %d", pf.bytesPerPixel);
}
g_system->showOverlay();
- g_system->copyRectToOverlay(buffer, 200, 270, 175, 100, 50);
+ g_system->copyRectToOverlay(buffer, 100 * pf.bytesPerPixel, 270, 175, 100, 50);
g_system->updateScreen();
+ delete[] buffer;
+
g_system->delayMillis(1000);
g_system->hideOverlay();
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index 106e1542d5..fa66b7ad8e 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -1031,7 +1031,7 @@ void BMVPlayer::CopyMovieToScreen() {
// The movie surface is slightly less high than the output screen (429 rows versus 432).
// Because of this, there's some extra line clearing above and below the displayed area
int yStart = (SCREEN_HEIGHT - SCREEN_HIGH) / 2;
- memset(_vm->screen().getBasePtr(0, 0), 0, yStart * SCREEN_WIDTH);
+ memset(_vm->screen().getPixels(), 0, yStart * SCREEN_WIDTH);
memcpy(_vm->screen().getBasePtr(0, yStart), ScreenBeg, SCREEN_WIDTH * SCREEN_HIGH);
memset(_vm->screen().getBasePtr(0, yStart + SCREEN_HIGH), 0,
(SCREEN_HEIGHT - SCREEN_HIGH - yStart) * SCREEN_WIDTH);
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index a945672da2..cc8166f295 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -478,6 +478,26 @@ static const TinselGameDescription gameDescriptions[] = {
},
#endif
+ { // Mac English CD, see tracker #3614864
+ {
+ "dw",
+ "CD",
+ {
+ {"dw.scn", 0, "114643df0d1f1530a0a9c5d4e38917bc", 1268553},
+ {"english.smp", 0, NULL, -1},
+ {NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_CD,
+ GUIO0()
+ },
+ GID_DW1,
+ 0,
+ GF_SCNFILES | GF_ENHANCED_AUDIO_SUPPORT,
+ TINSEL_V1,
+ },
+
{ // Mac multilanguage CD
{
"dw",
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index 5dae984def..c4f341f6fe 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -798,7 +798,7 @@ static void PackedWrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP,
*/
void ClearScreen() {
byte blackColorIndex = (!TinselV1Mac) ? 0 : 255;
- void *pDest = _vm->screen().getBasePtr(0, 0);
+ void *pDest = _vm->screen().getPixels();
memset(pDest, blackColorIndex, SCREEN_WIDTH * SCREEN_HEIGHT);
g_system->fillScreen(blackColorIndex);
g_system->updateScreen();
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 3921414b01..104adf72a2 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -300,7 +300,7 @@ void LoadFile(MEMHANDLE *pH) {
// discardable - unlock the memory
MemoryUnlock(pH->_node);
-
+
// set the loaded flag
pH->filesize |= fLoaded;
diff --git a/engines/tinsel/rince.cpp b/engines/tinsel/rince.cpp
index 3e6334f583..49666c13ca 100644
--- a/engines/tinsel/rince.cpp
+++ b/engines/tinsel/rince.cpp
@@ -808,7 +808,8 @@ void T2MoverProcess(CORO_PARAM, const void *param) {
PokeInPalette(pmi);
pMover->actorObj = MultiInitObject(pmi);
- pMover->actorID = pMover->actorID;
+ // FIXME: This is what the original did. A bug, perhaps?
+ // pMover->actorID = pMover->actorID;
pMover->bActive = true;
// add it to display list
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 17cb23b98f..43654fc3af 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -138,7 +138,7 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
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);
-
+
return &g_tempStruc;
}
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 9075e1adb1..5d410e62c7 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -868,9 +868,6 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
}
TinselEngine::~TinselEngine() {
- if (_bmv->MoviePlaying())
- _bmv->FinishBMV();
-
_system->getAudioCDManager()->stop();
delete _bmv;
delete _sound;
@@ -1007,6 +1004,9 @@ Common::Error TinselEngine::run() {
g_system->delayMillis(10);
}
+ if (_bmv->MoviePlaying())
+ _bmv->FinishBMV();
+
// Write configuration
_vm->_config->writeToDisk();
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index c5652f0c8d..380f4a3a26 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -73,6 +73,20 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
{
+ // 3 Skulls of the Toltecs English version (alternate)
+ // From bug #3614933
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "a9c9cfef9d05b8f7a5573b626fa4ea87", 337643527),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
// 3 Skulls of the Toltecs Russian version
{
"toltecs",
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index b52d7dad82..0850630c43 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -69,7 +69,7 @@ int MenuSystem::run(MenuID menuId) {
_vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000);
shadeRect(60, 39, 520, 247, 225, 229);
- memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
+ memcpy(_background->getPixels(), _vm->_screen->_frontScreen, 640 * 400);
while (_running) {
update();
@@ -229,7 +229,7 @@ void MenuSystem::initMenu(MenuID menuID) {
_items.clear();
- memcpy(_vm->_screen->_frontScreen, _background->pixels, 640 * 400);
+ memcpy(_vm->_screen->_frontScreen, _background->getPixels(), 640 * 400);
switch (menuID) {
case kMenuIdMain:
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 5e12773e1b..1eb2f41fd2 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -651,7 +651,7 @@ void Screen::drawSurface(int16 x, int16 y, Graphics::Surface *surface) {
int16 skipX = 0;
int16 width = surface->w;
int16 height = surface->h;
- byte *surfacePixels = (byte *)surface->getBasePtr(0, 0);
+ byte *surfacePixels = (byte *)surface->getPixels();
byte *frontScreen;
// Not on screen, skip
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index b06c0af675..fea40f3277 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -373,7 +373,7 @@ void SegmentMap::loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskR
maskRect.surface->create(maskRect.width, maskRect.height, Graphics::PixelFormat::createFormatCLUT8());
byte *backScreen = _vm->_screen->_backScreen + maskRect.x + (maskRect.y * _vm->_sceneWidth);
- byte *dest = (byte *)maskRect.surface->getBasePtr(0, 0);
+ byte *dest = (byte *)maskRect.surface->getPixels();
for (int16 h = 0; h < maskRect.height; h++) {
int16 w = maskRect.width;
diff --git a/engines/tony/detection.cpp b/engines/tony/detection.cpp
index 1094950e2c..d355450153 100644
--- a/engines/tony/detection.cpp
+++ b/engines/tony/detection.cpp
@@ -154,26 +154,16 @@ void TonyMetaEngine::removeSaveState(const char *target, int slot) const {
SaveStateDescriptor TonyMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String saveName;
byte difficulty;
- byte thumbData[160 * 120 * 2];
-
- if (Tony::RMOptionScreen::loadThumbnailFromSaveState(slot, thumbData, saveName, difficulty)) {
- // Convert the 565 thumbnail data to the needed overlay format
- Common::MemoryReadStream thumbStream(thumbData, 160 * 120 * 2);
- Graphics::PixelFormat destFormat = g_system->getOverlayFormat();
- Graphics::Surface *to = new Graphics::Surface();
- to->create(160, 120, destFormat);
-
- OverlayColor *pixels = (OverlayColor *)to->pixels;
- for (int y = 0; y < to->h; ++y) {
- for (int x = 0; x < to->w; ++x) {
- uint8 r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(thumbStream.readUint16LE(), r, g, b);
-
- // converting to current OSystem Color
- *pixels++ = destFormat.RGBToColor(r, g, b);
- }
- }
+ Graphics::Surface *to = new Graphics::Surface();
+ to->create(160, 120, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
+ if (Tony::RMOptionScreen::loadThumbnailFromSaveState(slot, (byte *)to->getPixels(), saveName, difficulty)) {
+#ifdef SCUMM_BIG_ENDIAN
+ uint16 *pixels = (uint16 *)to->getPixels();
+ for (int i = 0; i < to->w * to->h; ++i)
+ pixels[i] = READ_LE_UINT16(pixels + i);
+#endif
// Create the return descriptor
SaveStateDescriptor desc(slot, saveName);
desc.setDeletableFlag(true);
@@ -183,6 +173,7 @@ SaveStateDescriptor TonyMetaEngine::querySaveMetaInfos(const char *target, int s
return desc;
}
+ delete to;
return SaveStateDescriptor();
}
diff --git a/engines/tony/game.cpp b/engines/tony/game.cpp
index 501a588ff5..ca7c07ad8c 100644
--- a/engines/tony/game.cpp
+++ b/engines/tony/game.cpp
@@ -508,7 +508,8 @@ void RMOptionScreen::refreshThumbnails() {
_curThumb[i] = NULL;
_curThumbName[i].clear();
_curThumbDiff[i] = 11;
- }
+ } else
+ _curThumb[i]->prepareImage();
}
}
diff --git a/engines/tony/gfxcore.cpp b/engines/tony/gfxcore.cpp
index dc82c78ee5..410f9b8971 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -1865,7 +1865,7 @@ void RMGfxSourceBuffer8RLEWordAA::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RM
CORO_END_CODE;
}
-int RMGfxSourceBuffer8RLEWordAA::init(byte *buf, int dimx, int dimy, bool bLoadPalette) {
+int RMGfxSourceBuffer8RLEWordAA::init(const byte *buf, int dimx, int dimy, bool bLoadPalette) {
return RMGfxSourceBuffer8RLE::init(buf, dimx, dimy, bLoadPalette);
}
diff --git a/engines/tony/gfxcore.h b/engines/tony/gfxcore.h
index 1bacf7e5a9..9e8f5225c0 100644
--- a/engines/tony/gfxcore.h
+++ b/engines/tony/gfxcore.h
@@ -208,8 +208,10 @@ public:
* 16-bit color source
*/
class RMGfxSourceBuffer16 : public RMGfxSourceBuffer {
-protected:
+public:
virtual void prepareImage();
+
+protected:
bool _bTrasp0;
public:
@@ -408,7 +410,7 @@ public:
// Overloaded initialization methods
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
- virtual int init(byte *buf, int dimx, int dimy, bool bLoadPalette = false);
+ virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
virtual ~RMGfxSourceBuffer8RLEWordAA();
};
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index fff8676a89..5e6d44f0a3 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -2035,7 +2035,13 @@ int mpalGetSaveStateSize() {
void mpalSaveState(byte *buf) {
lockVar();
WRITE_LE_UINT32(buf, GLOBALS._nVars);
- memcpy(buf + 4, (byte *)GLOBALS._lpmvVars, GLOBALS._nVars * sizeof(MpalVar));
+ buf += 4;
+ for (uint i = 0; i < GLOBALS._nVars; ++i) {
+ LpMpalVar var = &GLOBALS._lpmvVars[i];
+ WRITE_LE_UINT32(buf, var->_dwVal);
+ memcpy(buf + 4, var->_lpszVarName, sizeof(var->_lpszVarName));
+ buf += (4 + sizeof(var->_lpszVarName));
+ }
unlockVar();
}
@@ -2050,10 +2056,16 @@ int mpalLoadState(byte *buf) {
globalFree(GLOBALS._hVars);
GLOBALS._nVars = READ_LE_UINT32(buf);
+ buf += 4;
GLOBALS._hVars = globalAllocate(GMEM_ZEROINIT | GMEM_MOVEABLE, GLOBALS._nVars * sizeof(MpalVar));
lockVar();
- memcpy((byte *)GLOBALS._lpmvVars, buf + 4, GLOBALS._nVars * sizeof(MpalVar));
+ for (uint i = 0; i < GLOBALS._nVars; ++i) {
+ LpMpalVar var = &GLOBALS._lpmvVars[i];
+ var->_dwVal = READ_LE_UINT32(buf);
+ memcpy(var->_lpszVarName, buf + 4, sizeof(var->_lpszVarName));
+ buf += (4 + sizeof(var->_lpszVarName));
+ }
unlockVar();
return GLOBALS._nVars * sizeof(MpalVar) + 4;
diff --git a/engines/tony/sound.cpp b/engines/tony/sound.cpp
index 90ae241db0..547f31906e 100644
--- a/engines/tony/sound.cpp
+++ b/engines/tony/sound.cpp
@@ -500,7 +500,13 @@ bool FPStream::loadFile(const Common::String &fileName, uint32 codec, int bufSiz
break;
case FPCODEC_ADPCM:
+#ifdef __amigaos4__
+ // HACK: AmigaOS 4 has weird performance problems with reading in the audio thread,
+ // so we read the whole stream into memory.
+ _rewindableStream = Audio::makeADPCMStream(_file.readStream(_size), DisposeAfterUse::YES, 0, Audio::kADPCMDVI, 44100, 2);
+#else
_rewindableStream = Audio::makeADPCMStream(&_file, DisposeAfterUse::NO, 0, Audio::kADPCMDVI, 44100, 2);
+#endif
break;
default:
diff --git a/engines/tony/window.cpp b/engines/tony/window.cpp
index 61497a8066..a732862854 100644
--- a/engines/tony/window.cpp
+++ b/engines/tony/window.cpp
@@ -330,6 +330,14 @@ void RMSnapshot::grabScreenshot(byte *lpBuf, int dezoom, uint16 *lpDestBuf) {
src += RM_BBX * dezoom;
}
}
+
+#ifdef SCUMM_BIG_ENDIAN
+ if (lpDestBuf != NULL) {
+ for (int i = 0; i < dimx * dimy; i++) {
+ lpDestBuf[i] = SWAP_BYTES_16(lpDestBuf[i]);
+ }
+ }
+#endif
}
} // End of namespace Tony
diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index a6744568f7..78d3954325 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -190,7 +190,7 @@ void Animation::drawFrame(Graphics::Surface &surface, int32 frame, int16 xx, int
int32 destPitch = surface.pitch;
uint8 *srcRow = _frames[frame]._data + offsX + (_frames[frame]._x2 - _frames[frame]._x1) * offsY;
- uint8 *curRow = (uint8 *)surface.pixels + (yy + _frames[frame]._y1 + _y1 + offsY) * destPitch + (xx + _x1 + _frames[frame]._x1 + offsX);
+ uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1 + offsX, yy + _frames[frame]._y1 + _y1 + offsY);
for (int16 y = 0; y < rectY; y++) {
uint8 *cur = curRow;
uint8 *c = srcRow + y * (_frames[frame]._x2 - _frames[frame]._x1);
@@ -231,7 +231,7 @@ void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 fram
int32 destPitch = surface.pitch;
int32 destPitchMask = mask->getWidth();
uint8 *c = _frames[frame]._data;
- uint8 *curRow = (uint8 *)surface.pixels;
+ uint8 *curRow = (uint8 *)surface.getPixels();
uint8 *curRowMask = mask->getDataPtr();
bool shadowFlag = false;
@@ -341,7 +341,7 @@ void Animation::drawFontFrame(Graphics::Surface &surface, int32 frame, int16 xx,
int32 destPitch = surface.pitch;
uint8 *c = _frames[frame]._data;
- uint8 *curRow = (uint8 *)surface.pixels + (yy + _frames[frame]._y1 + _y1) * destPitch + (xx + _x1 + _frames[frame]._x1);
+ uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1, yy + _frames[frame]._y1 + _y1);
for (int16 y = 0; y < rectY; y++) {
unsigned char *cur = curRow;
for (int16 x = 0; x < rectX; x++) {
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index 8c85e20f7c..f0463a52e1 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -112,7 +112,7 @@ bool Movie::playVideo(bool isFirstIntroVideo) {
}
_vm->_system->unlockScreen();
} else {
- _vm->_system->copyRectToScreen(frame->pixels, frame->pitch, 0, 0, frame->w, frame->h);
+ _vm->_system->copyRectToScreen(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
// WORKAROUND: There is an encoding glitch in the first intro video. This hides this using the adjacent pixels.
if (isFirstIntroVideo) {
diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp
index f59cdca064..65cc3a70e1 100644
--- a/engines/toon/picture.cpp
+++ b/engines/toon/picture.cpp
@@ -170,7 +170,7 @@ void Picture::drawMask(Graphics::Surface &surface, int16 x, int16 y, int16 dx, i
int32 destPitch = surface.pitch;
int32 srcPitch = _width;
uint8 *c = _data + _width * dy + dx;
- uint8 *curRow = (uint8 *)surface.pixels + y * destPitch + x;
+ uint8 *curRow = (uint8 *)surface.getBasePtr(x, y);
for (int16 yy = 0; yy < ry; yy++) {
uint8 *curSrc = c;
@@ -205,7 +205,7 @@ void Picture::drawWithRectList(Graphics::Surface& surface, int16 x, int16 y, int
int16 fillRy = MIN<int32>(ry, rect.bottom - rect.top);
uint8 *c = _data + _width * (dy + rect.top) + (dx + rect.left);
- uint8 *curRow = (uint8 *)surface.pixels + (y + rect.top) * destPitch + (x + rect.left);
+ uint8 *curRow = (uint8 *)surface.getBasePtr(x + rect.left, y + rect.top);
for (int16 yy = 0; yy < fillRy; yy++) {
uint8 *curSrc = c;
@@ -233,7 +233,7 @@ void Picture::draw(Graphics::Surface &surface, int16 x, int16 y, int16 dx, int16
int32 destPitch = surface.pitch;
int32 srcPitch = _width;
uint8 *c = _data + _width * dy + dx;
- uint8 *curRow = (uint8 *)surface.pixels + y * destPitch + x;
+ uint8 *curRow = (uint8 *)surface.getBasePtr(x, y);
for (int16 yy = 0; yy < ry; yy++) {
uint8 *curSrc = c;
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 7ad29ab8d8..286bcf1941 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -466,8 +466,7 @@ void ToonEngine::doMagnifierEffect() {
int32 cy = CLIP<int32>(posY + y, 0, TOON_BACKBUFFER_HEIGHT-1);
for (int32 x = -12; x <= 12; x++) {
int32 cx = CLIP<int32>(posX + x, 0, TOON_BACKBUFFER_WIDTH-1);
- int32 destPitch = surface.pitch;
- uint8 *curRow = (uint8 *)surface.pixels + cy * destPitch + cx;
+ uint8 *curRow = (uint8 *)surface.getBasePtr(cx, cy);
tempBuffer[(y + 12) * 25 + x + 12] = *curRow;
}
}
@@ -479,8 +478,7 @@ void ToonEngine::doMagnifierEffect() {
if (dist > 144)
continue;
int32 cx = CLIP<int32>(posX + x, 0, TOON_BACKBUFFER_WIDTH-1);
- int32 destPitch = surface.pitch;
- uint8 *curRow = (uint8 *)surface.pixels + cy * destPitch + cx;
+ uint8 *curRow = (uint8 *)surface.getBasePtr(cx, cy);
int32 lerp = (512 + intSqrt[dist] * 256 / 12);
*curRow = tempBuffer[(y * lerp / 1024 + 12) * 25 + x * lerp / 1024 + 12];
}
@@ -501,7 +499,7 @@ void ToonEngine::copyToVirtualScreen(bool updateScreen) {
if (_dirtyAll || _gameState->_currentScrollValue != lastScroll) {
// we have to refresh everything in case of scrolling.
- _system->copyRectToScreen((byte *)_mainSurface->pixels + state()->_currentScrollValue, TOON_BACKBUFFER_WIDTH, 0, 0, TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT);
+ _system->copyRectToScreen((byte *)_mainSurface->getPixels() + state()->_currentScrollValue, TOON_BACKBUFFER_WIDTH, 0, 0, TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT);
} else {
int32 offX = 0;
@@ -517,7 +515,7 @@ void ToonEngine::copyToVirtualScreen(bool updateScreen) {
}
rect.clip(TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT);
if (rect.left >= 0 && rect.top >= 0 && rect.right - rect.left > 0 && rect.bottom - rect.top > 0) {
- _system->copyRectToScreen((byte *)_mainSurface->pixels + _oldDirtyRects[i].left + offX + _oldDirtyRects[i].top * TOON_BACKBUFFER_WIDTH, TOON_BACKBUFFER_WIDTH, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ _system->copyRectToScreen((byte *)_mainSurface->getBasePtr(_oldDirtyRects[i].left + offX, _oldDirtyRects[i].top), TOON_BACKBUFFER_WIDTH, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
}
@@ -533,7 +531,7 @@ void ToonEngine::copyToVirtualScreen(bool updateScreen) {
}
rect.clip(TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT);
if (rect.left >= 0 && rect.top >= 0 && rect.right - rect.left > 0 && rect.bottom - rect.top > 0) {
- _system->copyRectToScreen((byte *)_mainSurface->pixels + _dirtyRects[i].left + offX + _dirtyRects[i].top * TOON_BACKBUFFER_WIDTH, TOON_BACKBUFFER_WIDTH, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ _system->copyRectToScreen((byte *)_mainSurface->getBasePtr(_dirtyRects[i].left + offX, _dirtyRects[i].top), TOON_BACKBUFFER_WIDTH, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
}
}
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 3aef18f4f0..63f84d25e1 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -678,7 +678,7 @@ void FocusObject::process(Event &event) {
BF_GLOBALS._events.setCursor(BF_GLOBALS._events.getCursor());
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (event.btnState == 3)) {
+ (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index 95598babc6..f1f00599e0 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -888,6 +888,7 @@ void Scene60::Action1::signal() {
break;
case 4:
remove();
+ break;
case 5:
setDelay(120);
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index 9f1e9ce36e..d26e34ae23 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -2649,7 +2649,7 @@ void Scene160::Action2::signal() {
}
void Scene160::Action2::process(Event &event) {
- if ((event.handled) || (event.eventType == 5))
+ if ((event.handled) || ((event.eventType != EVENT_BUTTON_DOWN) && (event.eventType != EVENT_KEYPRESS)))
return;
if (_actionIndex == 25) {
@@ -3237,7 +3237,7 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.disableControl();
- // Initialise objects
+ // Initialize objects
_door.postInit();
_door.setVisage(190);
_door.setStrip(1);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index abadc4300a..0cf487daa9 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -1220,7 +1220,7 @@ void Scene560::SafeInset::process(Event &event) {
}
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (event.btnState == 3)) {
+ (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
@@ -1459,7 +1459,7 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_lamp.setDetails(Rect(197, 43, 214, 56), 560, 7, 19, 30, 1, NULL);
_item4.setDetails(Rect(121, 18, 156, 54), 560, 8, 20, 31, 1, NULL);
_trophy.setDetails(Rect(259, 52, 275, 63), 560, 10, 22, 33, 1, NULL);
- _watercolours.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
+ _waterColors.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
_fileCabinets.setDetails(Rect(0, 47, 49, 100), 560, 14, 26, 37, 1, NULL);
_certificate.setDetails(Rect(280, 51, 292, 62), 560, 11, 23, 34, 1, NULL);
_bookcase.setDetails(Rect(176, 0, 319, 103), 560, 9, 21, 32, 1, NULL);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 73d323fc54..56bf20c93b 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -225,7 +225,7 @@ public:
NamedObject _object6;
PicturePart _picture1, _picture2, _picture3, _picture4;
Computer _computer;
- NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets;
+ NamedHotspot _chair, _lamp, _item4, _trophy, _waterColors, _fileCabinets;
NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office;
ASound _sound1;
bool _field380;
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index 5a60cd7c5e..9a20788b6a 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -1984,7 +1984,7 @@ void Scene840::BoatKeysInset::process(Event &event) {
CursorType cursorId = BF_GLOBALS._events.getCursor();
BF_GLOBALS._events.setCursor(cursorId);
- if ((event.eventType == EVENT_BUTTON_DOWN) && (cursorId == CURSOR_WALK) && (event.btnState == 3)) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (cursorId == CURSOR_WALK) && (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index de5ac62425..9828ca71d4 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -416,7 +416,7 @@ SequenceManager *SequenceManager::globalManager() {
ConversationChoiceDialog::ConversationChoiceDialog() {
_stdColor = 23;
_highlightColor = g_globals->_scenePalette._colors.background;
- _fontNumber = 1;
+ _fontNumber = (g_vm->getGameID() == GType_Ringworld2) ? 3 : 1;
_savedFgColor = _savedFontNumber = 0;
_selectedIndex = 0;
}
@@ -424,15 +424,15 @@ ConversationChoiceDialog::ConversationChoiceDialog() {
int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
_gfxManager._font.setFontNumber(_fontNumber);
- _bounds = Rect(20, 0, 20, 0);
+ _bounds = Rect(40, 0, 40, 0);
_choiceList.clear();
// Set up the list of choices
int yp = 0;
for (uint idx = 0; idx < choiceList.size(); ++idx) {
Rect tempRect;
- _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, 265);
- tempRect.moveTo(25, yp + 10);
+ _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, textMaxWidth());
+ tempRect.moveTo(textLeft(), yp + 10);
_choiceList.push_back(ChoiceEntry(choiceList[idx], tempRect));
yp += tempRect.height() + 5;
@@ -444,7 +444,8 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
_bounds.bottom -= 10;
yp = 180 - _bounds.height();
_bounds.translate(0, yp);
- _bounds.right = _bounds.left + 280;
+ _bounds.setWidth(textMaxWidth() + 15);
+ _bounds.moveTo(160 - (_bounds.width() / 2), _bounds.top);
// Draw the dialog
draw();
@@ -513,6 +514,7 @@ void ConversationChoiceDialog::draw() {
// Fill in the contents of the entire dialog
_gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+
drawFrame();
_gfxManager._bounds = tempRect;
@@ -524,7 +526,7 @@ void ConversationChoiceDialog::draw() {
Common::String strNum = Common::String::format("%d", idx + 1);
// Write the choice number
- _gfxManager._font.setPosition(13, _choiceList[idx]._bounds.top);
+ _gfxManager._font.setPosition(numberLeft(), _choiceList[idx]._bounds.top);
_gfxManager._font.writeString(strNum.c_str());
_gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT);
@@ -533,6 +535,18 @@ void ConversationChoiceDialog::draw() {
_gfxManager.deactivate();
}
+int ConversationChoiceDialog::textLeft() const {
+ return (g_vm->getGameID() == GType_Ringworld2) ? 20 : 25;
+}
+
+int ConversationChoiceDialog::textMaxWidth() const {
+ return (g_vm->getGameID() == GType_Ringworld2) ? 250 : 265;
+}
+
+int ConversationChoiceDialog::numberLeft() const {
+ return (g_vm->getGameID() == GType_Ringworld2) ? 8 : 13;
+}
+
/*--------------------------------------------------------------------------*/
void Obj44::load(const byte *dataP) {
@@ -542,8 +556,8 @@ void Obj44::load(const byte *dataP) {
_mode = s.readSint16LE();
_lookupValue = s.readSint16LE();
_lookupIndex = s.readSint16LE();
- _field6 = s.readSint16LE();
- _field8 = s.readSint16LE();
+ _exitMode = s.readSint16LE();
+ _speakerMode = s.readSint16LE();
}
_id = s.readSint16LE();
@@ -551,8 +565,8 @@ void Obj44::load(const byte *dataP) {
_callbackId[idx] = s.readSint16LE();
if (g_vm->getGameID() == GType_Ringworld2) {
- _field16 = s.readSint16LE();
- s.skip(20);
+ for (int i = 0; i < 11; ++i)
+ _field16[i] = s.readSint16LE();
} else {
s.skip(4);
}
@@ -578,9 +592,11 @@ void Obj44::synchronize(Serializer &s) {
s.syncAsSint16LE(_mode);
s.syncAsSint16LE(_lookupValue);
s.syncAsSint16LE(_lookupIndex);
- s.syncAsSint16LE(_field6);
- s.syncAsSint16LE(_field8);
- s.syncAsSint16LE(_field16);
+ s.syncAsSint16LE(_exitMode);
+ s.syncAsSint16LE(_speakerMode);
+
+ for (int i = 0; i < 11; ++i)
+ s.syncAsSint16LE(_field16[i]);
}
}
@@ -632,6 +648,7 @@ void StripManager::reset() {
_activeSpeaker = NULL;
_textShown = false;
_callbackObject = NULL;
+ _exitMode = 0;
_obj44List.clear();
if (!_script.empty()) {
@@ -679,6 +696,8 @@ void StripManager::synchronize(Serializer &s) {
s.syncAsByte(_textShown);
s.syncAsByte(_field2E6);
s.syncAsSint32LE(_field2E8);
+ if (g_vm->getGameID() == GType_Ringworld2)
+ s.syncAsSint16LE(_exitMode);
// Synchronize the item list
int arrSize = _obj44List.size();
@@ -688,7 +707,7 @@ void StripManager::synchronize(Serializer &s) {
for (int i = 0; i < arrSize; ++i)
_obj44List[i].synchronize(s);
- // Synhcronise script data
+ // Synchronize script data
int scriptSize = _script.size();
s.syncAsUint16LE(scriptSize);
if (s.isLoading())
@@ -708,14 +727,24 @@ void StripManager::synchronize(Serializer &s) {
}
void StripManager::remove() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ for (uint i = 0; i < _speakerList.size(); ++i) {
+ if (_activeSpeaker != _speakerList[i])
+ _speakerList[i]->proc16();
+ }
+ }
+
if (_textShown) {
if (_activeSpeaker)
_activeSpeaker->removeText();
_textShown = false;
}
- if (_activeSpeaker)
+ if (_activeSpeaker) {
+ if (g_vm->getGameID() == GType_Ringworld2)
+ static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->_speakerMode = 0xff;
_activeSpeaker->remove();
+ }
if (_sceneNumber != g_globals->_sceneManager._scene->_screenNumber) {
g_globals->_sceneManager._scene->_sceneBounds = _sceneBounds;
@@ -725,10 +754,15 @@ void StripManager::remove() {
if (_onEnd)
_onEnd();
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endHandler = NULL;
+
Action::remove();
}
void StripManager::signal() {
+ int strIndex = 0;
+
if (_textShown) {
_activeSpeaker->removeText();
_textShown = false;
@@ -760,12 +794,10 @@ void StripManager::signal() {
Obj44 &obj44 = _obj44List[_obj44Index];
- if (g_vm->getGameID() != GType_Ringworld2) {
- _field2E8 = obj44._id;
- } else {
+ if (g_vm->getGameID() == GType_Ringworld2) {
// Return to Ringworld specific handling
- if (obj44._field6)
- _field2E8 = obj44._field6;
+ if (obj44._exitMode)
+ _exitMode = obj44._exitMode;
switch (obj44._mode) {
case 1:
@@ -781,40 +813,91 @@ void StripManager::signal() {
break;
}
}
-
+
+ _field2E8 = obj44._id;
Common::StringArray choiceList;
// Build up a list of script entries
int idx;
+ bool delayFlag = false;
- if (g_vm->getGameID() == GType_Ringworld2 && obj44._field16) {
+ if ((g_vm->getGameID() == GType_Ringworld2) && obj44._field16[0]) {
// Special loading mode used in Return to Ringworld
for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
- int objIndex = _lookupList[obj44._field16 - 1];
-
- if (!obj44._list[objIndex]._id)
+ int f16Index = _lookupList[obj44._field16[0] - 1];
+ int entryId = obj44._field16[f16Index];
+
+ Obj0A &entry = obj44._list[idx];
+ if (entry._id == entryId) {
+ // Get the next one
+ choiceList.push_back((const char *)&_script[0] + entry._scriptOffset);
+ strIndex = idx;
+ delayFlag = true;
break;
-
- // Get the next one
- choiceList.push_back((const char *)&_script[0] + obj44._list[objIndex]._scriptOffset);
+ }
}
} else {
// Standard choices loading
- for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
+ for (idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) {
if (!obj44._list[idx]._id)
break;
// Get the next one
- choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ const char *choiceStr = (const char *)&_script[0] + obj44._list[idx]._scriptOffset;
+
+ if (!*choiceStr) {
+ // Choice is empty
+ assert(g_vm->getGameID() == GType_Ringworld2);
+
+ 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;
+
+ if (_obj44List[obj44Idx]._field16[0]) {
+ // WORKAROUND: The _lookupList isn't always correctly initialized. But it always
+ // 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];
+
+ if (_lookupList[_obj44List[obj44Idx]._field16[0] - 1]) {
+ int listIdx = 0;
+ while (_obj44List[obj44Idx]._list[listIdx]._id != listId)
+ ++listIdx;
+
+ choiceStr = (const char *)&_script[0] + _obj44List[obj44Idx]._list[listIdx]._scriptOffset;
+ } else {
+ for (int listIdx = idx; listIdx < (OBJ0A_LIST_SIZE - 1); ++listIdx) {
+ obj44._list[listIdx]._id = obj44._list[listIdx + 1]._id;
+ obj44._list[listIdx]._scriptOffset = obj44._list[listIdx + 1]._scriptOffset;
+
+ if (!obj44._list[listIdx + 1]._id)
+ obj44._list[listIdx]._id = 0;
+ }
+
+ --idx;
+ continue;
+ }
+ }
+ }
+ }
+
+ // Add entry to the list
+ choiceList.push_back(choiceStr);
}
}
- int strIndex = 0;
if (choiceList.size() > 1)
// Get the user to select a conversation option
strIndex = _choiceDialog.execute(choiceList);
- if ((choiceList.size() != 1) && !_field2E6)
+ if ((delayFlag || choiceList.size() != 1) && !_field2E6)
_delayFrames = 1;
else {
Speaker *speakerP = getSpeaker((const char *)&_script[0] + obj44._speakerOffset);
@@ -843,11 +926,28 @@ void StripManager::signal() {
}
}
- if ((g_vm->getGameID() == GType_Ringworld2) && (_obj44List.size() > 0))
- static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->proc15();
+ 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();
+ }
- _textShown = true;
- _activeSpeaker->setText(choiceList[strIndex]);
+ if (!choiceList[strIndex].empty()) {
+ _textShown = true;
+ _activeSpeaker->setText(choiceList[strIndex]);
+ } else if (!obj44._speakerMode) {
+ _delayFrames = 1;
+ } else {
+ _delayFrames = 0;
+ speaker->proc15();
+ }
+ } else {
+ _textShown = true;
+ _activeSpeaker->setText(choiceList[strIndex]);
+ }
}
_obj44Index = getNewIndex(obj44._list[strIndex]._id);
@@ -915,6 +1015,8 @@ Speaker *StripManager::getSpeaker(const char *speakerName) {
int StripManager::getNewIndex(int id) {
if (id == 10000)
return id;
+ if ((g_vm->getGameID() == GType_Ringworld2) && (id < 0))
+ return id;
for (uint idx = 0; idx < _obj44List.size(); ++idx) {
if (_obj44List[idx]._id == id) {
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index 0c4eb9539d..5aef0d8a7f 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -94,6 +94,7 @@ public:
virtual void proc12(Action *action);
virtual void setText(const Common::String &msg);
virtual void removeText();
+ virtual void proc16() {}
void setTextPos(const Common::Point &pt) { _textPos = pt; }
};
@@ -145,6 +146,10 @@ public:
};
class ConversationChoiceDialog : public ModalDialog {
+private:
+ int textLeft() const;
+ int textMaxWidth() const;
+ int numberLeft() const;
public:
int _stdColor;
int _highlightColor;
@@ -189,8 +194,9 @@ public:
// Return to Ringworld specific field
int _mode;
- int _lookupValue, _lookupIndex, _field6;
- int _field8, _field16;
+ int _lookupValue, _lookupIndex, _exitMode;
+ int _speakerMode;
+ int _field16[11];
public:
void load(const byte *dataP);
virtual void synchronize(Serializer &s);
@@ -217,6 +223,7 @@ public:
bool _textShown;
bool _field2E6;
int _field2E8;
+ int _exitMode;
Common::Array<Obj44> _obj44List;
Common::Array<byte> _script;
StripProc _onBegin;
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 1f3745d085..055005808c 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -1179,7 +1179,7 @@ void PaletteRotation::signal() {
int count = _end - _currIndex;
g_system->getPaletteManager()->setPalette((const byte *)&_palette[_currIndex * 3], _start, count);
- if (count2) {
+ if (count2 > 0) {
g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start + count, count2);
}
}
@@ -2111,8 +2111,13 @@ int SceneObject::getFrameCount() {
void SceneObject::animEnded() {
_animateMode = ANIM_MODE_NONE;
- if (_endAction)
- _endAction->signal();
+ if (_endAction) {
+ Action *endAction = _endAction;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endAction = NULL;
+
+ endAction->signal();
+ }
}
int SceneObject::changeFrame() {
@@ -2468,10 +2473,10 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
if (!OwnerList)
OwnerList = g_globals->_sceneObjects;
- if (!OwnerList->contains(this)) {
+ if (!OwnerList->contains(this) || ((_flags & OBJFLAG_REMOVE) != 0)) {
_percent = 100;
_priority = 255;
- _flags = 4;
+ _flags = OBJFLAG_ZOOMED;
_visage = 0;
_strip = 1;
_frame = 1;
@@ -2762,8 +2767,8 @@ void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum,
fixPriority(priority);
}
-void BackgroundSceneObject::proc27() {
- warning("STUB: BackgroundSceneObject::proc27()");
+void BackgroundSceneObject::copySceneToBackground() {
+ GLOBALS._sceneManager._scene->_backSurface.copyFrom(g_globals->gfxManager().getSurface(), 0, 0);
}
/*--------------------------------------------------------------------------*/
@@ -3216,7 +3221,7 @@ void Visage::flipVertical(GfxSurface &gfxSurface) {
// Flip the lines1
byte *line1P = (byte *)s.getBasePtr(0, y);
byte *line2P = (byte *)s.getBasePtr(0, s.h - y - 1);
-
+
for (int x = 0; x < s.w; ++x)
SWAP(line1P[x], line2P[x]);
}
@@ -3262,6 +3267,7 @@ void Player::postInit(SceneObjectList *OwnerList) {
_moveDiff.y = 2;
_effect = 1;
_shade = 0;
+ _linkedActor = NULL;
setObjectWrapper(new SceneObjectWrapper());
setPosition(_characterPos[_characterIndex]);
@@ -3992,7 +3998,7 @@ int WalkRegions::indexOf(const Common::Point &pt, const Common::List<int> *index
}
void WalkRegions::synchronize(Serializer &s) {
- // Synchronise the list of disabled regions as a list of values terminated with a '-1'
+ // Synchronize the list of disabled regions as a list of values terminated with a '-1'
int regionId = 0;
if (s.isLoading()) {
_disabledRegions.clear();
@@ -4242,9 +4248,10 @@ 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) {
- if ((*i)->contains(event.mousePos)) {
+ SceneItem *item = *i;
+ if (item->contains(event.mousePos)) {
// Pass the action to the item
- bool handled = (*i)->startAction(g_globals->_events.getCursor(), event);
+ bool handled = item->startAction(g_globals->_events.getCursor(), event);
if (!handled)
// Item wasn't handled, keep scanning
continue;
@@ -4291,10 +4298,15 @@ void SceneHandler::dispatch() {
GUIErrorMessage(SAVE_ERROR_MSG);
}
if (_loadGameSlot != -1) {
+ int priorSceneBeforeLoad = GLOBALS._sceneManager._previousScene;
+ int currentSceneBeforeLoad = GLOBALS._sceneManager._sceneNumber;
+
int loadSlot = _loadGameSlot;
_loadGameSlot = -1;
g_saver->restore(loadSlot);
g_globals->_events.setCursorFromFlag();
+
+ postLoad(priorSceneBeforeLoad, currentSceneBeforeLoad);
}
g_globals->_soundManager.dispatch();
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 655bd234e6..f7a5a43b16 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -613,7 +613,7 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void draw();
void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int32 arg10);
- void proc27();
+ static void copySceneToBackground();
};
class SceneText : public SceneObject {
@@ -900,6 +900,7 @@ public:
protected:
virtual void playerAction(Event &event) {}
virtual void processEnd(Event &event) {}
+ virtual void postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad) {}
public:
SceneHandler();
void registerHandler();
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
index 77ac0a25d7..43833f53b9 100644
--- a/engines/tsage/dialogs.cpp
+++ b/engines/tsage/dialogs.cpp
@@ -137,43 +137,47 @@ void ModalDialog::drawFrame() {
Rect origRect = _bounds;
_bounds.collapse(-10, -10);
- // Fill the dialog area
- g_globals->gfxManager().fillRect(origRect, 54);
-
- // Draw top line
- GfxSurface surface = surfaceFromRes(8, 1, 7);
- for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
- surface.draw(Common::Point(xp, _bounds.top));
- surface.draw(Common::Point(_bounds.right - 20, _bounds.top));
-
- surface = surfaceFromRes(8, 1, 1);
- surface.draw(Common::Point(_bounds.left, _bounds.top));
-
- surface = surfaceFromRes(8, 1, 4);
- surface.draw(Common::Point(_bounds.right - 10, _bounds.top));
-
- // Draw vertical edges
- surface = surfaceFromRes(8, 1, 2);
- for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
- surface.draw(Common::Point(_bounds.left, yp));
- surface.draw(Common::Point(_bounds.left, _bounds.bottom - 20));
-
- surface = surfaceFromRes(8, 1, 5);
- for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
- surface.draw(Common::Point(_bounds.right - 10, yp));
- surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 20));
-
- // Draw bottom line
- surface = surfaceFromRes(8, 1, 8);
- for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
- surface.draw(Common::Point(xp, _bounds.bottom - 10));
- surface.draw(Common::Point(_bounds.right - 20, _bounds.bottom - 10));
-
- surface = surfaceFromRes(8, 1, 3);
- surface.draw(Common::Point(_bounds.left, _bounds.bottom - 10));
-
- surface = surfaceFromRes(8, 1, 6);
- surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 10));
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ GfxElement::drawFrame();
+ } else {
+ // Fill the dialog area
+ g_globals->gfxManager().fillRect(origRect, 54);
+
+ // Draw top line
+ GfxSurface surface = surfaceFromRes(8, 1, 7);
+ for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
+ surface.draw(Common::Point(xp, _bounds.top));
+ surface.draw(Common::Point(_bounds.right - 20, _bounds.top));
+
+ surface = surfaceFromRes(8, 1, 1);
+ surface.draw(Common::Point(_bounds.left, _bounds.top));
+
+ surface = surfaceFromRes(8, 1, 4);
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.top));
+
+ // Draw vertical edges
+ surface = surfaceFromRes(8, 1, 2);
+ for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
+ surface.draw(Common::Point(_bounds.left, yp));
+ surface.draw(Common::Point(_bounds.left, _bounds.bottom - 20));
+
+ surface = surfaceFromRes(8, 1, 5);
+ for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
+ surface.draw(Common::Point(_bounds.right - 10, yp));
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 20));
+
+ // Draw bottom line
+ surface = surfaceFromRes(8, 1, 8);
+ for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
+ surface.draw(Common::Point(xp, _bounds.bottom - 10));
+ surface.draw(Common::Point(_bounds.right - 20, _bounds.bottom - 10));
+
+ surface = surfaceFromRes(8, 1, 3);
+ surface.draw(Common::Point(_bounds.left, _bounds.bottom - 10));
+
+ surface = surfaceFromRes(8, 1, 6);
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 10));
+ }
// Set the dialog's manager bounds
_gfxManager._bounds = origRect;
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 8f07a8243b..ac6ce0bf8e 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -113,7 +113,7 @@ bool EventsClass::getEvent(Event &evt, int eventMask) {
case Common::EVENT_RBUTTONUP:
case Common::EVENT_MBUTTONUP:
evt.eventType = EVENT_BUTTON_UP;
- evt.btnState = 0;
+ evt.btnState = BTNSHIFT_LEFT;
break;
case Common::EVENT_KEYDOWN:
evt.eventType = EVENT_KEYPRESS;
@@ -277,7 +277,7 @@ void EventsClass::setCursor(CursorType cursorType) {
GfxSurface s = surfaceFromRes(cursor);
Graphics::Surface surface = s.lockSurface();
- const byte *cursorData = (const byte *)surface.getBasePtr(0, 0);
+ const byte *cursorData = (const byte *)surface.getPixels();
CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
s.unlockSurface();
@@ -333,7 +333,7 @@ void EventsClass::pushCursor(CursorType cursorType) {
GfxSurface s = surfaceFromRes(cursor);
Graphics::Surface surface = s.lockSurface();
- const byte *cursorData = (const byte *)surface.getBasePtr(0, 0);
+ const byte *cursorData = (const byte *)surface.getPixels();
CursorMan.pushCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
s.unlockSurface();
@@ -346,7 +346,7 @@ void EventsClass::popCursor() {
}
void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Common::Point &hotspot, CursorType cursorId) {
- const byte *cursorData = (const byte *)cursor.getBasePtr(0, 0);
+ const byte *cursorData = (const byte *)cursor.getPixels();
CursorMan.replaceCursor(cursorData, cursor.w, cursor.h, hotspot.x, hotspot.y, transColor);
_currentCursor = cursorId;
@@ -355,7 +355,7 @@ void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Com
void EventsClass::setCursor(GfxSurface &cursor) {
Graphics::Surface s = cursor.lockSurface();
- const byte *cursorData = (const byte *)s.getBasePtr(0, 0);
+ const byte *cursorData = (const byte *)s.getPixels();
CursorMan.replaceCursor(cursorData, cursor.getBounds().width(), cursor.getBounds().height(),
cursor._centroid.x, cursor._centroid.y, cursor._transColor);
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 4589a926c9..d47634fed1 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/staticres.h"
namespace TsAGE {
@@ -366,31 +367,50 @@ bool BlueForceGlobals::removeFlag(int flagNum) {
namespace Ringworld2 {
+Ringworld2Globals::Ringworld2Globals() {
+ _scannerDialog = new ScannerDialog();
+}
+
+Ringworld2Globals::~Ringworld2Globals() {
+ delete _scannerDialog;
+}
+
void Ringworld2Globals::reset() {
Globals::reset();
+ if (!_scannerDialog)
+ _scannerDialog = new ScannerDialog();
+
+ // Default to Quinn as the active character
+ T2_GLOBALS._player._characterIndex = R2_QUINN;
+
// Reset the inventory
R2_INVENTORY.reset();
T2_GLOBALS._uiElements.updateInventory();
T2_GLOBALS._uiElements._active = false;
+ // Set the screen to track the player
+ _scrollFollower = &_player;
+
// Reset fields
- Common::fill(&_v1000[0], &_v1000[0x1000], 0);
- _v1000Flag = false;
+ Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[9][256], 0);
+ 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;
- _v565E1 = 0;
- _v565E3 = 0;
+ _electromagnetChangeAmount = 0;
+ _electromagnetZoom = 0;
_v565E5 = 0;
_v565E7 = 0;
_v565E9 = -5;
_v565EB = 26;
- _v565F5 = 0;
- _v565F6 = 0;
- _v565FA = 0;
+ _foodCount = 0;
+ _rimLocation = 0;
+ _rimTransportLocation = 0;
_v565AE = 0;
_v56605[0] = 0;
_v56605[1] = 3;
@@ -432,7 +452,7 @@ void Ringworld2Globals::reset() {
_v56613[(17 * 4) + 1] = 1;
_v566A6 = 3800;
- _v566A3 = 2;
+ _landerSuitNumber = 2;
_v566A4 = 1;
_v566A5 = 0;
_v566A8 = 5;
@@ -458,15 +478,12 @@ void Ringworld2Globals::reset() {
_v5780E = 0;
_v57810 = 0;
_v57C2C = 0;
- _v565EC[0] = 0;
- _v565EC[1] = 27;
- _v565EC[2] = 27;
- _v565EC[3] = 4;
- _v565EC[4] = 4;
- Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 1);
+ _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;
- _frameEdgeColour = 2;
+ _frameEdgeColor = 2;
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
_stripManager_lookupList[0] = 1;
_stripManager_lookupList[1] = 1;
@@ -479,6 +496,10 @@ void Ringworld2Globals::reset() {
_stripManager_lookupList[10] = 1;
_stripManager_lookupList[11] = 1;
+ // Reset junk/component data in scene 1550
+ Common::copy(&scene1550JunkLocationsDefault[0], &scene1550JunkLocationsDefault[508],
+ &_scene1550JunkLocations[0]);
+
// Reset fields stored in the player class
_player._characterIndex = R2_QUINN;
_player._characterScene[1] = 100;
@@ -496,16 +517,16 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v558C2);
s.syncAsSint16LE(_animationCtr);
s.syncAsSint16LE(_v5657C);
- s.syncAsSint16LE(_v565E1);
- s.syncAsSint16LE(_v565E3);
+ s.syncAsSint16LE(_electromagnetChangeAmount);
+ s.syncAsSint16LE(_electromagnetZoom);
s.syncAsSint16LE(_v565E5);
s.syncAsSint16LE(_v565E7);
s.syncAsSint16LE(_v565E9);
s.syncAsSint16LE(_v565EB);
- s.syncAsSint16LE(_v565F5);
- s.syncAsSint16LE(_v565F6);
- s.syncAsSint16LE(_v565FA);
- s.syncAsSint16LE(_v566A3);
+ s.syncAsSint16LE(_foodCount);
+ s.syncAsSint32LE(_rimLocation);
+ s.syncAsSint16LE(_rimTransportLocation);
+ s.syncAsSint16LE(_landerSuitNumber);
s.syncAsSint16LE(_v566A6);
s.syncAsSint16LE(_v56A93);
s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
@@ -521,11 +542,15 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v57C2C);
s.syncAsSint16LE(_speechSubtitles);
- for (i = 0; i < 5; i++)
- s.syncAsByte(_v565EC[i]);
+ byte temp;
+ s.syncAsByte(temp);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].x);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].x);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].y);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].y);
for (i = 0; i < MAX_CHARACTERS; ++i)
- s.syncAsByte(_v565F1[i]);
+ s.syncAsByte(_scannerFrequencies[i]);
s.syncAsByte(_v565AE);
s.syncAsByte(_v566A4);
@@ -548,7 +573,10 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsByte(_stripManager_lookupList[i]);
s.syncAsSint16LE(_insetUp);
- s.syncAsByte(_frameEdgeColour);
+ s.syncAsByte(_frameEdgeColor);
+
+ for (i = 0; i < 508; i += 4)
+ s.syncAsByte(_scene1550JunkLocations[i + 2]);
}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index d190b6a2a4..4512b34eb5 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -242,34 +242,31 @@ namespace Ringworld2 {
#define SPEECH_TEXT 1
#define SPEECH_VOICE 2
-#define k5A78C 15
-#define k5A78D 16
-#define k5A790 18
-#define k5A791 17
+class ScannerDialog;
class Ringworld2Globals: public TsAGE2Globals {
public:
ASoundExt _sound1, _sound2, _sound3, _sound4;
PlayStream _playStream;
StripProxy _stripProxy;
- bool _v1000Flag;
- byte _v1000[0x1000];
- byte _palIndexList[10][256];
+ bool _fadePaletteFlag;
+ byte _fadePaletteMap[10][256];
+ byte _paletteMap[4096];
int _insetUp;
- int _frameEdgeColour; // _v421e
+ int _frameEdgeColor; // _v421e
Rect _v5589E;
Rect _v558B6;
int _v558C2;
int _animationCtr;
- int _v565E1;
- int _v565E3;
+ int _electromagnetChangeAmount;
+ int _electromagnetZoom;
int _v565E5;
int _v565E7;
int _v565E9;
int _v565EB;
- int _v565F5;
- int _v565F6;
- int _v565FA;
+ int _foodCount;
+ int _rimLocation;
+ int _rimTransportLocation;
int _v5657C;
byte _v565AE;
byte _v56605[14];
@@ -277,7 +274,7 @@ public:
byte _v566A4;
byte _v566A5;
int _v566A6;
- byte _v566A3;
+ byte _landerSuitNumber;
byte _v566A8;
byte _v566A9;
byte _v566AA;
@@ -301,10 +298,14 @@ public:
int _v57810;
int _v57C2C;
int _speechSubtitles;
- byte _v565EC[5];
- byte _v565F1[4];
+ Common::Point _s1550PlayerArea[3]; // only used for Quinn and Seeker
+ byte _scannerFrequencies[4];
byte _stripManager_lookupList[12];
+ byte _scene1550JunkLocations[508];
+ ScannerDialog *_scannerDialog;
+ Ringworld2Globals();
+ virtual ~Ringworld2Globals();
virtual void reset();
virtual void synchronize(Serializer &s);
};
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index af6e6f9b13..2395cc67ed 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -47,7 +47,7 @@ GfxSurface *surfaceGetArea(GfxSurface &src, const Rect &bounds) {
Graphics::Surface destSurface = dest->lockSurface();
byte *srcP = (byte *)srcSurface.getBasePtr(bounds.left, bounds.top);
- byte *destP = (byte *)destSurface.getBasePtr(0, 0);
+ byte *destP = (byte *)destSurface.getPixels();
for (int y = bounds.top; y < bounds.bottom; ++y, srcP += srcSurface.pitch, destP += destSurface.pitch)
Common::copy(srcP, srcP + destSurface.pitch, destP);
@@ -76,7 +76,7 @@ GfxSurface surfaceFromRes(const byte *imgData) {
const byte *srcP = imgData + 10;
Graphics::Surface destSurface = s.lockSurface();
- byte *destP = (byte *)destSurface.getBasePtr(0, 0);
+ byte *destP = (byte *)destSurface.getPixels();
if (!rleEncoded) {
Common::copy(srcP, srcP + (r.width() * r.height()), destP);
@@ -242,7 +242,7 @@ void GfxSurface::clear() {
_customSurface->free();
delete _customSurface;
_customSurface = NULL;
- }
+ }
}
/**
@@ -294,8 +294,11 @@ void GfxSurface::addDirtyRect(const Rect &r) {
r2.translate(_bounds.left, _bounds.top);
// Add to the dirty rect list
- _dirtyRects.push_back(Rect(r2.left, r2.top,
- MIN(r2.right + 1, SCREEN_WIDTH), MIN(r2.bottom + 1, SCREEN_HEIGHT)));
+ r2.right = MIN(r2.right + 1, SCREEN_WIDTH);
+ r2.bottom = MIN(r2.bottom + 1, SCREEN_HEIGHT);
+
+ if (r2.isValidRect())
+ _dirtyRects.push_back(r2);
}
}
@@ -313,7 +316,7 @@ void GfxSurface::create(int width, int height) {
}
_customSurface = new Graphics::Surface();
_customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- Common::fill((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0);
+ Common::fill((byte *)_customSurface->getPixels(), (byte *)_customSurface->getBasePtr(0, height), 0);
_bounds = Rect(0, 0, width, height);
}
@@ -329,12 +332,7 @@ Graphics::Surface GfxSurface::lockSurface() {
// Setup the returned surface either as one pointing to the same pixels as the source, or
// as a subset of the source one based on the currently set bounds
Graphics::Surface result;
- result.w = _bounds.width();
- result.h = _bounds.height();
- result.pitch = src->pitch;
- result.format = src->format;
- result.pixels = src->getBasePtr(_bounds.left, _bounds.top);
-
+ result.init(_bounds.width(), _bounds.height(), src->pitch, src->getBasePtr(_bounds.left, _bounds.top), src->format);
return result;
}
@@ -360,7 +358,7 @@ void GfxSurface::synchronize(Serializer &s) {
if (_customSurface) {
s.syncAsSint16LE(_customSurface->w);
s.syncAsSint16LE(_customSurface->h);
- s.syncBytes((byte *)_customSurface->pixels, _customSurface->w * _customSurface->h);
+ s.syncBytes((byte *)_customSurface->getPixels(), _customSurface->w * _customSurface->h);
} else {
int zero = 0;
s.syncAsSint16LE(zero);
@@ -377,7 +375,7 @@ void GfxSurface::synchronize(Serializer &s) {
_customSurface = NULL;
} else {
create(w, h);
- s.syncBytes((byte *)_customSurface->pixels, w * h);
+ s.syncBytes((byte *)_customSurface->getPixels(), w * h);
}
}
}
@@ -414,8 +412,8 @@ GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
// Surface owns the internal data, so replicate it so new surface owns it's own
_customSurface = new Graphics::Surface();
_customSurface->create(s._customSurface->w, s._customSurface->h, Graphics::PixelFormat::createFormatCLUT8());
- const byte *srcP = (const byte *)s._customSurface->getBasePtr(0, 0);
- byte *destP = (byte *)_customSurface->getBasePtr(0, 0);
+ const byte *srcP = (const byte *)s._customSurface->getPixels();
+ byte *destP = (byte *)_customSurface->getPixels();
Common::copy(srcP, srcP + (_bounds.width() * _bounds.height()), destP);
}
@@ -578,7 +576,7 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
Graphics::Surface destSurface = srcImage.lockSurface();
const byte *srcP = (const byte *)srcSurface.getBasePtr(srcBounds.left, srcBounds.top);
- byte *destP = (byte *)destSurface.pixels;
+ byte *destP = (byte *)destSurface.getPixels();
for (int yp = srcBounds.top; yp < srcBounds.bottom; ++yp, srcP += srcSurface.pitch, destP += destSurface.pitch) {
Common::copy(srcP, srcP + srcBounds.width(), destP);
}
@@ -795,35 +793,58 @@ void GfxElement::drawFrame() {
lineP++;
}
}
+
+ // 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.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;
+ *((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.top + 1)) = 0;
+ *((byte *)surface.getBasePtr(tempRect.left + 1, tempRect.bottom - 1)) = 0;
+ *((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.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;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
+
gfxManager.unlockSurface();
+ gfxManager.getSurface().addDirtyRect(tempRect);
} else {
- // Fill dialog content with specified background colour
+ // Fill dialog content with specified background color
gfxManager.fillRect(tempRect, _colors.background);
- }
- --tempRect.bottom; --tempRect.right;
- gfxManager.fillArea(tempRect.left, tempRect.top, bgColor);
- gfxManager.fillArea(tempRect.left, tempRect.bottom, fgColor);
- gfxManager.fillArea(tempRect.right, tempRect.top, fgColor);
- gfxManager.fillArea(tempRect.right, tempRect.bottom, fgColor);
-
- tempRect.collapse(-1, -1);
- gfxManager.fillRect2(tempRect.left + 1, tempRect.top, tempRect.width() - 1, 1, bgColor);
- gfxManager.fillRect2(tempRect.left, tempRect.top + 1, 1, tempRect.height() - 1, bgColor);
- gfxManager.fillRect2(tempRect.left + 1, tempRect.bottom, tempRect.width() - 1, 1, fgColor);
- gfxManager.fillRect2(tempRect.right, tempRect.top + 1, 1, tempRect.height() - 1, fgColor);
-
- gfxManager.fillArea(tempRect.left, tempRect.top, 0);
- gfxManager.fillArea(tempRect.left, tempRect.bottom, 0);
- gfxManager.fillArea(tempRect.right, tempRect.top, 0);
- gfxManager.fillArea(tempRect.right, tempRect.bottom, 0);
-
- tempRect.collapse(-1, -1);
- gfxManager.fillRect2(tempRect.left + 2, tempRect.top, tempRect.width() - 3, 1, 0);
- gfxManager.fillRect2(tempRect.left, tempRect.top + 2, 1, tempRect.height() - 3, 0);
- gfxManager.fillRect2(tempRect.left + 2, tempRect.bottom, tempRect.width() - 3, 1, 0);
- gfxManager.fillRect2(tempRect.right, tempRect.top + 2, 1, tempRect.height() - 3, 0);
+ --tempRect.bottom; --tempRect.right;
+ gfxManager.fillArea(tempRect.left, tempRect.top, bgColor);
+ gfxManager.fillArea(tempRect.left, tempRect.bottom, fgColor);
+ gfxManager.fillArea(tempRect.right, tempRect.top, fgColor);
+ gfxManager.fillArea(tempRect.right, tempRect.bottom, fgColor);
+
+ tempRect.collapse(-1, -1);
+ gfxManager.fillRect2(tempRect.left + 1, tempRect.top, tempRect.width() - 1, 1, bgColor);
+ gfxManager.fillRect2(tempRect.left, tempRect.top + 1, 1, tempRect.height() - 1, bgColor);
+ gfxManager.fillRect2(tempRect.left + 1, tempRect.bottom, tempRect.width() - 1, 1, fgColor);
+ gfxManager.fillRect2(tempRect.right, tempRect.top + 1, 1, tempRect.height() - 1, fgColor);
+
+ gfxManager.fillArea(tempRect.left, tempRect.top, 0);
+ gfxManager.fillArea(tempRect.left, tempRect.bottom, 0);
+ gfxManager.fillArea(tempRect.right, tempRect.top, 0);
+ gfxManager.fillArea(tempRect.right, tempRect.bottom, 0);
+
+ tempRect.collapse(-1, -1);
+ gfxManager.fillRect2(tempRect.left + 2, tempRect.top, tempRect.width() - 3, 1, 0);
+ gfxManager.fillRect2(tempRect.left, tempRect.top + 2, 1, tempRect.height() - 3, 0);
+ gfxManager.fillRect2(tempRect.left + 2, tempRect.bottom, tempRect.width() - 3, 1, 0);
+ gfxManager.fillRect2(tempRect.right, tempRect.top + 2, 1, tempRect.height() - 3, 0);
+ }
gfxManager.unlockSurface();
}
diff --git a/engines/tsage/ringworld/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp
index 4d9d565705..89c07273fc 100644
--- a/engines/tsage/ringworld/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes1.cpp
@@ -2273,6 +2273,7 @@ void Scene60::Item1::doAction(int action) {
} else {
scene->setAction(&scene->_action2);
}
+ break;
default:
SceneHotspot::doAction(action);
break;
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 478fdcf5a5..e2afa574de 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -234,9 +234,9 @@ void CharacterDialog::show() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
scene->saveCharacter(oldCharacter);
- // Play a transition sound as the character is changed
+ // Play the correctfrequency, if any, of the character being switched to's scanner device
if (R2_GLOBALS._player._characterScene[0] != 300) {
- switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
R2_GLOBALS._sound4.stop();
break;
@@ -255,8 +255,8 @@ void CharacterDialog::show() {
default:
break;
}
- } else if (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex] > 1) {
- switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) {
+ } else if (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] > 1) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -272,8 +272,8 @@ void CharacterDialog::show() {
default:
break;
}
- } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._v565F1[1] != 1)) {
- switch (R2_GLOBALS._v565F1[1]) {
+ } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -291,10 +291,10 @@ void CharacterDialog::show() {
}
} else if (R2_GLOBALS._player._characterScene[2] != 300) {
R2_GLOBALS._sound4.stop();
- } else if (R2_GLOBALS._v565F1[2] == 1) {
+ } else if (R2_GLOBALS._scannerFrequencies[2] == 1) {
R2_GLOBALS._sound4.stop();
} else {
- switch (R2_GLOBALS._v565F1[1]) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index ebb09a7e08..c0fc2eb766 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -88,8 +88,10 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Walking in hall
return new Scene525();
case 600:
+ // Drive Room
return new Scene600();
case 700:
+ // Lander Bay 2
return new Scene700();
case 800:
// Sick bay
@@ -101,11 +103,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Deck #5 - By Lift
return new Scene850();
case 900:
+ // Lander Bay 2 - Crane Controls
return new Scene900();
/* Scene group #1 */
//
case 1000:
- error("Missing scene %d from group 1", sceneNumber);
+ // Cutscene scene
+ return new Scene1000();
case 1010:
// Cutscene - trip in space
return new Scene1010();
@@ -129,6 +133,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Elevator
return new Scene1530();
case 1550:
+ // Spaceport
return new Scene1550();
case 1575:
return new Scene1575();
@@ -139,10 +144,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Miranda being questioned
return new Scene1625();
case 1700:
+ // Rim
return new Scene1700();
case 1750:
+ // Rim Transport Vechile
return new Scene1750();
case 1800:
+ // Rim Lift Exterior
return new Scene1800();
case 1850:
return new Scene1850();
@@ -314,11 +322,23 @@ SceneExt::SceneExt(): Scene() {
for (int i = 0; i < 256; i++)
_field312[i] = 0;
- _field372 = _field37A = 0;
+
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
- _focusObject = NULL;
+
+ // WORKAROUND: In the original, playing animations don't reset the global _animationCtr
+ // counter as scene changes unless the playing animation explicitly finishes. For now,
+ // to make inter-scene debugging easier, I'm explicitly resetting the _animationCtr
+ // on scene start, since scene objects aren't drawn while it's non-zero
+ R2_GLOBALS._animationCtr = 0;
+}
+
+void SceneExt::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+
+ s.syncBytes(&_field312[0], 256);
+ _sceneAreas.synchronize(s);
}
void SceneExt::postInit(SceneObjectList *OwnerList) {
@@ -327,7 +347,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
// Exclude the bottom area of the screen to allow room for the UI
T2_GLOBALS._interfaceY = UI_INTERFACE_Y;
- // Initialise fields
+ // Initialize fields
_action = NULL;
_field12 = 0;
_sceneMode = 0;
@@ -336,8 +356,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
|| (sceneNumber == 50)
- || ((prevScene == 205) && (sceneNumber == 100))
- || ((prevScene == 180) && (sceneNumber == 100))) {
+ || ((sceneNumber == 100) && (prevScene == 0 || prevScene == 180 || prevScene == 205))) {
static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
R2_GLOBALS._uiElements._active = true;
R2_GLOBALS._uiElements.show();
@@ -349,6 +368,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
void SceneExt::remove() {
_sceneAreas.clear();
Scene::remove();
+ R2_GLOBALS._uiElements._active = true;
}
void SceneExt::process(Event &event) {
@@ -373,27 +393,6 @@ void SceneExt::dispatch() {
Scene::dispatch();
}
-void SceneExt::loadScene(int sceneNum) {
- Scene::loadScene(sceneNum);
-
- _v51C34.top = 0;
- _v51C34.bottom = 300;
-
- int prevScene = R2_GLOBALS._sceneManager._previousScene;
- int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
-
- if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50)) ||
- (sceneNumber == 50) || ((prevScene == 205) && (sceneNumber == 100)) ||
- ((prevScene == 180) && (sceneNumber == 100))) {
- // TODO: sub_17875
- R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._uiElements.show();
- } else {
- // Update the user interface
- R2_GLOBALS._uiElements.updateInventory();
- }
-}
-
bool SceneExt::display(CursorType action, Event &event) {
switch (action) {
case CURSOR_CROSSHAIRS:
@@ -415,17 +414,19 @@ bool SceneExt::display(CursorType action, Event &event) {
SceneItem::display2(5, 0);
break;
case R2_SONIC_STUNNER:
- if ((R2_GLOBALS._v565F1[1] == 2) || ((R2_GLOBALS._v565F1[1] == 1) &&
- (R2_GLOBALS._v565F1[2] == 2) && (R2_GLOBALS._sceneManager._previousScene == 300))) {
+ if ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 2)
+ || ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 1) &&
+ (R2_GLOBALS._scannerFrequencies[R2_SEEKER] == 2) &&
+ (R2_GLOBALS._sceneManager._previousScene == 300))) {
R2_GLOBALS._sound4.stop();
R2_GLOBALS._sound3.play(46);
SceneItem::display2(5, 15);
+
+ R2_GLOBALS._sound4.play(45);
} else {
R2_GLOBALS._sound3.play(43, 0);
- SceneItem::display2(2, 0);
+ SceneItem::display2(2, R2_SONIC_STUNNER);
}
-
- R2_GLOBALS._sound4.play(45);
break;
case R2_COM_SCANNER:
case R2_COM_SCANNER_2:
@@ -453,7 +454,6 @@ void SceneExt::fadeOut() {
void SceneExt::startStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 1;
scene->_savedPlayerEnabled = R2_GLOBALS._player._enabled;
if (scene->_savedPlayerEnabled) {
@@ -469,7 +469,6 @@ void SceneExt::startStrip() {
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
R2_GLOBALS._player.enableControl();
@@ -517,7 +516,7 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) {
assert(screenSize == (s.w * s.h));
// Copy the data
- byte *destP = (byte *)s.getBasePtr(0, 0);
+ byte *destP = (byte *)s.getPixels();
Common::copy(dataP, dataP + (s.w * s.h), destP);
_backSurface.unlockSurface();
@@ -565,6 +564,13 @@ void SceneExt::scalePalette(int RFactor, int GFactor, int BFactor) {
}
}
+void SceneExt::loadBlankScene() {
+ _backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2);
+ _backSurface.fillRect(_backSurface.getBounds(), 0);
+
+ R2_GLOBALS._screenSurface.fillRect(R2_GLOBALS._screenSurface.getBounds(), 0);
+}
+
/*--------------------------------------------------------------------------*/
void SceneHandlerExt::postInit(SceneObjectList *OwnerList) {
@@ -581,7 +587,7 @@ void SceneHandlerExt::process(Event &event) {
SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene);
if (scene && R2_GLOBALS._player._uiEnabled) {
// Handle any scene areas that have been registered
- SynchronizedList<SceneArea *>::iterator saIter;
+ SynchronizedList<EventHandler *>::iterator saIter;
for (saIter = scene->_sceneAreas.begin(); saIter != scene->_sceneAreas.end() && !event.handled; ++saIter) {
(*saIter)->process(event);
}
@@ -591,11 +597,32 @@ void SceneHandlerExt::process(Event &event) {
SceneHandler::process(event);
}
+void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad) {
+ if (priorSceneBeforeLoad == -1 || priorSceneBeforeLoad == 50
+ || priorSceneBeforeLoad == 180 || priorSceneBeforeLoad == 205)
+ setupPaletteMaps();
+
+ if (currentSceneBeforeLoad == 2900) {
+ R2_GLOBALS._gfxFontNumber = 50;
+ R2_GLOBALS._gfxColors.background = 0;
+ R2_GLOBALS._gfxColors.foreground = 59;
+ R2_GLOBALS._fontColors.background = 4;
+ R2_GLOBALS._fontColors.foreground = 15;
+ R2_GLOBALS._frameEdgeColor = 2;
+
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 0xff, 0xff, 0xff);
+ R2_GLOBALS._fadePaletteFlag = false;
+ setupPaletteMaps();
+ }
+}
+
void SceneHandlerExt::setupPaletteMaps() {
byte *palP = &R2_GLOBALS._scenePalette._palette[0];
- if (!R2_GLOBALS._v1000Flag) {
- R2_GLOBALS._v1000Flag = true;
+ // Set up the mapping table for giving faded versions of pixels at different fade percentages
+ if (!R2_GLOBALS._fadePaletteFlag) {
+ R2_GLOBALS._fadePaletteFlag = true;
for (int idx = 0; idx < 10; ++idx) {
for (int palIndex = 0; palIndex < 224; ++palIndex) {
@@ -625,7 +652,7 @@ void SceneHandlerExt::setupPaletteMaps() {
break;
}
- // Scan for the palette index with the closest matching colour
+ // Scan for the palette index with the closest matching color
int threshold = 769;
int foundIndex = -1;
for (int pIndex2 = 223; pIndex2 >= 0; --pIndex2) {
@@ -645,18 +672,19 @@ void SceneHandlerExt::setupPaletteMaps() {
foundIndex = pIndex2;
}
- R2_GLOBALS._palIndexList[idx][palIndex] = foundIndex;
+ R2_GLOBALS._fadePaletteMap[idx][palIndex] = foundIndex;
}
}
}
for (int palIndex = 0; palIndex < 224; ++palIndex) {
- int r = palP[palIndex * 3] >> 2;
- int g = palP[palIndex * 3 + 1] >> 2;
- int b = palP[palIndex * 3 + 2] >> 2;
+ int r = palP[palIndex * 3] >> 4;
+ int g = palP[palIndex * 3 + 1] >> 4;
+ int b = palP[palIndex * 3 + 2] >> 4;
- int idx = (((r << 4) | g) << 4) | b;
- R2_GLOBALS._v1000[idx] = palIndex;
+ int v = (r << 8) | (g << 4) | b;
+ assert(v < 0x1000);
+ R2_GLOBALS._paletteMap[v] = palIndex;
}
int vdx = 0;
@@ -664,9 +692,9 @@ void SceneHandlerExt::setupPaletteMaps() {
int palIndex = 224;
for (int vIndex = 0; vIndex < 4096; ++vIndex) {
- int v = R2_GLOBALS._v1000[vIndex];
+ int v = R2_GLOBALS._paletteMap[vIndex];
if (!v) {
- R2_GLOBALS._v1000[vIndex] = idx;
+ R2_GLOBALS._paletteMap[vIndex] = idx;
} else {
idx = v;
}
@@ -850,6 +878,7 @@ Ringworld2InvObjectList::Ringworld2InvObjectList():
_itemList.push_back(&_inv52);
_selectedItem = NULL;
+
}
void Ringworld2InvObjectList::reset() {
@@ -912,6 +941,9 @@ void Ringworld2InvObjectList::reset() {
setObjectScene(R2_ALCOHOL_LAMP_3, 2435);
setObjectScene(R2_BROKEN_DISPLAY, 1580);
setObjectScene(R2_TOOLBOX, 3260);
+
+ // Set up the select item handler method
+ T2_GLOBALS._onSelectItem = SelectItem;
}
void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
@@ -926,7 +958,129 @@ void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
// Update the user interface if necessary
- T2_GLOBALS._uiElements.updateInventory();
+ T2_GLOBALS._uiElements.updateInventory(
+ (sceneNumber == R2_GLOBALS._player._characterIndex) ? objectNum : 0);
+}
+
+/**
+ * When an inventory item is selected, in Return to Ringworld two objects can be combined
+ */
+bool Ringworld2InvObjectList::SelectItem(int objectNumber) {
+ // If no existing item selected, don't go any further
+ int currentItem = R2_GLOBALS._events.getCursor();
+ if (currentItem >= 256)
+ return false;
+
+ switch (objectNumber) {
+ case R2_NEGATOR_GUN:
+ switch (currentItem) {
+ case R2_SENSOR_PROBE:
+ if (R2_GLOBALS.getFlag(1))
+ SceneItem::display2(5, 1);
+ else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) != 100)
+ SceneItem::display2(5, 3);
+ else {
+ R2_GLOBALS._sound3.play(48);
+ SceneItem::display2(5, 2);
+ R2_INVENTORY.setObjectScene(R2_SPENT_POWER_CAPSULE, 1);
+ }
+ break;
+ case R2_COM_SCANNER:
+ R2_GLOBALS._sound3.play(44);
+ if (R2_GLOBALS.getFlag(1))
+ SceneItem::display2(5, 9);
+ else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 100)
+ SceneItem::display2(5, 8);
+ else
+ SceneItem::display2(5, 10);
+
+ R2_GLOBALS._sound3.stop();
+ break;
+ case R2_CHARGED_POWER_CAPSULE:
+ if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 1) {
+ R2_GLOBALS._sound3.play(49);
+ R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 100);
+ R2_GLOBALS.setFlag(1);
+ SceneItem::display2(5, 4);
+ } else {
+ SceneItem::display2(5, 5);
+ }
+ break;
+ default:
+ selectDefault(objectNumber);
+ break;
+ }
+ break;
+ case R2_STEPPING_DISKS:
+ switch (currentItem) {
+ case R2_SENSOR_PROBE:
+ if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400) {
+ R2_GLOBALS._sound3.play(48);
+ SceneItem::display2(5, 6);
+ R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 1);
+ } else {
+ SceneItem::display2(5, 7);
+ }
+ break;
+ case R2_COM_SCANNER:
+ R2_GLOBALS._sound3.play(44);
+ if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400)
+ SceneItem::display2(5, 16);
+ else
+ SceneItem::display2(5, 17);
+ R2_GLOBALS._sound3.stop();
+ break;
+ default:
+ selectDefault(objectNumber);
+ break;
+ }
+ break;
+ case R2_ATTRACTOR_UNIT:
+ case R2_CABLE_HARNESS:
+ if (currentItem == R2_CABLE_HARNESS ||
+ currentItem == R2_ATTRACTOR_UNIT) {
+ R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 1);
+ } else {
+ selectDefault(objectNumber);
+ }
+ break;
+ case R2_TANNER_MASK:
+ case R2_PURE_GRAIN_ALCOHOL:
+ if (currentItem == R2_TANNER_MASK ||
+ currentItem == R2_PURE_GRAIN_ALCOHOL) {
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 0);
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 0);
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 1);
+ } else {
+ selectDefault(objectNumber);
+ }
+ break;
+ default:
+ // Standard item selection
+ return false;
+ }
+
+ return true;
+}
+
+void Ringworld2InvObjectList::selectDefault(int objectNumber) {
+ Common::String msg1 = g_resourceManager->getMessage(4, 53);
+ Common::String msg2 = g_resourceManager->getMessage(4, R2_GLOBALS._events.getCursor());
+ Common::String msg3 = g_resourceManager->getMessage(4, 54);
+ Common::String msg4 = g_resourceManager->getMessage(4, 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,
+ SET_Y, 20,
+ SET_POS_MODE, 1,
+ SET_EXT_BGCOLOR, 7,
+ LIST_END);
}
/*--------------------------------------------------------------------------*/
@@ -1091,6 +1245,14 @@ void SceneActor::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
}
+void SceneActor::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
+ _field9C = NULL;
+ _linkedActor = NULL;
+
+ SceneObject::remove();
+}
+
bool SceneActor::startAction(CursorType action, Event &event) {
bool handled = true;
@@ -1123,9 +1285,35 @@ bool SceneActor::startAction(CursorType action, Event &event) {
return handled;
}
+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;
+}
+
/*--------------------------------------------------------------------------*/
-SceneArea::SceneArea(): EventHandler() {
+SceneArea::SceneArea(): SceneItem() {
_enabled = true;
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
@@ -1138,8 +1326,8 @@ void SceneArea::synchronize(Serializer &s) {
_bounds.synchronize(s);
s.syncAsSint16LE(_enabled);
s.syncAsSint16LE(_insideArea);
- s.syncAsSint16LE(_cursorNum);
- s.syncAsSint16LE(_savedCursorNum);
+ s.syncAsSint32LE(_cursorNum);
+ s.syncAsSint32LE(_savedCursorNum);
s.syncAsSint16LE(_cursorState);
}
@@ -1229,6 +1417,7 @@ void SceneExit::process(Event &event) {
/*--------------------------------------------------------------------------*/
void SceneAreaObject::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
_object1.remove();
SceneArea::remove();
--R2_GLOBALS._insetUp;
@@ -1238,19 +1427,22 @@ void SceneAreaObject::process(Event &event) {
if (_insetCount == R2_GLOBALS._insetUp) {
CursorType cursor = R2_GLOBALS._events.getCursor();
- if (_bounds.contains(event.mousePos)) {
+ if (_object1._bounds.contains(event.mousePos)) {
// Cursor moving in bounded area
if (cursor == _cursorNum) {
R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
- if (_cursorNum != cursor)
+ if (_cursorNum != cursor) {
// Cursor moved outside bounded area
- R2_GLOBALS._events.setCursor(_savedCursorNum);
-
+ _savedCursorNum = R2_GLOBALS._events.getCursor();
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+
if (event.eventType == EVENT_BUTTON_DOWN) {
- R2_GLOBALS._events.setCursor(_savedCursorNum);
event.handled = true;
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ remove();
}
}
}
@@ -1270,7 +1462,7 @@ void SceneAreaObject::setDetails(int visage, int strip, int frameNumber, const C
}
void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- ((SceneHotspot *)(this))->setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
2, (SceneItem *)NULL);
}
@@ -1341,7 +1533,7 @@ void MazeUI::clear() {
if (_mapData)
DEALLOCATE(_mapData);
_mapData = NULL;
-
+
_mapImage.clear();
}
@@ -1387,7 +1579,7 @@ void MazeUI::draw() {
// 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) {
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) {
@@ -1398,7 +1590,7 @@ void MazeUI::draw() {
if (cell >= 0) {
int frameNum = (cell % _frameCount) + 1;
int rlbNum = (cell % _resCount) / _frameCount + 1;
- int resNum = _cellsResNum + (cell / _resCount);
+ int resNum = _cellsResNum + (cell / _resCount);
visage.setVisage(resNum, rlbNum);
GfxSurface frame = visage.getFrame(frameNum);
@@ -1416,7 +1608,7 @@ void MazeUI::draw() {
// First line of the map to be displayed - only the bottom portion of that
// first cell row may be visible
yPos = _bounds.top;
- ySize = _cellSize.y - (_mapOffset.y % _cellSize.y);
+ ySize = _cellSize.y - (_mapOffset.y % _cellSize.y);
Rect srcBounds(_mapOffset.x % _cellSize.x, _mapOffset.y % _cellSize.y,
(_mapOffset.x % _cellSize.x) + _bounds.width(), _cellSize.y);
@@ -1564,7 +1756,7 @@ AnimationPlayer::~AnimationPlayer() {
void AnimationPlayer::synchronize(Serializer &s) {
EventHandler::synchronize(s);
- warning("TODO AnimationPlayer::load");
+ warning("TODO AnimationPlayer::synchronize");
}
void AnimationPlayer::remove() {
@@ -1682,7 +1874,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
default:
// ANIMPALMODE_CURR_PALETTE
- // Use the closest matching colours in the currently active palette to those specified in the animation
+ // Use the closest matching colors in the currently active palette to those specified in the animation
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
byte r = _subData._palData[idx * 3];
byte g = _subData._palData[idx * 3 + 1];
@@ -1928,6 +2120,349 @@ void AnimationPlayerExt::synchronize(Serializer &s) {
s.syncAsSint16LE(_v);
}
+/*--------------------------------------------------------------------------*/
+
+ModalWindow::ModalWindow() {
+ _field20 = 0;
+}
+
+void ModalWindow::remove() {
+ R2_GLOBALS._sceneItems.remove(&_object1);
+ _object1.remove();
+
+ SceneArea::remove();
+
+ --R2_GLOBALS._insetUp;
+}
+
+void ModalWindow::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsByte(_field20);
+}
+
+void ModalWindow::process(Event &event) {
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_object1._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 ModalWindow::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ _object1.postInit();
+ _object1.setup(visage, stripFrameNum, frameNum);
+ _object1.setPosition(Common::Point(posX, posY));
+ _object1.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+}
+
+void ModalWindow::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+
+void ScannerDialog::Button::setup(int buttonId) {
+ _buttonId = buttonId;
+ _buttonDown = false;
+ SceneActor::postInit();
+
+ SceneObject::setup(4, 2, 2);
+ fixPriority(255);
+
+ if (_buttonId == 1)
+ setPosition(Common::Point(141, 99));
+ else if (_buttonId == 2)
+ setPosition(Common::Point(141, 108));
+
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this);
+}
+
+void ScannerDialog::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+ s.syncAsSint16LE(_buttonId);
+}
+
+void ScannerDialog::Button::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE
+ && _bounds.contains(event.mousePos) && !_buttonDown) {
+ setFrame(3);
+ _buttonDown = true;
+ event.handled = true;
+ }
+
+ if (event.eventType == EVENT_BUTTON_UP && _buttonDown) {
+ setFrame(2);
+ _buttonDown = false;
+ event.handled = true;
+
+ reset();
+ }
+}
+
+bool ScannerDialog::Button::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+
+ return startAction(action, event);
+}
+
+void ScannerDialog::Button::reset() {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ ScannerDialog &scanner = *R2_GLOBALS._scannerDialog;
+
+ switch (_buttonId) {
+ case 1:
+ // Talk button
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ scene->_sceneMode = 80;
+ scene->signal();
+ break;
+ case 1700:
+ scene->_sceneMode = 30;
+ scene->signal();
+ remove();
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2:
+ // Scan button
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ scanner._obj4.setup(4, 3, 1);
+
+ scanner._obj5.postInit();
+ scanner._obj5.setup(4, 4, 1);
+ scanner._obj5.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_QUINN].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN].y + 59));
+ scanner._obj5.fixPriority(257);
+
+ scanner._obj6.postInit();
+ scanner._obj6.setup(4, 4, 2);
+ scanner._obj6.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_SEEKER].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER].y + 59));
+ scanner._obj6.fixPriority(257);
+ break;
+ case 1700:
+ case 1800:
+ if (R2_GLOBALS._rimLocation < 1201)
+ scanner._obj4.setup(4, 3, 3);
+ else if (R2_GLOBALS._rimLocation < 1201)
+ scanner._obj4.setup(4, 3, 4);
+ else
+ scanner._obj4.setup(4, 3, 5);
+ break;
+ case 3800:
+ case 3900:
+ if ((R2_GLOBALS._v56A93 + 1) == 0 && R2_GLOBALS._v566A9 == 0) {
+ do {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._randomSource.getRandomNumber(3);
+ } while (R2_GLOBALS._v566A9 == R2_GLOBALS._v566AA);
+ }
+
+ scanner._obj4.setup(4, 7, R2_GLOBALS._v566A9);
+ if (!R2_GLOBALS.getFlag(46))
+ R2_GLOBALS.setFlag(46);
+ break;
+ default:
+ scanner._obj4.setup(4, 3, 2);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::Slider::Slider() {
+ _initial = _xStart = _yp = 0;
+ _width = _xInc = 0;
+ _sliderDown = false;
+}
+
+void ScannerDialog::Slider::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_initial);
+ s.syncAsSint16LE(_xStart);
+ s.syncAsSint16LE(_yp);
+ s.syncAsSint16LE(_width);
+ s.syncAsSint16LE(_xInc);
+}
+
+void ScannerDialog::Slider::remove() {
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.remove(this);
+ SceneActor::remove();
+}
+
+void ScannerDialog::Slider::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE
+ && _bounds.contains(event.mousePos)) {
+ _sliderDown = true;
+ }
+
+ if (event.eventType == EVENT_BUTTON_UP && _sliderDown) {
+ _sliderDown = false;
+ event.handled = true;
+ update();
+ }
+
+ if (_sliderDown) {
+ event.handled = true;
+ if (event.mousePos.x < _xStart) {
+ setPosition(Common::Point(_xStart, _yp));
+ } else if (event.mousePos.x >= (_xStart + _width)) {
+ setPosition(Common::Point(_xStart + _width, _yp));
+ } else {
+ setPosition(Common::Point(event.mousePos.x, _yp));
+ }
+ }
+}
+
+bool ScannerDialog::Slider::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+
+ return startAction(action, event);
+}
+
+void ScannerDialog::Slider::update() {
+ int incHalf = (_width / (_xInc - 1)) / 2;
+ int newFrequency = ((_position.x - _xStart + incHalf) * _xInc) / (_width + incHalf * 2);
+ setPosition(Common::Point(_xStart + ((_width * newFrequency) / (_xInc - 1)), _yp));
+
+ R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] = newFrequency + 1;
+
+ switch (newFrequency) {
+ case 0:
+ R2_GLOBALS._sound4.stop();
+ break;
+ case 1:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 2:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+}
+
+void ScannerDialog::Slider::setup(int initial, int xStart, int yp, int width, int xInc) {
+ _initial = initial;
+ _xStart = xStart;
+ _yp = yp;
+ _width = width;
+ _xInc = xInc;
+ _sliderDown = false;
+ SceneActor::postInit();
+ SceneObject::setup(4, 2, 1);
+ fixPriority(255);
+ setPosition(Common::Point(_width * (_initial - 1) / (_xInc - 1) + _xStart, yp));
+
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this);
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::ScannerDialog() {
+}
+
+void ScannerDialog::remove() {
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ case 1700:
+ R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
+ break;
+ case 3800:
+ case 3900: {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 3806;
+ scene->signal();
+ break;
+ }
+ default:
+ break;
+ }
+
+ SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene);
+ scene->_sceneAreas.remove(&_talkButton);
+ scene->_sceneAreas.remove(&_scanButton);
+ _talkButton.remove();
+ _scanButton.remove();
+ _slider.remove();
+ _obj4.remove();
+ _obj5.remove();
+ _obj6.remove();
+ _obj7.remove();
+
+ ModalWindow::remove();
+}
+
+void ScannerDialog::proc12(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);
+
+ proc13(100, -1, -1, -1);
+ _talkButton.setup(1);
+ _scanButton.setup(2);
+ _slider.setup(R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex], 142, 124, 35, 5);
+
+ _obj4.postInit();
+ _obj4.setup(4, 3, 2);
+ _obj4.setPosition(Common::Point(160, 83));
+ _obj4.fixPriority(256);
+
+ if (R2_GLOBALS._sceneManager._sceneNumber == 3800 || R2_GLOBALS._sceneManager._sceneNumber == 3900) {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 3805;
+ scene->signal();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index 24434568ad..c7e36fc5f0 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -42,9 +42,8 @@ public:
static Scene *createScene(int sceneNumber);
};
-class SceneArea: public EventHandler {
+class SceneArea: public SceneItem {
public:
- Rect _bounds;
bool _enabled;
bool _insideArea;
CursorType _cursorNum;
@@ -54,9 +53,12 @@ public:
SceneArea();
void setDetails(const Rect &bounds, CursorType cursor);
+ virtual Common::String getClassName() { return "SceneArea"; }
virtual void synchronize(Serializer &s);
virtual void remove();
virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event) { return false; }
+ virtual void doAction(int action) {}
};
class SceneExit: public SceneArea {
@@ -80,26 +82,21 @@ private:
static void endStrip();
public:
byte _field312[256];
- int _field372;
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
- int _field37A;
- SceneObject *_focusObject;
Visage _cursorVisage;
- SynchronizedList<SceneArea *> _sceneAreas;
-
- Rect _v51C34;
+ SynchronizedList<EventHandler *> _sceneAreas;
public:
SceneExt();
virtual Common::String getClassName() { return "SceneExt"; }
+ virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void process(Event &event);
virtual void dispatch();
- virtual void loadScene(int sceneNum);
virtual void refreshBackground(int xAmount, int yAmount);
virtual void saveCharacter(int characterIndex);
virtual void restore() {}
@@ -108,12 +105,14 @@ public:
void fadeOut();
void clearScreen();
void scalePalette(int RFactor, int GFactor, int BFactor);
+ void loadBlankScene();
};
class SceneHandlerExt: public SceneHandler {
public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void process(Event &event);
+ virtual void postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad);
void setupPaletteMaps();
};
@@ -159,6 +158,9 @@ public:
/*--------------------------------------------------------------------------*/
class Ringworld2InvObjectList : public InvObjectList {
+private:
+ static bool SelectItem(int objectNumber);
+ static void selectDefault(int obectNumber);
public:
InvObject _none;
InvObject _inv1;
@@ -260,7 +262,9 @@ class SceneActor: public SceneObject {
public:
virtual Common::String getClassName() { return "SceneActor"; }
virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
virtual bool startAction(CursorType action, Event &event);
+ virtual GfxSurface getFrame();
};
class SceneActorExt: public SceneActor {
@@ -386,6 +390,8 @@ public:
enum AnimationPaletteMode { ANIMPALMODE_REPLACE_PALETTE = 0, ANIMPALMODE_CURR_PALETTE = 1,
ANIMPALMODE_NONE = 2 };
+enum AnimationObjectMode { ANIMOBJMODE_1 = 1, ANIMOBJMODE_2 = 2, ANIMOBJMODE_42 = 42 };
+
class AnimationPlayer: public EventHandler {
private:
void rleDecode(const byte *pSrc, byte *pDest, int size);
@@ -400,8 +406,9 @@ public:
Common::File _resourceFile;
Rect _rect1, _screenBounds;
int _field38;
- int _field3A, _paletteMode;
- int _objectMode;
+ int _field3A;
+ AnimationPaletteMode _paletteMode;
+ AnimationObjectMode _objectMode;
int _field58, _sliceHeight;
byte _palIndexes[256];
ScenePalette _palette;
@@ -426,6 +433,7 @@ public:
virtual void changePane() {}
virtual void closing() {}
+
bool load(int animId, Action *endAction = NULL);
bool isCompleted();
void close();
@@ -440,6 +448,74 @@ public:
virtual void synchronize(Serializer &s);
};
+class ModalWindow: public SceneArea {
+public:
+ SceneActor _object1;
+ byte _field20;
+public:
+ ModalWindow();
+
+ virtual void remove();
+ 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);
+};
+
+class ScannerDialog: public ModalWindow {
+
+ class Button: public SceneActor {
+ private:
+ void reset();
+ public:
+ int _buttonId;
+ bool _buttonDown;
+ public:
+ Button();
+ void setup(int buttonId);
+
+ virtual void synchronize(Serializer &s);
+ virtual Common::String getClassName() { return "ScannerButton"; }
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Slider: public SceneActor {
+ private:
+ void update();
+ public:
+ int _initial;
+ int _xStart;
+ int _yp;
+ int _width;
+ int _xInc;
+ bool _sliderDown;
+ public:
+ Slider();
+ void setup(int initial, int xStart, int yp, int width, int xInc);
+
+ virtual void synchronize(Serializer &s);
+ virtual Common::String getClassName() { return "ScannerSlider"; }
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ };
+public:
+ Button _talkButton;
+ Button _scanButton;
+ Slider _slider;
+ SceneActor _obj4;
+ SceneActor _obj5;
+ SceneActor _obj6;
+ SceneActor _obj7;
+public:
+ ScannerDialog();
+
+ virtual Common::String getClassName() { return "ScannerDialog"; }
+ virtual void remove();
+ void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index 3b7d283e44..a0846d386a 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -226,9 +226,9 @@ bool Scene100::Terminal::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
void Scene100::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(100);
R2_GLOBALS._scenePalette.loadPalette(0);
+ SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene != 125)
R2_GLOBALS._sound1.play(10);
@@ -392,11 +392,11 @@ void Scene100::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene125::Object5::startAction(CursorType action, Event &event) {
+bool Scene125::Food::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return true;
- else
- return SceneActor::startAction(action, event);
+
+ return SceneActor::startAction(action, event);
}
/*--------------------------------------------------------------------------*/
@@ -573,23 +573,23 @@ void Scene125::Icon::hideIcon() {
/*--------------------------------------------------------------------------*/
-bool Scene125::Item4::startAction(CursorType action, Event &event) {
+bool Scene125::DiskSlot::startAction(CursorType action, Event &event) {
Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 126;
- scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_object7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_infoDisk, NULL);
return true;
}
break;
case R2_OPTO_DISK:
if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1) {
R2_GLOBALS._player.disableControl();
- scene->_object7.postInit();
+ scene->_infoDisk.postInit();
scene->_sceneMode = 125;
- scene->setAction(&scene->_sequenceManager, scene, 125, &scene->_object7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 125, &scene->_infoDisk, NULL);
return true;
}
break;
@@ -626,16 +626,16 @@ void Scene125::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
- _object7.postInit();
- _object7.setup(160, 3, 5);
- _object7.setPosition(Common::Point(47, 167));
+ _infoDisk.postInit();
+ _infoDisk.setup(160, 3, 5);
+ _infoDisk.setPosition(Common::Point(47, 167));
}
- _object6.postInit();
- _object6.setup(162, 1, 1);
- _object6.setPosition(Common::Point(214, 168));
+ _foodDispenser.postInit();
+ _foodDispenser.setup(162, 1, 1);
+ _foodDispenser.setPosition(Common::Point(214, 168));
- _item4.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL);
+ _diskSlot.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL);
_item3.setDetails(Rect(144, 119, 286, 167), 126, 6, 7, 8, 1, NULL);
_item2.setDetails(1, 126, 3, 4, 5);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 126, 0, 1, -1, 1, NULL);
@@ -656,8 +656,8 @@ void Scene125::signal() {
_icon4.postInit();
_icon4._sceneRegionId = 5;
- _sceneMode = 2;
setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL);
+ _sceneMode = 2;
break;
case 2:
_icon1.setup(160, 1, 1);
@@ -698,7 +698,7 @@ void Scene125::signal() {
_icon6._sceneRegionId = 8;
consoleAction(5);
- R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 10:
@@ -782,10 +782,11 @@ void Scene125::signal() {
break;
case 125:
R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[1]);
+ R2_GLOBALS._player.enableControl();
break;
case 126:
R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 1);
- _object7.remove();
+ _infoDisk.remove();
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
break;
@@ -970,14 +971,17 @@ void Scene125::consoleAction(int id) {
case 15:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 3) {
+ if (R2_GLOBALS._foodCount < 3) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 2);
- _object5.setPosition(Common::Point(216, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 2);
+ _food.setPosition(Common::Point(216, UI_INTERFACE_Y));
+
+ R2_GLOBALS._foodCount += 2;
- R2_GLOBALS._v565F5 += 2;
- } else if (R2_GLOBALS._v565F5 == 3) {
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
+ } else if (R2_GLOBALS._foodCount == 3) {
SceneItem::display2(126, 13);
} else {
SceneItem::display2(126, 14);
@@ -986,13 +990,16 @@ void Scene125::consoleAction(int id) {
case 16:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 3);
- _object5.setPosition(Common::Point(218, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 3);
+ _food.setPosition(Common::Point(218, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._foodCount;
- ++R2_GLOBALS._v565F5;
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 15);
}
@@ -1000,13 +1007,16 @@ void Scene125::consoleAction(int id) {
case 17:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 1);
- _object5.setPosition(Common::Point(215, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 1);
+ _food.setPosition(Common::Point(215, UI_INTERFACE_Y));
- ++R2_GLOBALS._v565F5;
+ ++R2_GLOBALS._foodCount;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 16);
}
@@ -1553,7 +1563,7 @@ void Scene180::signal() {
R2_GLOBALS._sceneManager._hasPalette = true;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
_animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 1;
_animationPlayer.load(1);
@@ -1596,7 +1606,7 @@ void Scene180::signal() {
case 5:
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
_animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 2;
_animationPlayer.load(2);
@@ -1701,7 +1711,7 @@ void Scene180::signal() {
_field412 = 1;
_animationPlayer._paletteMode = ANIMPALMODE_REPLACE_PALETTE;
_animationPlayer._v = 1;
- _animationPlayer._objectMode = 42;
+ _animationPlayer._objectMode = ANIMOBJMODE_42;
R2_GLOBALS._scene180Mode = 3;
_animationPlayer.load(3);
break;
@@ -1800,7 +1810,7 @@ void Scene180::signal() {
case 40:
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 4;
if (_animationPlayer.load(4)) {
_animationPlayer.dispatch();
@@ -1839,7 +1849,7 @@ void Scene180::signal() {
_field412 = 1;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
_animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 15;
_animationPlayer.load(15, NULL);
@@ -1923,7 +1933,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 4;
R2_GLOBALS._gfxColors.background = 3;
R2_GLOBALS._fontColors.background = 3;
- R2_GLOBALS._frameEdgeColour = 3;
+ R2_GLOBALS._frameEdgeColor = 3;
break;
case 1:
@@ -1932,7 +1942,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 25;
R2_GLOBALS._gfxColors.background = 43;
R2_GLOBALS._fontColors.background = 48;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 2:
@@ -1942,7 +1952,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.background = 136;
R2_GLOBALS._fontColors.background = 48;
R2_GLOBALS._fontColors.foreground = 253;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 3:
@@ -1951,7 +1961,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 84;
R2_GLOBALS._gfxColors.background = 118;
R2_GLOBALS._fontColors.background = 47;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 14:
@@ -1961,7 +1971,7 @@ void Scene180::restore() {
R2_GLOBALS._fontColors.foreground = 38;
R2_GLOBALS._gfxColors.foreground = 192;
R2_GLOBALS._gfxColors.background = 30;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
default:
@@ -2025,7 +2035,7 @@ void Scene200::EastExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 206;
scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
}
@@ -2034,7 +2044,7 @@ void Scene200::WestExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 208;
scene->setAction(&scene->_sequenceManager, scene, 208, &R2_GLOBALS._player, NULL);
}
@@ -2042,8 +2052,8 @@ void Scene200::WestExit::changeScene() {
/*--------------------------------------------------------------------------*/
void Scene200::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(200);
+ SceneExt::postInit();
_westExit.setDetails(Rect(94, 0, 123, 58), EXITCURSOR_W, 175);
_westExit.setDest(Common::Point(125, 52));
@@ -2311,19 +2321,6 @@ void Scene205::Action1::textLoop() {
/*--------------------------------------------------------------------------*/
-Scene205::Object::Object(): SceneObject() {
- _x100 = _y100 = 0;
-}
-
-void Scene205::Object::synchronize(Serializer &s) {
- EventHandler::synchronize(s);
-
- s.syncAsSint32LE(_x100);
- s.syncAsSint32LE(_y100);
-}
-
-/*--------------------------------------------------------------------------*/
-
Scene205::Scene205(): SceneExt() {
_yp = 0;
_textIndex = 1;
@@ -2492,14 +2489,13 @@ void Scene205::handleText() {
*--------------------------------------------------------------------------*/
Scene250::Button::Button(): SceneActor() {
- _floorNumber = _v2 = 0;
+ _floorNumber = 0;
}
void Scene250::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_floorNumber);
- s.syncAsSint16LE(_v2);
}
bool Scene250::Button::startAction(CursorType action, Event &event) {
@@ -2507,7 +2503,7 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (scene->_field414) {
+ if (scene->_destButtonY) {
SceneItem::display2(250, 15);
} else {
switch (_floorNumber) {
@@ -2558,7 +2554,6 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
void Scene250::Button::setFloor(int floorNumber) {
SceneActor::postInit();
_floorNumber = floorNumber;
- _v2 = 0;
if (_floorNumber <= 9) {
SceneObject::setup(250, 1, 4);
@@ -2583,22 +2578,23 @@ void Scene250::Button::setFloor(int floorNumber) {
/*--------------------------------------------------------------------------*/
Scene250::Scene250(): SceneExt() {
- _field412 = _field414 = _field416 = _field418 = _field41A = 0;
+ _currButtonY = _destButtonY = _elevatorSpeed = 0;
+ _skippingFl = _skippableFl = false;
}
void Scene250::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_currButtonY);
+ s.syncAsSint16LE(_destButtonY);
+ s.syncAsSint16LE(_elevatorSpeed);
+ s.syncAsSint16LE(_skippableFl);
+ s.syncAsSint16LE(_skippingFl);
}
void Scene250::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(250);
+ SceneExt::postInit();
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
@@ -2635,28 +2631,28 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 200:
- _field412 = 55;
+ _currButtonY = 55;
break;
case 300:
- _field412 = 43;
+ _currButtonY = 43;
break;
case 700:
- _field412 = 139;
+ _currButtonY = 139;
break;
case 850:
- _field412 = 91;
+ _currButtonY = 91;
break;
default:
R2_GLOBALS._sceneManager._previousScene = 200;
- _field412 = 55;
+ _currButtonY = 55;
break;
}
- _currentFloor.setPosition(Common::Point(111, _field412));
+ _currentFloor.setPosition(Common::Point(111, _currButtonY));
}
void Scene250::signal() {
- if (_field41A)
+ if (_skippingFl)
_sceneMode = 20;
switch (_sceneMode) {
@@ -2667,20 +2663,24 @@ void Scene250::signal() {
R2_GLOBALS._player.setPosition(Common::Point(261, 185));
ADD_MOVER(R2_GLOBALS._player, 261, 15);
- _field416 = 0;
+ _elevatorSpeed = 0;
_sceneMode = 2;
break;
case 2:
- _sceneMode = ((_field414 - 12) == _field412) ? 4 : 3;
+ if (_destButtonY - 12 == _currButtonY)
+ _sceneMode = 4;
+ else
+ _sceneMode = 3;
+
signal();
break;
case 3:
_currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12));
- _field412 += 12;
+ _currButtonY += 12;
R2_GLOBALS._player.setPosition(Common::Point(261, 185));
ADD_MOVER(R2_GLOBALS._player, 261, 15);
- if ((_field414 - 12) == _field412)
+ if ((_destButtonY - 12) == _currButtonY)
_sceneMode = 4;
break;
case 4:
@@ -2702,22 +2702,24 @@ void Scene250::signal() {
R2_GLOBALS._player.setup(250, 1, 2);
R2_GLOBALS._player.setPosition(Common::Point(261, 15));
ADD_MOVER(R2_GLOBALS._player, 261, 185);
- _field416 = 0;
+ _elevatorSpeed = 0;
_sceneMode = 7;
break;
case 7:
- _field418 = 1;
- if ((_field414 + 12) == _field412)
+ _skippableFl = true;
+ if ((_destButtonY + 12) == _currButtonY)
+ _sceneMode = 9;
+ else
_sceneMode = 8;
signal();
break;
case 8:
_currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12));
- _field412 -= 12;
+ _currButtonY -= 12;
R2_GLOBALS._player.setPosition(Common::Point(261, 15));
ADD_MOVER(R2_GLOBALS._player, 261, 185);
- if ((_field414 + 12) == _field412)
+ if ((_destButtonY + 12) == _currButtonY)
_sceneMode = 9;
break;
case 9:
@@ -2733,7 +2735,7 @@ void Scene250::signal() {
break;
case 20:
// Handle changing scene
- switch (_field414) {
+ switch (_destButtonY) {
case 55:
R2_GLOBALS._sceneManager.changeScene(200);
break;
@@ -2741,7 +2743,7 @@ void Scene250::signal() {
R2_GLOBALS._sceneManager.changeScene(300);
break;
case 139:
- R2_GLOBALS._sceneManager.changeScene(139);
+ R2_GLOBALS._sceneManager.changeScene(700);
break;
case 91:
R2_GLOBALS._sceneManager.changeScene(850);
@@ -2756,12 +2758,13 @@ void Scene250::signal() {
}
void Scene250::changeFloor(int floorNumber) {
- _field414 = (floorNumber - 1) * 12 + 43;
- _button1.setPosition(Common::Point(111, _field414));
+ _destButtonY = (floorNumber - 1) * 12 + 43;
+ _button1.setPosition(Common::Point(111, _destButtonY));
_button1.show();
- _sceneMode = (_field412 >= _field414) ? 6 : 1;
- if (_field414 == _field412)
+ _skippableFl = true;
+ _sceneMode = (_currButtonY >= _destButtonY) ? 6 : 1;
+ if (_destButtonY == _currButtonY)
_sceneMode = 20;
signal();
@@ -2769,8 +2772,8 @@ void Scene250::changeFloor(int floorNumber) {
void Scene250::process(Event &event) {
if (!event.handled) {
- if (((event.eventType == EVENT_KEYPRESS) || (event.btnState != 0)) && _field418) {
- _field41A = 1;
+ if (((event.eventType == EVENT_KEYPRESS) || (event.btnState == BTNSHIFT_RIGHT)) && _skippableFl) {
+ _skippingFl = true;
event.handled = true;
}
@@ -2781,14 +2784,14 @@ void Scene250::process(Event &event) {
void Scene250::dispatch() {
SceneExt::dispatch();
- if (((_sceneMode == 2) || (_sceneMode == 7)) && (_field416 < 100)) {
- ++_field416;
- R2_GLOBALS._player._moveDiff.y = _field416 / 5;
+ if (((_sceneMode == 2) || (_sceneMode == 7)) && (_elevatorSpeed < 100)) {
+ ++_elevatorSpeed;
+ R2_GLOBALS._player._moveDiff.y = _elevatorSpeed / 5;
}
if (((_sceneMode == 5) || (_sceneMode == 10)) && (R2_GLOBALS._player._moveDiff.y > 4)) {
- --_field416;
- R2_GLOBALS._player._moveDiff.y = _field416 / 7 + 3;
+ --_elevatorSpeed;
+ R2_GLOBALS._player._moveDiff.y = (_elevatorSpeed / 7) + 3;
}
}
@@ -2986,7 +2989,7 @@ bool Scene300::Miranda::startAction(CursorType action, Event &event) {
} else if (!R2_GLOBALS.getFlag(55)) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_sceneMode = 10;
- scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
+ scene->_stripManager.start3(201, scene, R2_GLOBALS._stripManager_lookupList);
} else {
scene->_sceneMode = 16;
@@ -3048,7 +3051,7 @@ bool Scene300::Seeker::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS.getFlag(44)) {
+ if (!R2_GLOBALS.getFlag(44)) {
if (!R2_GLOBALS.getFlag(38)) {
R2_GLOBALS._sound1.play(69);
scene->_stripId = 181;
@@ -3090,10 +3093,10 @@ bool Scene300::Seeker::startAction(CursorType action, Event &event) {
} else {
R2_GLOBALS._player.disableControl();
scene->_stripId = 171;
- }
- scene->_sceneMode = 310;
- scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL);
+ scene->_sceneMode = 310;
+ scene->setAction(&scene->_sequenceManager1, scene, 310, &R2_GLOBALS._player, NULL);
+ }
return true;
case R2_READER:
@@ -3152,7 +3155,7 @@ bool Scene300::Doorway::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
- (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) {
+ (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_SEEKER] == 500)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 301;
scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
@@ -3171,6 +3174,9 @@ bool Scene300::Doorway::startAction(CursorType action, Event &event) {
Scene300::Scene300(): SceneExt() {
_stripId = 0;
_rotation = NULL;
+
+ _stripManager.setColors(60, 255);
+ _stripManager.setFontNumber(3);
}
void Scene300::synchronize(Serializer &s) {
@@ -3181,8 +3187,9 @@ void Scene300::synchronize(Serializer &s) {
}
void Scene300::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(300);
+ SceneExt::postInit();
+
_sound1.play(23);
setZoomPercents(75, 93, 120, 100);
@@ -3191,8 +3198,6 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
}
- _stripManager.setColors(60, 255);
- _stripManager.setFontNumber(3);
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_quinnSpeaker);
@@ -3233,7 +3238,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_protocolDisplay.postInit();
_protocolDisplay.setup(300, 6, 1);
_protocolDisplay.setPosition(Common::Point(287, 71));
- _protocolDisplay.animate(ANIM_MODE_7, NULL);
+ _protocolDisplay.animate(ANIM_MODE_7, 0, NULL);
_protocolDisplay._numFrames = 5;
_object6.postInit();
@@ -3365,7 +3370,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
break;
case 325:
if (!R2_GLOBALS.getFlag(44) || R2_GLOBALS.getFlag(25))
- setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 307, &R2_GLOBALS._player, NULL);
else {
R2_GLOBALS.setFlag(60);
R2_GLOBALS._player.setup(302, 3, 1);
@@ -3402,9 +3407,11 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
if (R2_GLOBALS.getFlag(51)) {
+ // Things don't seem right
_sceneMode = 13;
_stripManager.start3(300, this, R2_GLOBALS._stripManager_lookupList);
} else {
+ // Back in Ringworld space
_sceneMode = 11;
_stripManager.start3(200, this, R2_GLOBALS._stripManager_lookupList);
}
@@ -3484,27 +3491,27 @@ void Scene300::remove() {
void Scene300::signal() {
switch (_sceneMode) {
case 10:
- switch (_stripManager._field2E8) {
- case 0:
+ switch (_stripManager._exitMode) {
+ case 1:
R2_GLOBALS._sound1.changeSound(10);
R2_GLOBALS.setFlag(38);
break;
- case 1:
+ case 2:
R2_GLOBALS.setFlag(3);
break;
- case 2:
+ case 3:
R2_GLOBALS.setFlag(4);
break;
- case 3:
+ case 4:
R2_GLOBALS.setFlag(13);
if (R2_GLOBALS._stripManager_lookupList[1] == 6)
R2_GLOBALS.setFlag(40);
break;
- case 4:
+ case 5:
if (R2_GLOBALS._stripManager_lookupList[1] == 6)
R2_GLOBALS.setFlag(40);
break;
- case 5:
+ case 6:
R2_GLOBALS._sceneManager.changeScene(1000);
break;
default:
@@ -3565,7 +3572,7 @@ void Scene300::signal() {
break;
case 16:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._sceneManager.changeScene(1000);
} else {
@@ -3624,6 +3631,8 @@ void Scene300::signal() {
case 309:
signal309();
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._events._currentCursor = CURSOR_ARROW;
+
_sceneMode = 10;
_stripManager.start3(_stripId, this, R2_GLOBALS._stripManager_lookupList);
break;
@@ -3891,7 +3900,7 @@ Scene325::Scene325(): SceneExt() {
_field412 = 7;
_iconFontNumber = 50;
_field416 = _field418 = 0;
- _field41A = _field41C = _field41E = _field420 = 0;
+ _field41A = _field41C = _field41E = _scannerLocation = 0;
_soundCount = _soundIndex = 0;
for (int idx = 0; idx < 10; ++idx)
@@ -3899,8 +3908,8 @@ Scene325::Scene325(): SceneExt() {
}
void Scene325::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(325);
+ SceneExt::postInit();
R2_GLOBALS.clearFlag(50);
_stripManager.addSpeaker(&_quinnSpeaker);
@@ -3926,7 +3935,7 @@ void Scene325::synchronize(Serializer &s) {
s.syncAsSint16LE(_field41A);
s.syncAsSint16LE(_field41C);
s.syncAsSint16LE(_field41E);
- s.syncAsSint16LE(_field420);
+ s.syncAsSint16LE(_scannerLocation);
s.syncAsSint16LE(_soundCount);
s.syncAsSint16LE(_soundIndex);
@@ -4027,19 +4036,19 @@ void Scene325::signal() {
if (R2_GLOBALS.getFlag(44) && !R2_GLOBALS.getFlag(51)) {
if (v != 13) {
- setMessage(328, 0);
+ setMessage(328, v);
} else {
- _field420 = 864;
+ _scannerLocation = 864;
_object12.postInit();
- _object2.setup(326, 4, 1);
+ _object12.setup(326, 4, 1);
_object12.setPosition(Common::Point(149, 128));
_object12.fixPriority(20);
- _object13.postInit();
- _object13.setup(326, 4, 2);
- _object13.setPosition(Common::Point(149, (int)(_field420 * ADJUST_FACTOR)));
- _object13.fixPriority(21);
+ _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);
@@ -4049,7 +4058,7 @@ void Scene325::signal() {
_object1.postInit();
_object1.setup(326, 1, 1);
_object1.setPosition(Common::Point(210, 32));
- _object10.fixPriority(10);
+ _object1.fixPriority(10);
_object2.postInit();
_object2.setup(326, 1, 1);
@@ -4099,7 +4108,7 @@ void Scene325::signal() {
} else if (R2_GLOBALS.getFlag(51)) {
setMessage(329, (v == 12) ? 10 : v);
} else {
- setMessage(327, (v < 15) ? 1 : v);
+ setMessage(327, (v >= 15) ? 1 : v);
}
break;
}
@@ -4140,12 +4149,12 @@ void Scene325::signal() {
setMessage(128, _field416);
break;
default:
- R2_GLOBALS._player.enableControl();
- R2_GLOBALS._player._canWalk = false;
- _field416 = 105;
- setMessage(128, _field416);
+ _field416 = 0;
break;
}
+
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
break;
case 10:
R2_GLOBALS._player.enableControl();
@@ -4227,31 +4236,50 @@ void Scene325::consoleAction(int id) {
_icon1.hideIcon();
_icon2.hideIcon();
_icon3.hideIcon();
- // TODO: Finish
- break;
- case 3:
- _icon1.setIcon(5);
- _icon2.setIcon(6);
- _icon3.setIcon(R2_GLOBALS.getFlag(50) ? 16 : 15);
- break;
- case 4:
- case 5:
- _field418 = id;
- _icon1.setIcon(17);
- _icon2.setIcon(18);
- _icon3.setIcon(19);
- break;
- case 7:
- consoleAction(((_field412 == 5) || (_field412 == 6) || (_field412 == 15)) ? 4 : 7);
+
+ if (id == 2 || (id == 19 && _field418 == 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();
+
+ } else {
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+ }
+
+ _icon6.setIcon(12);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
break;
- case 8:
- R2_GLOBALS._sceneManager.changeScene(300);
- case 9:
- case 10:
- _iconFontNumber = (id - 1) == 9 ? 50 : 52;
- _text1.remove();
- _icon6.setIcon(7);
+
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _field412 = id;
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+
+ _icon5.setIcon(13);
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(14);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(12);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
break;
+
case 11:
if (R2_GLOBALS.getFlag(57) && (R2_GLOBALS._player._characterIndex == 1) && !R2_GLOBALS.getFlag(25)) {
R2_GLOBALS._player.disableControl();
@@ -4260,6 +4288,7 @@ void Scene325::consoleAction(int id) {
_stripManager.start(403, this);
} else {
R2_GLOBALS._player.disableControl();
+ id = 8;
_text1.remove();
_icon4.setPosition(Common::Point(80, 62));
@@ -4267,7 +4296,7 @@ void Scene325::consoleAction(int id) {
_icon4.hideIcon();
_object12.remove();
- _object13.remove();
+ _scannerTab.remove();
_object10.remove();
_object1.remove();
_object2.remove();
@@ -4286,6 +4315,31 @@ void Scene325::consoleAction(int id) {
BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
}
break;
+
+ case 3:
+ _icon1.setIcon(5);
+ _icon2.setIcon(6);
+ _icon3.setIcon(R2_GLOBALS.getFlag(50) ? 16 : 15);
+ break;
+ case 4:
+ case 5:
+ _field418 = 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);
+ break;
+ case 8:
+ R2_GLOBALS._sceneManager.changeScene(300);
+ case 9:
+ case 10:
+ _iconFontNumber = (id - 1) == 9 ? 50 : 52;
+ _text1.remove();
+ _icon6.setIcon(7);
+ break;
case 12:
_icon4.setIcon(14);
_icon4._object2.hide();
@@ -4295,7 +4349,7 @@ void Scene325::consoleAction(int id) {
case 18:
case 19:
case 20:
- if (_field420) {
+ if (_scannerLocation) {
R2_GLOBALS._player.disableControl();
_field41A = 1296;
_field41E = 1;
@@ -4315,7 +4369,7 @@ void Scene325::consoleAction(int id) {
case 18:
case 19:
case 20:
- if (_field420 < 1620) {
+ if (_scannerLocation < 1620) {
R2_GLOBALS._player.disableControl();
_field41A = 1296;
_field41E = -1;
@@ -4337,31 +4391,6 @@ void Scene325::consoleAction(int id) {
consoleAction(4);
id = 4;
break;
- case 22:
- case 23:
- case 24:
- case 25:
- R2_GLOBALS._player.disableControl();
- consoleAction(2);
- _field412 = id;
-
- _icon1.hideIcon();
- _icon2.hideIcon();
- _icon3.hideIcon();
- _icon4.hideIcon();
-
- _icon5.setIcon(13);
- _icon4.setPosition(Common::Point(52, 107));
- _icon4._sceneRegionId = 9;
- _icon4.setIcon(14);
- _icon4._object2.hide();
-
- _icon6.setIcon(12);
- _sceneMode = 10;
- _palette.loadPalette(161);
-
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
- break;
case 6:
default:
_icon1.setIcon(1);
@@ -4436,21 +4465,21 @@ void Scene325::dispatch() {
if (yp >= 30) {
yp -= 12;
- --_field420;
+ --_scannerLocation;
flag = true;
}
if (yp <= 10) {
yp += 12;
- ++_field420;
+ ++_scannerLocation;
flag = true;
}
- _object3.setPosition(Common::Point(149, (int)(_field420 * ADJUST_FACTOR) + 22));
+ _scannerTab.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
for (int idx = 0; idx < 4; ++idx)
_objList[idx].remove();
if (flag) {
- int v = _field420 - 758;
+ int v = _scannerLocation - 758;
_object10.setFrame((v++ <= 0) ? 1 : v);
_object1.setFrame((v++ <= 0) ? 1 : v);
_object2.setFrame((v++ <= 0) ? 1 : v);
@@ -4490,7 +4519,7 @@ void Scene325::dispatch() {
R2_GLOBALS._sound3.stop();
_field41C = 0;
- if (_field420 == 756) {
+ if (_scannerLocation == 756) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_USE);
_sceneMode = 12;
@@ -4797,6 +4826,11 @@ void Scene400::dispatch() {
*
*--------------------------------------------------------------------------*/
+Scene500::PanelDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+
bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
@@ -4819,17 +4853,18 @@ bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
-bool Scene500::Object2::startAction(CursorType action, Event &event) {
+bool Scene500::Seeker::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1101 : 1103;
} else {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1102 : 1105;
}
+ scene->_sceneMode = 524;
scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
return true;
} else {
@@ -4837,7 +4872,7 @@ bool Scene500::Object2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object3::startAction(CursorType action, Event &event) {
+bool Scene500::Suit::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -4848,20 +4883,20 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
case CURSOR_USE:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if ((_strip != 3) && (_strip != 7))
- SceneItem::display2(500, _strip);
+ SceneItem::display2(500, _strip + 25);
else if (R2_GLOBALS.getFlag(26)) {
R2_GLOBALS._player.disableControl();
scene->_stripNumber = 1103;
scene->_sceneMode = 524;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, NULL);
} else if (!R2_GLOBALS.getFlag(28))
SceneItem::display2(500, 41);
- else if (!R2_GLOBALS.getFlag(40))
+ else if (!R2_GLOBALS.getFlag(25))
SceneItem::display2(500, 40);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 512;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(26);
}
} else {
@@ -4877,7 +4912,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 515;
- scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(28);
}
return true;
@@ -4887,12 +4922,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
return true;
default:
- if (action < R2_LAST_INVENT) {
- SceneItem::display2(500, action);
- return true;
- } else {
- return SceneActor::startAction(action, event);
- }
+ return SceneActor::startAction(action, event);
}
}
@@ -4908,7 +4938,7 @@ bool Scene500::Doorway::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 500;
- scene->setAction(&scene->_sequenceManager1, scene, 500, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 500, &R2_GLOBALS._player, this, NULL);
}
return true;
@@ -4960,7 +4990,7 @@ bool Scene500::AirLock::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
- &scene->_object2, &scene->_airLock, NULL);
+ &scene->_seeker, &scene->_airLock, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -4986,7 +5016,7 @@ bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 520 : 502;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -5029,7 +5059,36 @@ bool Scene500::Locker2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+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);
+
+ _button1.setupButton(1);
+ _button2.setupButton(2);
+ _button3.setupButton(3);
+}
+
+void Scene500::PanelDialog::remove() {
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.remove(&_button1);
+ scene->_sceneAreas.remove(&_button2);
+ scene->_sceneAreas.remove(&_button3);
+
+ _button1.remove();
+ _button2.remove();
+ _button3.remove();
+
+ SceneAreaObject::remove();
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 511;
+ scene->setAction(&scene->_sequenceManager1, scene, 511, &R2_GLOBALS._player, NULL);
+}
+
+bool Scene500::PanelDialog::Button::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
return false;
} else {
@@ -5037,6 +5096,119 @@ bool Scene500::Object::startAction(CursorType action, Event &event) {
}
}
+void Scene500::PanelDialog::Button::setupButton(int buttonId) {
+ _buttonId = buttonId;
+ _buttonDown = false;
+ SceneActor::postInit();
+ setup(500, 7, 1);
+ fixPriority(251);
+
+ switch (_buttonId) {
+ case 1:
+ setPosition(Common::Point(139, 78));
+ break;
+ case 2:
+ setPosition(Common::Point(139, 96));
+ break;
+ case 3:
+ setPosition(Common::Point(139, 114));
+ break;
+ default:
+ break;
+ }
+
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.push_front(this);
+}
+
+void Scene500::PanelDialog::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_buttonDown);
+}
+
+void Scene500::PanelDialog::Button::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) &&
+ (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ _bounds.contains(event.mousePos) && !_buttonDown) {
+ _buttonDown = true;
+ event.handled = true;
+ setFrame(2);
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ setFrame(1);
+ _buttonDown = false;
+ event.handled = true;
+
+ doButtonPress();
+ }
+}
+
+void Scene500::PanelDialog::Button::doButtonPress() {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS.getFlag(28)) {
+ SceneItem::display2(500, 48);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = _buttonId;
+
+ switch (_buttonId) {
+ case 1:
+ if (--R2_GLOBALS._landerSuitNumber == 0)
+ R2_GLOBALS._landerSuitNumber = 3;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 5;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 2:
+ if (++R2_GLOBALS._landerSuitNumber == 4)
+ R2_GLOBALS._v566A4 = 1;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 6;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, 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);
+ } else {
+ scene->_suit.postInit();
+ scene->_suit.hide();
+ scene->_suit._effect = 1;
+ 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.setFlag(35);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
void Scene500::postInit(SceneObjectList *OwnerList) {
@@ -5055,27 +5227,27 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._walkRegions.disableRegion(1);
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(1505, 1, 1);
- _object2._moveDiff.x = 5;
- _object2.setPosition(Common::Point(42, 151));
- _object2.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _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) {
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
- _object2.setPosition(Common::Point(42, 151));
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _seeker.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
+ _seeker.setPosition(Common::Point(42, 151));
R2_GLOBALS._walkRegions.disableRegion(1);
R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._walkRegions.disableRegion(3);
- _object2.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
+ _seeker.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
}
}
- if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 500) && R2_GLOBALS.getFlag(27)) {
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 500) && R2_GLOBALS.getFlag(27)) {
_tanks1.postInit();
_tanks1.setup(502, 7, 1);
_tanks1.setPosition(Common::Point(281, 120));
@@ -5151,16 +5323,16 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
} else {
_object8.setup(500, 8, 7);
- _object3.postInit();
- _object3._effect = 1;
- _object3.setPosition(Common::Point(247, 52));
- _object3.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ _suit.postInit();
+ _suit._effect = 1;
+ _suit.setPosition(Common::Point(247, 52));
+ _suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
if (!R2_GLOBALS.getFlag(26)) {
if (R2_GLOBALS.getFlag(28))
- _object3.setup(502, 7, 2);
+ _suit.setup(502, 7, 2);
else
- _object3.setup(502, R2_GLOBALS._v566A3 + 2, 7);
+ _suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 7);
}
}
@@ -5206,7 +5378,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 6:
@@ -5215,7 +5387,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_5, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 7:
@@ -5223,14 +5395,14 @@ void Scene500::signal() {
_object8.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 500:
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 501:
- if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 500) {
_stripNumber = 1100;
_sceneMode = 523;
setAction(&_sequenceManager1, this, 523, &R2_GLOBALS._player, NULL);
@@ -5261,7 +5433,7 @@ void Scene500::signal() {
break;
case 506:
case 518:
- R2_GLOBALS.setFlag(11);
+ R2_GLOBALS.setFlag(12);
R2_GLOBALS._player.enableControl();
break;
case 507:
@@ -5271,12 +5443,12 @@ void Scene500::signal() {
break;
case 509:
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 510:
R2_GLOBALS._player.enableControl();
- _area1.setDetails(500, 6, 1, Common::Point(160, 120));
+ _panelDialog.setDetails(500, 6, 1, Common::Point(160, 120));
R2_GLOBALS._player.enableControl();
break;
case 513:
@@ -5338,28 +5510,16 @@ void Scene525::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 600 -
+ * Scene 600 - Drive Room
*
*--------------------------------------------------------------------------*/
-Scene600::Scene600() {
- _field412 = 0;
- for (int i = 0; i < 256; i++)
- _fieldAD2[i] = 0;
-}
-
-void Scene600::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- for (int i = 0; i < 256; i++)
- s.syncAsByte(_fieldAD2[i]);
-}
-
-bool Scene600::Item1::startAction(CursorType action, Event &event) {
+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, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ 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;
}
@@ -5368,12 +5528,14 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
if ((R2_GLOBALS.getFlag(5)) && (!R2_GLOBALS.getFlag(8))) {
- SceneItem::display(600, 32, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ 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, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ if (!R2_GLOBALS.getFlag(5)) {
+ 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;
}
@@ -5385,35 +5547,52 @@ 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->_actor3.postInit();
- scene->_actor2.postInit();
+ scene->_stasisField.postInit();
+ scene->_computer.postInit();
scene->_sceneMode = 612;
- setAction(&scene->_sequenceManager1, this, 612, &scene->_actor3, &scene->_actor2, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_stasisField, &scene->_computer, &R2_GLOBALS._player, NULL);
return true;
}
-void Scene600::Actor4::signal() {
- Common::Point pt(36, 177 + R2_GLOBALS._randomSource.getRandomNumber(5));
+void Scene600::Smoke::signal() {
+ Common::Point pt(177 + R2_GLOBALS._randomSource.getRandomNumber(5),
+ 108 + R2_GLOBALS._randomSource.getRandomNumber(3));
NpcMover *mover = new NpcMover();
addMover(mover, &pt, this);
}
-bool Scene600::Actor4::startAction(CursorType action, Event &event) {
- if ((action >= CURSOR_WALK) && (action < R2CURSORS_START))
+bool Scene600::Smoke::startAction(CursorType action, Event &event) {
+ if (action >= CURSOR_WALK)
// Only action cursors
return SceneActor::startAction(action, event);
return false;
}
-void Scene600::Actor4::draw() {
- warning("TODO: Actor4::draw()");
- SceneActor::draw();
+GfxSurface Scene600::Smoke::getFrame() {
+ GfxSurface frame = SceneActor::getFrame();
+
+ if (_effect) {
+ // Translate the frame using the scene's pixel map
+ byte *pixelMap = static_cast<Scene600 *>(R2_GLOBALS._sceneManager._scene)->_pixelMap;
+ Graphics::Surface surface = frame.lockSurface();
+ byte *srcP = (byte *)surface.getPixels();
+
+ while (srcP < ((byte *)surface.getBasePtr(0, surface.h))) {
+ *srcP = pixelMap[*srcP];
+ srcP++;
+ }
+
+ frame.unlockSurface();
+ }
+
+ return frame;
}
-bool Scene600::Actor5::startAction(CursorType action, Event &event) {
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START))
+bool Scene600::Doorway::startAction(CursorType action, Event &event) {
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
if (action != CURSOR_USE)
@@ -5423,10 +5602,10 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) {
if ((R2_INVENTORY.getObjectScene(R2_CLAMP) == 600) && (!R2_GLOBALS.getFlag(6))) {
R2_GLOBALS._player.disableControl();
- scene->_actor6.setDetails(600, 11, -1, -1, 3, (SceneItem *) NULL);
+ 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->_actor5, &scene->_actor6, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, &scene->_actor1, NULL);
return true;
}
@@ -5436,7 +5615,7 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) {
if (!R2_GLOBALS.getFlag(6)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 616;
- scene->setAction(&scene->_sequenceManager1, scene, 616, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor6, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 616, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, NULL);
return true;
}
@@ -5445,27 +5624,28 @@ bool Scene600::Actor5::startAction(CursorType action, Event &event) {
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 601;
- scene->setAction(&scene->_sequenceManager1, scene, 601, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 601, &R2_GLOBALS._player, &scene->_doorway, NULL);
}
return true;
}
-bool Scene600::Actor6::startAction(CursorType action, Event &event) {
+bool Scene600::Laser::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ if (action < CURSOR_WALK) {
switch (action) {
case R2_COM_SCANNER:
+ // 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);
return true;
} else {
R2_GLOBALS._player.disableControl();
- scene->_actor8.postInit();
- scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_actor6);
+ scene->_scanner.postInit();
+ scene->_scanner.setDetails(600, 20, -1, -1, 4, &scene->_laser);
scene->_sceneMode = 607;
- scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_scanner, NULL);
return true;
}
} else {
@@ -5478,28 +5658,29 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) {
return true;
} else {
R2_GLOBALS._player.disableControl();
- scene->_actor7.postInit();
- scene->_actor7.setDetails(600, 27, -1, -1, 5, &scene->_actor6);
+ scene->_aerosol.postInit();
+ scene->_aerosol.setDetails(600, 27, -1, -1, 5, &scene->_laser);
- scene->_actor4.postInit();
- scene->_actor4.setup(601, 3, 1);
- scene->_actor4._effect = 3;
- scene->_actor4._moveDiff = Common::Point(1, 1);
- scene->_actor4._moveRate = 2;
- scene->_actor4._numFrames = 3;
- scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_actor7);
+ scene->_smoke.postInit();
+ scene->_smoke.setup(601, 3, 1);
+ scene->_smoke._effect = 3;
+ scene->_smoke._moveDiff = Common::Point(1, 1);
+ scene->_smoke._moveRate = 2;
+ scene->_smoke._numFrames = 3;
+ scene->_smoke.setDetails(600, 24, 25, 26, 5, &scene->_aerosol);
scene->_sceneMode = 605;
- scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_actor7, &scene->_actor4, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_smoke, &scene->_doorway, NULL);
return true;
}
break;
case R2_CLAMP:
+ // If cloud is active
if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 606;
- scene->setAction(&scene->_sequenceManager1, scene, 606, &R2_GLOBALS._player, &scene->_actor6, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 606, &R2_GLOBALS._player, &scene->_laser, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -5509,7 +5690,7 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) {
return false;
break;
}
- } else if (action != CURSOR_USE) {
+ } else if (action == CURSOR_USE) {
if (R2_GLOBALS.getFlag(5)) {
return SceneActor::startAction(action, event);
} else {
@@ -5522,32 +5703,49 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene600::Actor7::startAction(CursorType action, Event &event) {
+bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
- } else if (action == CURSOR_USE) {
+
+ if (action == CURSOR_USE) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 614;
- scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_aerosol, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
}
}
-bool Scene600::Actor8::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+Scene600::Scene600() {
+ _field412 = 0;
+ Common::fill(&_pixelMap[0], &_pixelMap[256], 0);
+}
+
+void Scene600::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ for (int i = 0; i < 256; i++)
+ s.syncAsByte(_pixelMap[i]);
+}
+
+bool Scene600::Scanner::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(9) == 600)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 615;
- scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_actor8, NULL);
- } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._v565F1[1] == 2) && (!R2_GLOBALS.getFlag(8))){
+ scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_scanner, NULL);
+ } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 608;
- scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_smoke, NULL);
} else {
return SceneActor::startAction(action, event);
}
@@ -5562,23 +5760,31 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(3);
_field412 = 0;
- warning("FIXME: loop to initialize _fieldAD2[]");
+ // Initialize pixel map for the obscuring effect
+ ScenePalette &pal = R2_GLOBALS._scenePalette;
+ uint r, g, b;
+ for (int i = 0; i < 256; ++i) {
+ pal.getEntry(i, &r, &g, &b);
+ int av = ((r + g + b) / 48);
- _actor5.postInit();
- _actor5.setVisage(600);
- _actor5.setPosition(Common::Point(29, 147));
- _actor5.fixPriority(10);
- _actor5.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL);
+ _pixelMap[i] = R2_GLOBALS._paletteMap[(av << 8) | (av << 4) | av];
+ }
- _actor6.postInit();
- _actor6.setPosition(Common::Point(246, 41));
-
- if (R2_INVENTORY.getObjectScene(9) == 600) {
- _actor8.postInit();
- _actor8.setup(602, 5, 1);
- _actor8.setPosition(Common::Point(246, 41));
- _actor8.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
- switch (R2_GLOBALS._v565F1[1] - 2) {
+ _doorway.postInit();
+ _doorway.setVisage(600);
+ _doorway.setPosition(Common::Point(29, 147));
+ _doorway.fixPriority(10);
+ _doorway.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _laser.postInit();
+ _laser.setPosition(Common::Point(246, 41));
+
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) {
+ _scanner.postInit();
+ _scanner.setup(602, 5, 1);
+ _scanner.setPosition(Common::Point(246, 41));
+ _scanner.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
+ switch (R2_GLOBALS._scannerFrequencies[1] - 2) {
case 0:
R2_GLOBALS._sound4.play(45);
break;
@@ -5597,11 +5803,11 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS.getFlag(6)) {
- _actor6.setup(602, 7, 1);
- _actor6.setDetails(600, 11, -1, -1, 1, (SceneItem *) NULL);
+ _laser.setup(602, 7, 1);
+ _laser.setDetails(600, 11, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor6.setup(600, 2, 1);
- _actor6.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL);
+ _laser.setup(600, 2, 1);
+ _laser.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL);
_actor1.postInit();
_actor1.setup(600, 3, 5);
@@ -5613,32 +5819,34 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_object1.setup2(603, 1, 1, 244, 50, 10, 0);
if (R2_GLOBALS.getFlag(5)) {
- if (R2_INVENTORY.getObjectScene(12) == 600) {
- _actor7.postInit();
- _actor7.setup(602, 2, 2);
- _actor7.setPosition(Common::Point(189, 95));
- _actor7.setDetails(600, 27, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_AEROSOL) == 600) {
+ _aerosol.postInit();
+ _aerosol.setup(602, 2, 2);
+ _aerosol.setPosition(Common::Point(189, 95));
+ _aerosol.setDetails(600, 27, -1, -1, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS.getFlag(8)) {
if (R2_GLOBALS.getFlag(9)) {
- _actor2.postInit();
- _actor2.setup(603, 2, 1);
- _actor2.setPosition(Common::Point(233, 45));
- _actor2.animate(ANIM_MODE_2, NULL);_actor2.fixPriority(11);
+ // Computer is active
+ _computer.postInit();
+ _computer.setup(603, 2, 1);
+ _computer.setPosition(Common::Point(233, 45));
+ _computer.animate(ANIM_MODE_2, NULL);
+ _computer.fixPriority(11);
}
} else {
- _actor4.postInit();
- _actor4.setup(601, 1, 1);
- _actor4.setPosition(Common::Point(180, 110));
- _actor4._moveDiff = Common::Point(1, 1);
- _actor4._moveRate = 2;
- _actor4._numFrames = 3;
- _actor4.animate(ANIM_MODE_2, NULL);
- _actor4.fixPriority(130);
- _actor4._effect = 3;
- _actor4.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
- _actor4.signal();
+ _smoke.postInit();
+ _smoke.setup(601, 1, 1);
+ _smoke.setPosition(Common::Point(180, 110));
+ _smoke._moveDiff = Common::Point(1, 1);
+ _smoke._moveRate = 2;
+ _smoke._numFrames = 3;
+ _smoke.animate(ANIM_MODE_2, NULL);
+ _smoke.fixPriority(130);
+ _smoke._effect = 3;
+ _smoke.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
+ _smoke.signal();
}
}
@@ -5651,30 +5859,30 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_item3.setDetails(11, 600, 14, -1, -1);
if (R2_GLOBALS.getFlag(9)) {
- _item1.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
+ _background.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);
- _item1.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
+ _background.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);
_sceneMode = 600;
if (R2_GLOBALS._sceneManager._previousScene == 700) {
if (R2_GLOBALS.getFlag(6)) {
- setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_doorway, NULL);
} else if (R2_GLOBALS.getFlag(5)) {
- setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL);
} else {
- setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL);
}
} else if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.setPosition(Common::Point(50, 140));
R2_GLOBALS._player.setStrip(3);
- _actor6.setFrame(_actor6.getFrameCount());
+ _laser.setFrame(_laser.getFrameCount());
signal();
} else {
- _actor5.setFrame(7);
- _actor6.setFrame(7);
+ _doorway.setFrame(7);
+ _laser.setFrame(7);
R2_GLOBALS._player.setPosition(Common::Point(28, 140));
R2_GLOBALS._player.setStrip(5);
signal();
@@ -5682,7 +5890,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
}
void Scene600::remove() {
- if (R2_INVENTORY.getObjectScene(9) == 600)
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)
R2_GLOBALS._sound4.fadeOut2(NULL);
SceneExt::remove();
}
@@ -5697,51 +5905,58 @@ void Scene600::signal() {
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 605:
+ // After cloud is active
R2_GLOBALS._player.enableControl();
R2_GLOBALS._walkRegions.enableRegion(6);
R2_GLOBALS._walkRegions.enableRegion(7);
R2_GLOBALS._walkRegions.enableRegion(9);
R2_GLOBALS._walkRegions.enableRegion(10);
- R2_INVENTORY.setObjectScene(12, 600);
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 600);
R2_GLOBALS.setFlag(5);
- _actor4._effect = 3;
- _actor4.signal();
+ _smoke._effect = 3;
+ _smoke.signal();
break;
case 606:
- R2_INVENTORY.setObjectScene(15, 600);
+ // After Clamp is put on laser
+ R2_INVENTORY.setObjectScene(R2_CLAMP, 600);
R2_GLOBALS._player.enableControl();
break;
case 607:
- R2_INVENTORY.setObjectScene(9, 600);
+ // After scanner is put on laser
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 600);
R2_GLOBALS._player.enableControl();
break;
case 608:
+ // deactivate cloud
R2_GLOBALS.setFlag(8);
- _actor4.remove();
+ _smoke.remove();
R2_GLOBALS._walkRegions.disableRegion(6);
R2_GLOBALS._walkRegions.disableRegion(9);
R2_GLOBALS._walkRegions.disableRegion(10);
R2_GLOBALS._player.enableControl();
break;
case 612:
+ // Deactivate stasis field
R2_GLOBALS.setFlag(9);
- _actor3.remove();
+ _stasisField.remove();
R2_GLOBALS._sceneItems.remove(&_item4);
- _actor2.setDetails(600, 21, -1, 23, 4, &_item4);
- _item1.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ _computer.setDetails(600, 21, -1, 23, 4, &_item4);
+ _background.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
case 614:
+ // Pick up Aerosol
R2_GLOBALS._player.enableControl();
- _actor7.remove();
- R2_INVENTORY.setObjectScene(12, 1);
+ _aerosol.remove();
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 1);
R2_GLOBALS._walkRegions.disableRegion(7);
break;
case 615:
- _actor8.remove();
- R2_INVENTORY.setObjectScene(9, 1);
+ // Pick up Com Scanner
+ _scanner.remove();
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 1);
R2_GLOBALS._player.enableControl();
break;
default:
@@ -5753,8 +5968,9 @@ void Scene600::signal() {
}
void Scene600::process(Event &event) {
- if ((!R2_GLOBALS._player._canWalk) && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
- if (!_actor5.contains(event.mousePos) || (_actor5._frame <= 1)) {
+ 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;
} else {
@@ -5766,7 +5982,7 @@ void Scene600::process(Event &event) {
} else {
R2_GLOBALS._player.disableControl();
_sceneMode = 613;
- setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_laser, NULL);
event.handled = true;
}
} else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_field412 < 10)){
@@ -5778,9 +5994,9 @@ void Scene600::process(Event &event) {
void Scene600::dispatch() {
if ((_field412 != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
- if ( ((_actor6._strip == 4) && (_actor6._frame > 1))
+ if ( ((_laser._strip == 4) && (_laser._frame > 1))
|| (_sceneMode == 601)
- || ((_sceneMode == 616) && (_actor5._frame > 1)) )
+ || ((_sceneMode == 616) && (_doorway._frame > 1)) )
_field412 = 0;
else {
_field412--;
@@ -5796,14 +6012,14 @@ void Scene600::dispatch() {
_aSound1.play(40);
Scene::dispatch();
- if ((_actor4._strip == 3) && (_actor4._frame == 3)) {
+ if ((_smoke._strip == 3) && (_smoke._frame == 3)) {
_actor1.setStrip(4);
_actor1.setFrame(1);
}
}
/*--------------------------------------------------------------------------
- * Scene 700 -
+ * Scene 700 - Lander Bay 2
*
*--------------------------------------------------------------------------*/
Scene700::Scene700() {
@@ -5822,26 +6038,26 @@ bool Scene700::Item11::startAction(CursorType action, Event &event) {
return NamedHotspot::startAction(action, event);
}
-bool Scene700::Item12::startAction(CursorType action, Event &event) {
+bool Scene700::HandGrip::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case R2_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 3, 2);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 3, 2);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 20;
break;
case R2_ATTRACTOR_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 2, 8);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 2, 8);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 21;
break;
default:
@@ -5849,7 +6065,7 @@ bool Scene700::Item12::startAction(CursorType action, Event &event) {
break;
}
- scene->setAction(&scene->_sequenceManager, this, 707, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_cable, NULL);
return true;
}
@@ -5901,7 +6117,7 @@ bool Scene700::Actor4::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor5::startAction(CursorType action, Event &event) {
+bool Scene700::Cable::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -5910,7 +6126,7 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) {
case 0:
if ((_strip == 2) && (_frame == 1)) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._position.x <= 100) {
+ if (R2_GLOBALS._player._position.y <= 100) {
scene->_sceneMode = 710;
scene->setAction(&scene->_sequenceManager, scene, 710, &R2_GLOBALS._player, this, NULL);
} else {
@@ -5935,9 +6151,9 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) {
break;
case R2_ATTRACTOR_UNIT:
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) {
+ if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 700) {
scene->_sceneMode = 706;
- scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_cable, NULL);
} else {
scene->_sceneMode = 15;
Common::Point pt(_position.x - 12, _position.y + 1);
@@ -5969,10 +6185,10 @@ bool Scene700::Actor6::startAction(CursorType action, Event &event) {
}
void Scene700::postInit(SceneObjectList *OwnerList) {
+ loadScene(700);
if (R2_GLOBALS._sceneManager._previousScene == 900)
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ _sceneBounds = Rect(160, 0, 480, 200);
- loadScene(700);
R2_GLOBALS._v558B6.set(60, 0, 260, 200);
SceneExt::postInit();
@@ -5994,7 +6210,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor1.postInit();
_actor1.setup(700, 4, 1);
- _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._v565E3 * 8) / 5), ((R2_GLOBALS._v565E1 + 20 ) / 5) - 12));
+ _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);
@@ -6019,20 +6235,20 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _actor5.postInit();
- _actor5.fixPriority(10);
+ _cable.postInit();
+ _cable.fixPriority(10);
switch (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS)) {
case 0:
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
- _actor5.setup(701, 3, 2);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 2);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 3, 1);
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 1);
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6041,23 +6257,23 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
case 700:
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
- _actor5.setup(701, 2, 1);
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ _cable.setup(701, 2, 1);
else
- _actor5.setup(701, 2, 8);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.fixPriority(77);
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 2, 8);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.fixPriority(77);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 1, 8);
+ _cable.setup(701, 1, 8);
if (R2_GLOBALS._v565E7 == 0) {
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
} else {
- _actor5.setup(701, 1, 1);
- _actor5.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
+ _cable.setup(701, 1, 1);
+ _cable.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
}
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6072,7 +6288,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor4.setPosition(Common::Point(454, 117));
_actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
- _item12.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, 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);
@@ -6158,9 +6374,7 @@ void Scene700::signal() {
}
break;
case 3:
- R2_INVENTORY.setObjectScene(5, 600);
- R2_INVENTORY.setObjectScene(16, 700);
- R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._sceneManager.changeScene(600);
break;
case 4:
_sceneMode = 5;
@@ -6179,7 +6393,7 @@ void Scene700::signal() {
break;
case 11:
_sceneMode = 12;
- _actor5.remove();
+ _cable.remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
case 12:
@@ -6204,13 +6418,13 @@ void Scene700::signal() {
break;
case 16:
_sceneMode = 17;
- _actor5.setup(701, 1, 8);
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._v565E1 + 10) / 5) * 4))) {
- _actor5.animate(ANIM_MODE_6, NULL);
- Common::Point pt(_actor5._position.x, _actor1._position.y + 120);
+ _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))) {
+ _cable.animate(ANIM_MODE_6, NULL);
+ Common::Point pt(_cable._position.x, _actor1._position.y + 120);
NpcMover *mover = new NpcMover();
- _actor5.addMover(mover, &pt, NULL);
+ _cable.addMover(mover, &pt, NULL);
R2_GLOBALS._v565E7 = 1;
}
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
@@ -6230,9 +6444,9 @@ void Scene700::signal() {
R2_GLOBALS._player.enableControl();
break;
case 21:
- _actor5.fixPriority(77);
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _cable.fixPriority(77);
+ if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
@@ -6247,10 +6461,10 @@ void Scene700::signal() {
R2_GLOBALS._sceneManager.changeScene(900);
break;
case 706:
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- _actor5.fixPriority(77);
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _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))
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
@@ -6317,12 +6531,26 @@ bool Scene800::DeviceSlot::startAction(CursorType action, Event &event) {
break;
R2_GLOBALS._player.disableControl();
- scene->_reader.postInit();
+ _lookLineNum = 27;
+ scene->_sceneMode = 809;
if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800)
- scene->setAction(&scene->_sequenceManager1, scene, 814, &R2_GLOBALS._player, &scene->_reader, &scene->_opticalFibre, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 815, &R2_GLOBALS._player, &scene->_reader, &scene->_opticalFibre, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 804, &R2_GLOBALS._player, &scene->_reader, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 809, &R2_GLOBALS._player, &scene->_reader, NULL);
+ return true;
+ case R2_READER:
+ R2_GLOBALS._player.disableControl();
+ scene->_reader.postInit();
+ scene->_sceneMode = 804;
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800) {
+ 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->_reader, NULL);
+ }
return true;
default:
break;
@@ -6416,8 +6644,8 @@ bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
void Scene800::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(800);
+ SceneExt::postInit();
_door.postInit();
_door.setVisage(800);
@@ -6826,8 +7054,9 @@ void Scene825::doButtonPress(int buttonId) {
_sceneText.setup(NO_TREATMENT_REQUIRED);
} else {
_button6._buttonId = 5;
-
+ _sceneMode = 827;
_object5.postInit();
+
setAction(&_sequenceManager1, this, 827, &_object5, NULL);
}
} else {
@@ -7006,8 +7235,8 @@ bool Scene850::Panel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
void Scene850::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(850);
+ SceneExt::postInit();
_liftDoor.postInit();
_liftDoor.setup(850, 2, 1);
@@ -7103,44 +7332,47 @@ void Scene850::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 900 -
+ * Scene 900 - Lander Bay 2 - Crane Controls
*
*--------------------------------------------------------------------------*/
-Scene900::Actor4::Actor4() {
- _fieldA4 = 0;
+
+Scene900::Button::Button() {
+ _buttonId = 0;
}
-void Scene900::Actor4::synchronize(Serializer &s) {
+void Scene900::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_buttonId);
}
-void Scene900::Actor4::sub96135(int arg1) {
- _fieldA4 = arg1;
+
+void Scene900::Button::initButton(int buttonId) {
+ _buttonId = buttonId;
+ postInit();
setDetails(900, -1, -1, -1, 2, (SceneItem *) NULL);
}
Scene900::Scene900() {
_field412 = 0;
- _field414 = 0;
- _field416 = 0;
+ _magnetChangeAmount.x = 0;
+ _magnetChangeAmount.y = 0;
}
void Scene900::synchronize(Serializer &s) {
SceneExt::synchronize(s);
s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_magnetChangeAmount.x);
+ s.syncAsSint16LE(_magnetChangeAmount.y);
}
-bool Scene900::Actor4::startAction(CursorType action, Event &event) {
+bool Scene900::Button::startAction(CursorType action, Event &event) {
Scene900 *scene = (Scene900 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_USE) {
R2_GLOBALS._sound2.play(14);
- switch (_fieldA4) {
+ switch (_buttonId) {
case 2:
if (scene->_field412 == 1) {
scene->_sceneMode = 2;
@@ -7150,15 +7382,15 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
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._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) {
+ 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);
} else {
- if (((scene->_actor3._percent * 49) / 100) + scene->_actor3._position.x == scene->_actor2._position.x) {
- if (scene->_actor2._position.x == 166 - (R2_GLOBALS._v565E3 / 15)) {
+ if (((scene->_electromagnet._percent * 49) / 100) + scene->_electromagnet._position.x == scene->_actor2._position.x) {
+ if (scene->_actor2._position.x == 166 - (R2_GLOBALS._electromagnetZoom / 15)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 4;
- scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2)) / 9;
- Common::Point pt(scene->_actor3._position.x + ((scene->_actor3._percent * 49) / 100), scene->_actor3._position.y + ((scene->_actor3._percent * 3) / 10) - 2);
+ scene->_actor2._moveDiff.y = (scene->_actor2._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);
@@ -7179,7 +7411,7 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
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._v565E3 / 15));
+ Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._electromagnetZoom / 15));
NpcMover *mover = new NpcMover();
scene->_actor2.addMover(mover, &pt, this);
}
@@ -7196,30 +7428,30 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
return true;
break;
case 4:
- if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 != 0)) {
+ if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetZoom != 0)) {
scene->_aSound1.play(38);
- scene->_field416 = -5;
+ scene->_magnetChangeAmount.y = -5;
}
return true;
break;
case 5:
- if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E3 < 135)) {
+ if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetZoom < 135)) {
scene->_aSound1.play(38);
- scene->_field416 = 5;
+ scene->_magnetChangeAmount.y = 5;
}
return true;
break;
case 6:
- if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 > -10)) {
+ if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetChangeAmount > -10)) {
scene->_aSound1.play(38);
- scene->_field414 = -5;
+ scene->_magnetChangeAmount.x = -5;
}
return true;
break;
case 7:
- if ((scene->_field416 == 0) && (scene->_field414 == 0) && (R2_GLOBALS._v565E1 < 20)) {
+ if ((scene->_magnetChangeAmount.y == 0) && (scene->_magnetChangeAmount.x == 0) && (R2_GLOBALS._electromagnetChangeAmount < 20)) {
scene->_aSound1.play(38);
- scene->_field414 = 5;
+ scene->_magnetChangeAmount.x = 5;
}
return true;
break;
@@ -7234,12 +7466,12 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
default:
if (scene->_field412 == 1) {
R2_GLOBALS._player.disableControl();
- scene->_actor5.remove();
- scene->_actor6.remove();
- scene->_actor7.remove();
- scene->_actor8.remove();
- scene->_actor9.remove();
- scene->_actor10.remove();
+ scene->_button2.remove();
+ scene->_button3.remove();
+ scene->_button4.remove();
+ scene->_button5.remove();
+ scene->_button6.remove();
+ scene->_button7.remove();
R2_GLOBALS._sound2.play(37);
scene->_sceneMode = 901;
scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_actor1, this ,NULL);
@@ -7252,10 +7484,8 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
break;
}
} else if (action == CURSOR_LOOK) {
- if ((_fieldA4 == 2) && (scene->_field412 == 2))
- SceneItem::display(900, 21, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- else
- SceneItem::display(900, _fieldA4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ 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);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -7275,16 +7505,15 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_actor1.postInit();
_actor1.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
- _field414 = 0;
- _field416 = 0;
+ _magnetChangeAmount.x = 0;
+ _magnetChangeAmount.y = 0;
- _actor3.postInit();
- _actor3.fixPriority(1);
- // useless, the original use it for debugging purposes: strcpy(_actor3._actorName, "Crane");
- _actor3.setup(900, 1, 2);
- _actor3.setPosition(Common::Point(89, 0));
- _actor3._effect = 1;
- _actor3.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL);
+ _electromagnet.postInit();
+ _electromagnet.fixPriority(1);
+ _electromagnet.setup(900, 1, 2);
+ _electromagnet.setPosition(Common::Point(89, 0));
+ _electromagnet._effect = 1;
+ _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();
@@ -7294,7 +7523,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
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._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) {
+ } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
_actor2.setup(901, 2, 1);
} else {
_actor2.setup(901, 2, 8);
@@ -7306,7 +7535,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._v565E7 == 0) {
_actor2.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 * _actor3._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3)));
+ _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);
}
}
@@ -7329,68 +7558,68 @@ void Scene900::signal() {
_field412 = 1;
R2_GLOBALS._sound2.play(37);
- _actor5.remove();
- _actor6.remove();
- _actor7.remove();
- _actor8.remove();
- _actor9.remove();
- _actor10.remove();
+ _button2.remove();
+ _button3.remove();
+ _button4.remove();
+ _button5.remove();
+ _button6.remove();
+ _button7.remove();
- _actor5.sub96135(2);
- _actor5.setup(900, 2, 1);
- _actor5.setPosition(Common::Point(36, 166));
+ _button2.initButton(2);
+ _button2.setup(900, 2, 1);
+ _button2.setPosition(Common::Point(36, 166));
- _actor6.sub96135(3);
- _actor6.setup(900, 2, 5);
- _actor6.setPosition(Common::Point(117, 166));
+ _button3.initButton(3);
+ _button3.setup(900, 2, 5);
+ _button3.setPosition(Common::Point(117, 166));
break;
case 2:
_field412 = 2;
- _actor5.remove();
- _actor6.remove();
+ _button2.remove();
+ _button3.remove();
- _actor5.sub96135(2);
+ _button2.initButton(2);
if (R2_GLOBALS._v565E5 == 0)
- _actor5.setup(900, 3, 9);
+ _button2.setup(900, 3, 9);
else
- _actor5.setup(900, 3, 11);
- _actor5.setPosition(Common::Point(36, 166));
+ _button2.setup(900, 3, 11);
+ _button2.setPosition(Common::Point(36, 166));
- _actor7.sub96135(5);
- _actor7.setup(900, 3, 3);
- _actor7.setPosition(Common::Point(76, 134));
+ _button4.initButton(5);
+ _button4.setup(900, 3, 3);
+ _button4.setPosition(Common::Point(76, 134));
- _actor8.sub96135(4);
- _actor8.setup(900, 3, 7);
- _actor8.setPosition(Common::Point(76, 156));
+ _button5.initButton(4);
+ _button5.setup(900, 3, 7);
+ _button5.setPosition(Common::Point(76, 156));
- _actor9.sub96135(6);
- _actor9.setup(900, 3, 1);
- _actor9.setPosition(Common::Point(55, 144));
+ _button6.initButton(6);
+ _button6.setup(900, 3, 1);
+ _button6.setPosition(Common::Point(55, 144));
- _actor10.sub96135(7);
- _actor10.setup(900, 3, 5);
- _actor10.setPosition(Common::Point(99, 144));
+ _button7.initButton(7);
+ _button7.setup(900, 3, 5);
+ _button7.setPosition(Common::Point(99, 144));
break;
case 3:
_field412 = 3;
- _actor5.remove();
- _actor6.remove();
- _actor7.remove();
- _actor8.remove();
- _actor9.remove();
- _actor10.remove();
+ _button2.remove();
+ _button3.remove();
+ _button4.remove();
+ _button5.remove();
+ _button6.remove();
+ _button7.remove();
- _actor5.sub96135(8);
- _actor5.setup(900, 4, 1);
- _actor5.setPosition(Common::Point(36, 166));
+ _button2.initButton(8);
+ _button2.setup(900, 4, 1);
+ _button2.setPosition(Common::Point(36, 166));
- _actor6.sub96135(9);
- _actor6.setup(900, 4, 5);
- _actor6.setPosition(Common::Point(117, 166));
+ _button3.initButton(9);
+ _button3.setup(900, 4, 5);
+ _button3.setPosition(Common::Point(117, 166));
break;
case 4:
_sceneMode = 0;
@@ -7404,9 +7633,9 @@ void Scene900::signal() {
_actor1.setup(900, 1, 1);
- _actor4.sub96135(1);
- _actor4.setup(900, 1, 3);
- _actor4.setPosition(Common::Point(77, 168));
+ _button1.initButton(1);
+ _button1.setup(900, 1, 3);
+ _button1.setPosition(Common::Point(77, 168));
_sceneMode = 1;
signal();
@@ -7425,26 +7654,28 @@ void Scene900::signal() {
}
void Scene900::dispatch() {
- if (_field416 != 0) {
- if (_field416 < 0) {
- R2_GLOBALS._v565E3--;
- ++_field416;
+ if (_magnetChangeAmount.y != 0) {
+ if (_magnetChangeAmount.y < 0) {
+ R2_GLOBALS._electromagnetZoom--;
+ ++_magnetChangeAmount.y;
} else {
- ++R2_GLOBALS._v565E3;
- _field416--;
+ ++R2_GLOBALS._electromagnetZoom;
+ _magnetChangeAmount.y--;
}
}
- if (_field414 != 0) {
- R2_GLOBALS._v565E1--;
- ++_field414;
- } else {
- ++R2_GLOBALS._v565E1;
- _field414++;
+ if (_magnetChangeAmount.x != 0) {
+ if (_magnetChangeAmount.x < 0) {
+ R2_GLOBALS._electromagnetChangeAmount--;
+ ++_magnetChangeAmount.x;
+ } else {
+ ++R2_GLOBALS._electromagnetChangeAmount;
+ _magnetChangeAmount.x--;
+ }
}
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._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) {
+ 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);
} else {
@@ -7453,17 +7684,17 @@ void Scene900::dispatch() {
}
}
- _actor3.changeZoom(100 - ((R2_GLOBALS._v565E3 * 70) / 100));
- _actor3.setPosition(Common::Point(((_actor3._percent * R2_GLOBALS._v565E1 * 6) / 100) + 89, R2_GLOBALS._v565E3));
+ _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(_actor3._position.x + ((_actor3._percent * 49) / 100), _actor3._position.y + ((_actor3._percent * 3) / 10)));
- if (R2_GLOBALS._v565E3 >= 75) {
+ _actor2.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(((_actor3._percent + 52) / 10) * 10);
+ _actor2.changeZoom(((_electromagnet._percent + 52) / 10) * 10);
} else {
_actor2.setup(901, 5, 1);
- _actor2.changeZoom(((_actor3._percent / 10) * 10) + 30);
+ _actor2.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 2f52f9578f..df0b4d8fc6 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -102,7 +102,7 @@ public:
class Scene125: public SceneExt {
/* Objects */
- class Object5: public SceneActor {
+ class Food: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -126,7 +126,7 @@ class Scene125: public SceneExt {
};
/* Items */
- class Item4: public NamedHotspot {
+ class DiskSlot: public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -135,8 +135,8 @@ public:
ScenePalette _palette;
ASoundExt _sound1;
NamedHotspot _background, _item2, _item3;
- Item4 _item4;
- SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _object7;
+ DiskSlot _diskSlot;
+ SceneActor _object1, _object2, _object3, _object4, _food, _foodDispenser, _infoDisk;
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
SequenceManager _sequenceManager;
SceneText _sceneText;
@@ -277,9 +277,7 @@ class Scene205: public SceneExt {
public:
int _x100, _y100;
public:
- Object();
-
- virtual void synchronize(Serializer &s);
+ // TODO: Check if this derives from DataManager? and flesh out
};
private:
void setup();
@@ -312,7 +310,7 @@ public:
class Scene250: public SceneExt {
class Button: public SceneActor {
public:
- int _floorNumber, _v2;
+ int _floorNumber;
Button();
void setFloor(int floorNumber);
@@ -320,7 +318,8 @@ class Scene250: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412, _field414, _field416, _field418, _field41A;
+ int _currButtonY, _destButtonY, _elevatorSpeed;
+ bool _skippingFl, _skippableFl;
NamedHotspot _background, _item2, _item3, _item4;
Button _button1, _currentFloor;
Button _floor1, _floor2, _floor3, _floor4, _floor5;
@@ -453,7 +452,7 @@ private:
Common::String parseMessage(const Common::String &msg);
public:
int _field412, _iconFontNumber, _field416, _field418;
- int _field41A, _field41C, _field41E, _field420;
+ int _field41A, _field41C, _field41E, _scannerLocation;
int _soundCount, _soundIndex;
int _soundQueue[10];
SpeakerQuinn _quinnSpeaker;
@@ -461,7 +460,7 @@ public:
SceneHotspot _background, _item2;
SceneObject _object1, _object2, _object3, _object4, _object5;
SceneObject _object6, _object7, _object8, _object9, _object10;
- SceneObject _object11, _object12, _object13;
+ SceneObject _object11, _object12, _scannerTab;
SceneObject _objList[4];
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
ASoundExt _sound1;
@@ -526,6 +525,31 @@ public:
};
class Scene500: public SceneExt {
+ /* Dialogs */
+ class PanelDialog: public SceneAreaObject {
+ class Button: public SceneActor {
+ private:
+ int _buttonId;
+ bool _buttonDown;
+
+ void doButtonPress();
+ public:
+ Button();
+ virtual Common::String getClassName() { return "Scene500_Button"; }
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ virtual void synchronize(Serializer &s);
+
+ void setupButton(int buttonId);
+ };
+ public:
+ Button _button1, _button2, _button3;
+
+ virtual Common::String getClassName() { return "Scene500_PanelWindow"; }
+ virtual void remove();
+ void setDetails(int visage, int strip, int frameNumber, const Common::Point &pt);
+ };
+
/* Items */
class ControlPanel: public SceneHotspot {
public:
@@ -533,11 +557,11 @@ class Scene500: public SceneExt {
};
/* Objects */
- class Object2: public SceneActor {
+ class Seeker: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object3: public SceneActor {
+ class Suit: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -572,20 +596,16 @@ class Scene500: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object: public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
public:
int _stripNumber;
byte _buffer[2710];
- SpeakerSeeker _seekerSpeaker;
- SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker500 _seekerSpeaker;
+ SpeakerQuinn500 _quinnSpeaker;
SceneHotspot _background, _item2;
ControlPanel _controlPanel;
SceneActor _object1;
- Object2 _object2;
- Object3 _object3;
+ Seeker _seeker;
+ Suit _suit;
Doorway _doorway;
OxygenTanks _tanks1, _tanks2;
AirLock _airLock;
@@ -594,8 +614,7 @@ public:
SonicStunner _sonicStunner;
Locker1 _locker1;
Locker2 _locker2;
- SceneAreaObject _area1;
- Object _obj1, _obj2, _obj3;
+ PanelDialog _panelDialog;
ASoundExt _sound1;
SequenceManager _sequenceManager1, _sequenceManager2;
public:
@@ -615,7 +634,7 @@ public:
};
class Scene600 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class CompartmentHotspot : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -624,48 +643,48 @@ class Scene600 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Smoke : public SceneActor {
public:
virtual void signal();
virtual bool startAction(CursorType action, Event &event);
- virtual void draw();
+ virtual GfxSurface getFrame();
};
- class Actor5 : public SceneActor {
+ class Doorway : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Laser : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Aerosol : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class Scanner : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
int _field412;
- Item1 _item1;
- Item1 _item2;
- Item1 _item3;
+ CompartmentHotspot _background;
+ CompartmentHotspot _item2;
+ CompartmentHotspot _item3;
Item4 _item4;
- Item1 _item5;
+ CompartmentHotspot _item5;
BackgroundSceneObject _object1;
SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
+ SceneActor _computer;
+ SceneActor _stasisField;
+ Smoke _smoke;
+ Doorway _doorway;
+ Laser _laser;
+ Aerosol _aerosol;
+ Scanner _scanner;
ASoundExt _aSound1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
- byte _fieldAD2[256];
+ byte _pixelMap[256];
Scene600();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -681,7 +700,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item12 : public NamedHotspot {
+ class HandGrip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -698,7 +717,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Cable : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -718,12 +737,12 @@ public:
NamedHotspot _item9;
NamedHotspot _item10;
Item11 _item11;
- Item12 _item12;
+ HandGrip _handGrip;
SceneActor _actor1;
Actor2 _actor2;
Actor3 _actor3;
Actor4 _actor4;
- Actor5 _actor5;
+ Cable _cable;
Actor6 _actor6;
Actor6 _actor7;
Actor6 _actor8;
@@ -865,30 +884,29 @@ public:
};
class Scene900 : public SceneExt {
- class Actor4 : public SceneActor {
+ class Button : public SceneActor {
public:
- int _fieldA4;
+ int _buttonId;
- Actor4();
- void sub96135(int arg1);
+ Button();
+ void initButton(int buttonId);
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
public:
int _field412;
- int _field414;
- int _field416;
+ Common::Point _magnetChangeAmount;
NamedHotspot _item1;
SceneActor _actor1;
SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor4 _actor5;
- Actor4 _actor6;
- Actor4 _actor7;
- Actor4 _actor8;
- Actor4 _actor9;
- Actor4 _actor10;
+ SceneActor _electromagnet;
+ Button _button1;
+ Button _button2;
+ Button _button3;
+ Button _button4;
+ Button _button5;
+ Button _button6;
+ Button _button7;
ASoundExt _aSound1;
SequenceManager _sequenceManager1;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index 59736989ee..e44c95449e 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -5,7 +5,7 @@
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU GenWeral Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
@@ -30,9 +30,453 @@ namespace TsAGE {
namespace Ringworld2 {
/*--------------------------------------------------------------------------
+ * Scene 1000 - Cutscene scene
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene1000::Scene1000(): SceneExt() {
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ R2_GLOBALS._uiElements._active = false;
+ _gameTextSpeaker._displayMode = 9;
+ _forceCheckAnimationFl = false;
+ _animCounter = 0;
+}
+
+void Scene1000::postInit(SceneObjectList *OwnerList) {
+ loadBlankScene();
+ SceneExt::postInit();
+
+ _stripManager.addSpeaker(&_gameTextSpeaker);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ switch (R2_GLOBALS._sceneManager._previousScene) {
+ case 300:
+ _sceneMode = R2_GLOBALS.getFlag(57) ? 40 : 0;
+ break;
+ case 1010:
+ _sceneMode = 30;
+ break;
+ case 1100:
+ _sceneMode = 10;
+ break;
+ case 1530:
+ _sceneMode = 20;
+ break;
+ case 2500:
+ _sceneMode = 100;
+ break;
+ case 2800:
+ _sceneMode = 2800;
+ break;
+ case 3100:
+ if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 1000)
+ _sceneMode = 90;
+ else
+ _sceneMode = 80;
+ break;
+ case 3500:
+ _sceneMode = 50;
+ break;
+ case 3700:
+ _sceneMode = 60;
+ break;
+ default:
+ _sceneMode = 999;
+ break;
+ }
+
+ R2_GLOBALS._uiElements._active = false;
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+}
+
+void Scene1000::remove() {
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 0xff, 0xff, 0xff);
+ SceneExt::remove();
+}
+
+void Scene1000::signal() {
+ ScenePalette scenePalette1, scenePalette2;
+ uint32 black = 0;
+
+ switch (_sceneMode++) {
+ case 0:
+ // TODO: Sort out values
+ R2_GLOBALS._gfxColors.foreground = 191;
+ R2_GLOBALS._gfxColors.background = 144;
+ R2_GLOBALS._fontColors.background = 224;
+ R2_GLOBALS._fontColors.foreground = 119;
+
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer.load(5, this);
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+
+ _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);
+
+ R2_GLOBALS._sound1.play(67);
+ break;
+
+ case 1:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+
+ // TODO: Sort out values
+ R2_GLOBALS._gfxColors.foreground = 191;
+ R2_GLOBALS._gfxColors.background = 144;
+ R2_GLOBALS._fontColors.background = 224;
+ R2_GLOBALS._fontColors.foreground = 119;
+
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ loadScene(9999);
+
+ R2_GLOBALS._player.setup(1140, 1, 1);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 100));
+ R2_GLOBALS._player.show();
+
+ _animCounter = 0;
+ _stripManager.start(29, this);
+ break;
+
+ case 2:
+ if (R2_GLOBALS._speechSubtitles & SPEECH_TEXT) {
+ setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
+ } else {
+ if (++_animCounter < 3)
+ _sceneMode = 2;
+
+ setAction(&_sequenceManager1, this, 2, &R2_GLOBALS._player, NULL);
+ }
+ break;
+
+ case 3:
+ // TODO: Sort out values
+ R2_GLOBALS._gfxColors.foreground = 191;
+ R2_GLOBALS._gfxColors.background = 144;
+ R2_GLOBALS._fontColors.background = 224;
+ R2_GLOBALS._fontColors.foreground = 119;
+
+ for (int percent = 100; percent >= 0; percent -= 5)
+ R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(7, this);
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound2.play(81);
+ R2_GLOBALS._sound1.play(80);
+ break;
+
+ case 4:
+ // TODO: Sort out values
+ R2_GLOBALS._gfxColors.foreground = 191;
+ R2_GLOBALS._gfxColors.background = 144;
+ R2_GLOBALS._fontColors.background = 224;
+ R2_GLOBALS._fontColors.foreground = 119;
+
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1100);
+ break;
+
+ case 10:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(6, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound1.play(55);
+ break;
+
+ case 11:
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+
+ case 20:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(8, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 21:
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(1530);
+ break;
+
+ case 30:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(17, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound2.play(91);
+ break;
+
+ case 31:
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS.setFlag(51);
+ R2_GLOBALS._sceneManager.changeScene(300);
+ break;
+
+ case 40:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(18, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound2.play(90);
+ break;
+
+ case 41:
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(1010);
+ break;
+
+ case 50:
+ R2_GLOBALS._sound2.play(306);
+ for (int percent = 100; percent >= 0; percent -= 5)
+ R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(13, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 51:
+ R2_GLOBALS._sound2.stop();
+ R2_GLOBALS._sound2.play(307);
+ R2_GLOBALS._sound1.play(308);
+
+ for (int percent = 100; percent >= 0; percent -= 5)
+ R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(14, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 52:
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(3350);
+ break;
+
+ case 60:
+ R2_GLOBALS._sound1.play(333);
+
+ for (int percent = 100; percent >= 0; percent -= 5)
+ R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(12, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 61:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(160);
+ break;
+
+ case 70:
+ R2_GLOBALS._sound2.play(113);
+ for (int percent = 100; percent >= 0; percent -= 5)
+ R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(9, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 71:
+ case 81:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(3100);
+ break;
+
+ case 80:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(10, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound1.play(242);
+ R2_GLOBALS._sound2.play(286);
+ break;
+
+ case 90:
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(11, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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);
+
+ R2_GLOBALS._sound1.play(277);
+ break;
+
+ case 91:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._player._characterIndex = R2_SEEKER;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 3100;
+ R2_GLOBALS._sceneManager.changeScene(2500);
+ break;
+
+ case 100:
+ R2_GLOBALS._sound1.play(304);
+ R2_GLOBALS._sound2.play(82);
+
+ _animationPlayer._paletteMode = ANIMPALMODE_NONE;
+ _animationPlayer._objectMode = ANIMOBJMODE_2;
+ _animationPlayer.load(19, this);
+
+ R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256);
+ R2_GLOBALS._sceneManager._hasPalette = false;
+ _animationPlayer.dispatch();
+
+ _forceCheckAnimationFl = true;
+ 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;
+
+ case 101:
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._sceneManager.changeScene(3500);
+ break;
+ }
+}
+
+void Scene1000::dispatch() {
+ if (_forceCheckAnimationFl) {
+ if (_animationPlayer.isCompleted()) {
+ _forceCheckAnimationFl = false;
+ _animationPlayer.close();
+ _animationPlayer.remove();
+
+ if (_sceneMode == 52)
+ _endHandler = this;
+ } else {
+ _animationPlayer.dispatch();
+ }
+ }
+
+ Scene::dispatch();
+}
+
+
+/*--------------------------------------------------------------------------
* Scene 1010 - Cutscene: A pixel lost in space!
*
*--------------------------------------------------------------------------*/
+
void Scene1010::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(1010);
@@ -218,18 +662,18 @@ void Scene1020::dispatch() {
*
*--------------------------------------------------------------------------*/
Scene1100::Scene1100() {
- _field412 = 0;
- _field414 = 0;
+ _nextStripNum = 0;
+ _paletteRefreshStatus = 0;
}
void Scene1100::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_nextStripNum);
+ s.syncAsSint16LE(_paletteRefreshStatus);
}
-bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
+bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_TALK)
@@ -237,24 +681,24 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
if (R2_GLOBALS.getFlag(52)) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
- scene->_field412 = 327;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ scene->_nextStripNum = 327;
else
- scene->_field412 = 328;
+ scene->_nextStripNum = 328;
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 55;
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ 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._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(304, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(308, scene, R2_GLOBALS._stripManager_lookupList);
@@ -263,7 +707,7 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
+bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -271,7 +715,7 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1114;
- scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -282,21 +726,21 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
case R2_PHOTON_STUNNER:
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_sceneMode = 1112;
- scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
scene->_sceneMode = 1115;
- scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else if (_strip == 2) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1113;
- if (R2_GLOBALS._player._characterIndex == 1) {
- scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else {
@@ -309,11 +753,11 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
}
}
-bool Scene1100::Actor18::startAction(CursorType action, Event &event) {
+bool Scene1100::Chief::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
- scene->_field412 = 0;
+ scene->_nextStripNum = 0;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
@@ -371,7 +815,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.stop();
if (R2_GLOBALS._sceneManager._previousScene == 300) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player._characterScene[1] = 1100;
R2_GLOBALS._player._characterScene[2] = 1100;
@@ -381,28 +825,28 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor16.postInit();
- _actor16.hide();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _seeker.postInit();
+ _seeker.hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor17.postInit();
- _actor17.setup(1105, 3, 1);
- _actor17.setPosition(Common::Point(312, 165));
- _actor17._numFrames = 5;
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.postInit();
+ _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);
@@ -416,7 +860,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS._sceneManager._previousScene == 1000) {
_actor2.setPosition(Common::Point(50, 30));
- _field414 = 0;
+ _paletteRefreshStatus = 0;
_palette1.loadPalette(1101);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
@@ -429,25 +873,25 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveRate = 30;
R2_GLOBALS._player._moveDiff = Common::Point(16, 2);
- _object1.setup2(1104, 2, 1, 175, 125, 102, 1);
+ _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, 1);
_object2.setup2(1102, 5, 1, 216, 167, 1, 0);
- _actor12.postInit();
- _actor12.setup(1113, 2, 1);
- _actor12.setPosition(Common::Point(67, 151));
- _actor12.fixPriority(255);
+ _leftImpacts.postInit();
+ _leftImpacts.setup(1113, 2, 1);
+ _leftImpacts.setPosition(Common::Point(67, 151));
+ _leftImpacts.fixPriority(255);
- _actor3.postInit();
- _actor3.setup(1102, 6, 1);
- _actor3._moveRate = 30;
- _actor3._moveDiff.x = 2;
+ _shipFormation.postInit();
+ _shipFormation.setup(1102, 6, 1);
+ _shipFormation._moveRate = 30;
+ _shipFormation._moveDiff.x = 2;
- _actor4.postInit();
- _actor4.setup(1102, 6, 2);
- _actor4._moveRate = 30;
- _actor4._moveDiff.x = 2;
- _actor4._effect = 5;
- _actor4._field9C = _field312;
+ _shipFormationShadow.postInit();
+ _shipFormationShadow.setup(1102, 6, 2);
+ _shipFormationShadow._moveRate = 30;
+ _shipFormationShadow._moveDiff.x = 2;
+ _shipFormationShadow._effect = 5;
+ _shipFormationShadow._field9C = _field312;
R2_GLOBALS._sound1.play(86);
@@ -464,66 +908,66 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- _actor16.postInit();
+ _seeker.postInit();
if (R2_GLOBALS.getFlag(52)) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(19, 7, 1);
- _actor16.setup(29, 6, 1);
+ _seeker.setup(29, 6, 1);
} else {
R2_GLOBALS._player.setup(29, 7, 1);
- _actor16.setup(19, 6, 1);
+ _seeker.setup(19, 6, 1);
}
R2_GLOBALS._player.setPosition(Common::Point(140, 124));
- _actor16.setPosition(Common::Point(237, 134));
+ _seeker.setPosition(Common::Point(237, 134));
R2_GLOBALS._player.enableControl();
} else {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1107, 2, 1);
- _actor16.setup(1107, 4, 1);
+ _seeker.setup(1107, 4, 1);
R2_GLOBALS._player.setPosition(Common::Point(247, 169));
- _actor16.setPosition(Common::Point(213, 169));
+ _seeker.setPosition(Common::Point(213, 169));
} else {
R2_GLOBALS._player.setup(1107, 4, 1);
- _actor16.setup(1107, 2, 1);
+ _seeker.setup(1107, 2, 1);
R2_GLOBALS._player.setPosition(Common::Point(213, 169));
- _actor16.setPosition(Common::Point(247, 169));
+ _seeker.setPosition(Common::Point(247, 169));
}
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
if (!R2_GLOBALS.getFlag(52)) {
- _actor17.postInit();
+ _trooper.postInit();
if (R2_GLOBALS.getFlag(53))
- _actor17.setup(1106, 2, 4);
+ _trooper.setup(1106, 2, 4);
else
- _actor17.setup(1105, 4, 4);
+ _trooper.setup(1105, 4, 4);
- _actor17.setPosition(Common::Point(17, 54));
- _actor17._numFrames = 5;
+ _trooper.setPosition(Common::Point(17, 54));
+ _trooper._numFrames = 5;
if (R2_GLOBALS.getFlag(53))
- _actor17.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
else
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
- _actor17.fixPriority(200);
+ _trooper.fixPriority(200);
}
_actor1.postInit();
_actor1.setup(1512, 1, 1);
@@ -549,30 +993,30 @@ void Scene1100::remove() {
void Scene1100::signal() {
switch (_sceneMode++) {
case 0:
- _actor3.setPosition(Common::Point(350, 20));
+ _shipFormation.setPosition(Common::Point(350, 20));
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
break;
case 1:{
Common::Point pt(-150, 20);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, this);
- _actor4.setPosition(Common::Point(350, 55));
+ _shipFormation.addMover(mover, &pt, this);
+ _shipFormationShadow.setPosition(Common::Point(350, 55));
Common::Point pt2(-150, 55);
NpcMover *mover2 = new NpcMover();
- _actor4.addMover(mover2, &pt2, NULL);
+ _shipFormationShadow.addMover(mover2, &pt2, NULL);
}
break;
case 2:
- _actor3.remove();
- _actor4.remove();
- _actor5.postInit();
- _actor6.postInit();
- _actor7.postInit();
- _actor8.postInit();
- _actor9.postInit();
- _actor10.postInit();
- setAction(&_sequenceManager1, this, 1102, &_actor5, &_actor6, &_actor7, &_actor8, &_actor9, &_actor10, NULL);
+ _shipFormation.remove();
+ _shipFormationShadow.remove();
+ _shotImpact1.postInit();
+ _shotImpact2.postInit();
+ _shotImpact3.postInit();
+ _shotImpact4.postInit();
+ _shotImpact5.postInit();
+ _laserShot.postInit();
+ setAction(&_sequenceManager1, this, 1102, &_shotImpact1, &_shotImpact2, &_shotImpact3, &_shotImpact4, &_shotImpact5, &_laserShot, NULL);
break;
case 3: {
R2_GLOBALS._sound2.play(84);
@@ -583,26 +1027,26 @@ void Scene1100::signal() {
}
break;
case 4:
- _actor18.postInit();
- _actor18.show();
- setAction(&_sequenceManager1, this, 1101, &_actor18, &_actor10, NULL);
+ _chief.postInit();
+ _chief.show();
+ setAction(&_sequenceManager1, this, 1101, &_chief, &_laserShot, NULL);
break;
case 5:
- _actor13.postInit();
- _actor13._effect = 6;
- _actor13.setup(1103, 3, 1);
- _actor13._moveRate = 30;
+ _runningGuy1.postInit();
+ _runningGuy1._effect = 6;
+ _runningGuy1.setup(1103, 3, 1);
+ _runningGuy1._moveRate = 30;
- _actor14.postInit();
- _actor14._effect = 6;
- _actor14.setup(1103, 4, 1);
- _actor4._moveRate = 25;
+ _runningGuy2.postInit();
+ _runningGuy2._effect = 6;
+ _runningGuy2.setup(1103, 4, 1);
+ _runningGuy2._moveRate = 25;
- _actor13.setAction(&_sequenceManager2, this, 1109, &_actor13, &_actor14, NULL);
+ _runningGuy1.setAction(&_sequenceManager2, this, 1109, &_runningGuy1, &_runningGuy2, NULL);
break;
case 6: {
- _actor13.remove();
- _actor14.remove();
+ _runningGuy1.remove();
+ _runningGuy2.remove();
R2_GLOBALS._player.setPosition(Common::Point(-50, 136));
R2_GLOBALS._sound2.play(84);
Common::Point pt(350, 236);
@@ -611,29 +1055,30 @@ void Scene1100::signal() {
}
break;
case 7:
- setAction(&_sequenceManager1, this, 1103, &_actor18, &_actor10);
+ setAction(&_sequenceManager1, this, 1103, &_chief, &_laserShot, NULL);
break;
case 8:
R2_GLOBALS._player._effect = 0;
- _actor11.postInit();
- setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_actor10, &_actor11, &_actor18, NULL);
+ _animation.postInit();
+ setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_laserShot, &_animation, &_chief, NULL);
break;
case 9:
- _object1.proc27();
+ _rightLandslide.copySceneToBackground();
- _actor15.postInit();
- _actor15.setup(1103, 2, 1);
- _actor15._moveRate = 30;
- _actor15.setAction(&_sequenceManager3, this, 1107, &_actor15, NULL);
+ _runningGuy3.postInit();
+ _runningGuy3.setup(1103, 2, 1);
+ _runningGuy3._moveRate = 30;
+ _runningGuy3.setAction(&_sequenceManager3, this, 1107, &_runningGuy3, NULL);
break;
case 10:
- _actor13.postInit();
- _actor13.setup(1103, 1, 1);
- _actor13._moveRate = 15;
- _actor13.setAction(&_sequenceManager2, this, 1108, &_actor13, NULL);
+ _runningGuy1.postInit();
+ _runningGuy1.setup(1103, 1, 1);
+ _runningGuy1._moveRate = 15;
+ _runningGuy1.setAction(&_sequenceManager2, this, 1108, &_runningGuy1, NULL);
break;
case 11: {
- setAction(&_sequenceManager1, this, 1116, &_actor11, &_actor10, &_actor12, NULL);
+ setAction(&_sequenceManager1, this, 1106, &_animation, &_laserShot, &_leftImpacts, NULL);
+
R2_GLOBALS._player._effect = 5;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setPosition(Common::Point(-50, 131));
@@ -647,19 +1092,19 @@ void Scene1100::signal() {
// Really nothing
break;
case 13:
- _actor17.postInit();
- R2_GLOBALS._scrollFollower = &_actor17;
+ _trooper.postInit();
+ R2_GLOBALS._scrollFollower = &_trooper;
- _actor11.setup(1100, 2, 1);
- _actor11.setPosition(Common::Point(408, 121));
+ _animation.setup(1100, 2, 1);
+ _animation.setPosition(Common::Point(408, 121));
- _actor10.setup(1100, 3, 5);
- _actor10.setPosition(Common::Point(409, 121));
+ _laserShot.setup(1100, 3, 5);
+ _laserShot.setPosition(Common::Point(409, 121));
- setAction(&_sequenceManager1, this, 1104, &_actor17, NULL);
+ setAction(&_sequenceManager1, this, 1104, &_trooper, NULL);
break;
case 14:
- setAction(&_sequenceManager1, this, 1100, &_actor11, &_actor10, NULL);
+ setAction(&_sequenceManager1, this, 1100, &_animation, &_laserShot, NULL);
break;
case 15:
R2_GLOBALS._sceneManager.changeScene(1000);
@@ -672,14 +1117,14 @@ void Scene1100::signal() {
break;
case 21: {
R2_GLOBALS._sound2.play(92);
- _actor17.animate(ANIM_MODE_5, NULL);
+ _trooper.animate(ANIM_MODE_5, NULL);
Common::Point pt(187, 45);
NpcMover *mover = new NpcMover();
_actor1.addMover(mover, &pt, this);
}
break;
case 22:
- setAction(&_sequenceManager1, this, 1110, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1110, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 23:
R2_GLOBALS._player.disableControl();
@@ -693,74 +1138,77 @@ void Scene1100::signal() {
break;
case 25:
R2_GLOBALS._player.disableControl();
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
R2_GLOBALS._sound1.play(95);
- setAction(&_sequenceManager1, this, 1111, &_actor17, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1111, &_trooper, &R2_GLOBALS._player, &_seeker, NULL);
break;
case 26:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(302, this);
break;
case 27:
R2_GLOBALS._player.disableControl();
- setAction(&_sequenceManager1, this, 1120, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1120, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 28:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(303, this);
break;
+ case 29:
+ case 50:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
case 51:
R2_GLOBALS.setFlag(53);
- _actor17.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
- // No break on purpose
- case 50:
- // No break on purpose
- case 29:
+ _trooper.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
+
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
case 52:
R2_GLOBALS._sound1.play(98);
R2_GLOBALS.setFlag(52);
R2_GLOBALS._player.disableControl();
_sceneMode = 1116;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
setAction(&_sequenceManager1, this, 1116, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1123, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1123, &_seeker, NULL);
} else {
setAction(&_sequenceManager1, this, 1124, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1117, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1117, &_seeker, NULL);
}
break;
case 53:
_sceneMode = 54;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (_field412 == 0) {
+ if (_nextStripNum == 0) {
R2_GLOBALS.setFlag(55);
if (R2_GLOBALS.getFlag(55)) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ 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 == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(317, this);
else
_stripManager.start(322, this);
}
} else {
- _stripManager.start3(_field412, this, _stripManager._lookupList);
+ _stripManager.start3(_nextStripNum, this, _stripManager._lookupList);
}
break;
case 54:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.disableControl();
_sceneMode = 1125;
- setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_seeker, NULL);
} else
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
@@ -801,9 +1249,9 @@ void Scene1100::signal() {
break;
case 1116:
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
break;
case 1125: {
_sceneMode = 99;
@@ -822,37 +1270,37 @@ void Scene1100::signal() {
}
void Scene1100::dispatch() {
- if ((g_globals->_sceneObjects->contains(&_actor10)) && (_actor10._visage == 1102) && (_actor10._strip == 4) && (_actor10._frame == 1) && (_actor10._flags & OBJFLAG_HIDING)) {
- if (_field414 == 1) {
- _field414 = 2;
+ if ((g_globals->_sceneObjects->contains(&_laserShot)) && (_laserShot._visage == 1102) && (_laserShot._strip == 4) && (_laserShot._frame == 1) && (_laserShot._flags & OBJFLAG_HIDING)) {
+ if (_paletteRefreshStatus == 1) {
+ _paletteRefreshStatus = 2;
R2_GLOBALS._scenePalette.refresh();
}
} else {
- if (_field414 == 2)
+ if (_paletteRefreshStatus == 2)
R2_GLOBALS._scenePalette.refresh();
- _field414 = 1;
+ _paletteRefreshStatus = 1;
}
Scene::dispatch();
- if (R2_GLOBALS._player._bounds.contains(_actor13._position))
- _actor13._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy1._position))
+ _runningGuy1._shade = 3;
else
- _actor13._shade = 0;
+ _runningGuy1._shade = 0;
- if (R2_GLOBALS._player._bounds.contains(_actor14._position))
- _actor14._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy2._position))
+ _runningGuy2._shade = 3;
else
- _actor14._shade = 0;
+ _runningGuy2._shade = 0;
- if (R2_GLOBALS._player._bounds.contains(_actor15._position))
- _actor15._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy3._position))
+ _runningGuy3._shade = 3;
else
- _actor15._shade = 0;
+ _runningGuy3._shade = 0;
}
void Scene1100::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
}
@@ -883,13 +1331,6 @@ void Scene1200::synchronize(Serializer &s) {
}
Scene1200::LaserPanel::LaserPanel() {
- _field20 = 0;
-}
-
-void Scene1200::LaserPanel::synchronize(Serializer &s) {
- SceneArea::synchronize(s);
-
- s.syncAsByte(_field20);
}
void Scene1200::LaserPanel::Jumper::init(int state) {
@@ -1051,53 +1492,13 @@ void Scene1200::LaserPanel::remove() {
// sub201EA
R2_GLOBALS._sceneItems.remove((SceneItem *)this);
- _actor2.remove();
+ _object1.remove();
SceneArea::remove();
R2_GLOBALS._insetUp--;
R2_GLOBALS._player._canWalk = true;
}
-void Scene1200::LaserPanel::process(Event &event) {
- if (_field20 != R2_GLOBALS._insetUp)
- return;
-
- CursorType cursor = R2_GLOBALS._events.getCursor();
-
- if (_actor2._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 Scene1200::LaserPanel::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
- Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
-
- _actor2.postInit();
- _actor2.setup(visage, stripFrameNum, frameNum);
- _actor2.setPosition(Common::Point(posX, posY));
- _actor2.fixPriority(250);
- _cursorNum = CURSOR_INVALID;
- scene->_sceneAreas.push_front(this);
- ++R2_GLOBALS._insetUp;
- _field20 = R2_GLOBALS._insetUp;
-}
-
-void Scene1200::LaserPanel::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- _actor2.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
-}
-
void Scene1200::postInit(SceneObjectList *OwnerList) {
loadScene(1200);
SceneExt::postInit();
@@ -1571,10 +1972,9 @@ void Scene1200::dispatch() {
break;
}
_mazeUI.setMazePosition(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
- warning("int unk = set_pane_p(_paneNumber);");
- _mazeUI.draw();
- warning("_gfxManager.sub294AC(unk);");
- warning("tmpRect.sub14DF3();");
+
+ debug("_gfxManager.sub294AC(unk);");
+ debug("tmpRect.sub14DF3();");
if (_field416 != 0) {
switch(_field412 - 1) {
@@ -5578,7 +5978,8 @@ void Scene1337::subCF31D() {
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;
+ }
}
}
@@ -5588,8 +5989,10 @@ void Scene1337::subCF31D() {
tmpVal = subC274D(1);
int tmpVal2 = subC331B(1);
- if ((tmpVal != -1) && ( tmpVal2 != -1))
+ if ((tmpVal != -1) && ( tmpVal2 != -1)) {
subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
+ found = true;
+ }
if (found)
return;
@@ -6613,7 +7016,7 @@ void Scene1500::signal() {
}
break;
case 24:
- R2_GLOBALS._sceneManager.changeScene(300);
+ R2_GLOBALS._sceneManager.changeScene(1550);
break;
default:
break;
@@ -6774,21 +7177,22 @@ void Scene1530::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 1550 -
+ * Scene 1550 - Spaceport
*
*--------------------------------------------------------------------------*/
-Scene1550::UnkObj15501::UnkObj15501() {
- _fieldA4 = _fieldA6 = 0;
+
+Scene1550::Junk::Junk() {
+ _fieldA4 = _junkNumber = 0;
}
-void Scene1550::UnkObj15501::synchronize(Serializer &s) {
+void Scene1550::Junk::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_junkNumber);
}
-bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
+bool Scene1550::Junk::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -6841,36 +7245,36 @@ bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
}
}
-Scene1550::UnkObj15502::UnkObj15502() {
- _fieldA4 = 0;
+Scene1550::ShipComponent::ShipComponent() {
+ _componentId = 0;
}
-void Scene1550::UnkObj15502::synchronize(Serializer &s) {
+void Scene1550::ShipComponent::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_componentId);
}
-bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
+bool Scene1550::ShipComponent::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (_fieldA4 == 8) {
+ if (_componentId == 8) {
scene->_field412 = 1;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1576;
else
scene->_sceneMode = 1584;
- // strcpy(scene->_arrUnkObj15502[7]._actorName, 'hatch');
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[7], NULL);
+ // strcpy(scene->_shipComponents[7]._actorName, 'hatch');
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[7], NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case CURSOR_LOOK:
- if (_fieldA4 == 8)
+ if (_componentId == 8)
SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
else if (_frame == 1)
SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
@@ -6880,92 +7284,92 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
break;
case R2_FUEL_CELL:
scene->_field412 = 1;
- if (_fieldA4 == 6) {
+ if (_componentId == 6) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.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->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GYROSCOPE:
scene->_field412 = 1;
- if (_fieldA4 == 3) {
+ if (_componentId == 3) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.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->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GUIDANCE_MODULE:
scene->_field412 = 1;
- if (_fieldA4 == 1) {
+ if (_componentId == 1) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.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->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_THRUSTER_VALVE:
scene->_field412 = 1;
- if (_fieldA4 == 4) {
+ if (_componentId == 4) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1572;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[3], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_RADAR_MECHANISM:
scene->_field412 = 1;
- if (_fieldA4 == 2) {
+ if (_componentId == 2) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.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->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_IGNITOR:
scene->_field412 = 1;
- if (_fieldA4 == 5) {
+ if (_componentId == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1573;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[4], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_BATTERY:
scene->_field412 = 1;
- if (_fieldA4 == 7) {
+ if (_componentId == 7) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.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->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
@@ -6976,47 +7380,48 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
}
}
-void Scene1550::UnkObj15502::subA5CDF(int strip) {
- _fieldA4 = strip;
+void Scene1550::ShipComponent::setupShipComponent(int componentId) {
+ _componentId = componentId;
postInit();
- setup(1517, _fieldA4, 1);
- switch (_fieldA4 - 1) {
- case 0:
+ setup(1517, _componentId, 1);
+
+ switch (_componentId) {
+ case 1:
if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
setFrame(5);
setPosition(Common::Point(287, 85));
break;
- case 1:
+ case 2:
if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0)
setFrame(5);
setPosition(Common::Point(248, 100));
break;
- case 2:
- if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 0)
+ case 3:
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
setFrame(5);
setPosition(Common::Point(217, 85));
break;
- case 3:
- if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE))
+ case 4:
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 0)
setFrame(5);
setPosition(Common::Point(161, 121));
break;
- case 4:
- if (R2_INVENTORY.getObjectScene(R2_IGNITOR))
+ case 5:
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 0)
setFrame(5);
setPosition(Common::Point(117, 121));
break;
- case 5:
- if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL))
+ case 6:
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0)
setFrame(5);
setPosition(Common::Point(111, 85));
break;
- case 6:
- if (R2_INVENTORY.getObjectScene(R2_BATTERY))
+ case 7:
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 0)
setFrame(5);
setPosition(Common::Point(95, 84));
break;
- case 7: {
+ case 8: {
setup(1516, 1, 1);
setPosition(Common::Point(201, 45));
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
@@ -7029,6 +7434,9 @@ void Scene1550::UnkObj15502::subA5CDF(int strip) {
default:
break;
}
+
+ fixPriority(92);
+ setDetails(1550, 70, -1, -1, 2, (SceneItem *)NULL);
}
Scene1550::UnkObj15503::UnkObj15503() {
@@ -7115,19 +7523,16 @@ void Scene1550::UnkArea1550::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -7175,26 +7580,30 @@ void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum
_areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
}
-bool Scene1550::Hotspot1::startAction(CursorType action, Event &event) {
+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 == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ 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._v565EC[R2_GLOBALS._player._characterIndex], R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2], k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]);
+ 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::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1550::Wreckage::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1550::Companion::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
@@ -7212,7 +7621,7 @@ bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1552;
else
scene->_sceneMode = 1588;
@@ -7229,7 +7638,7 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
scene->_sceneMode = 50;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(518, scene);
else
scene->_stripManager.start(520, scene);
@@ -7250,7 +7659,7 @@ bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1555;
else
scene->_sceneMode = 1589;
@@ -7266,7 +7675,7 @@ bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1586;
else
scene->_sceneMode = 1587;
@@ -7281,7 +7690,7 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1585;
scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
@@ -7361,19 +7770,22 @@ void Scene1550::synchronize(Serializer &s) {
}
void Scene1550::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ 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);
else
+ // Normal scene entry
loadScene(1550);
+ SceneExt::postInit();
scalePalette(65, 65, 65);
setZoomPercents(30, 75, 170, 100);
_field417 = 1550;
_field419 = 0;
- SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS.setFlag(R2_ATTRACTOR_CABLE_HARNESS);
+ R2_GLOBALS.setFlag(16);
if ((R2_GLOBALS._player._characterScene[1] != 1550) && (R2_GLOBALS._player._characterScene[1] != 1580)) {
R2_GLOBALS._player._characterScene[1] = 1550;
@@ -7388,14 +7800,15 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player._effect = 6;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setup(1500, 3, 1);
else
R2_GLOBALS._player.setup(1505, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ 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
R2_GLOBALS._player.setPosition(Common::Point(160, 100));
@@ -7404,7 +7817,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
_field414 = 0;
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._sceneManager._previousScene) {
@@ -7419,21 +7832,22 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(105);
break;
case 1580:
+ // Leaving intact ship
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1580) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
_field412 = 1;
- _actor1.postInit();
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[7].hide();
- if (R2_GLOBALS._player._characterIndex == 1)
+ _landingStrut.postInit();
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[7].hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 1577;
else
_sceneMode = 1578;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_arrUnkObj15502[7], NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_landingStrut, &_shipComponents[7], NULL);
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
} else {
R2_GLOBALS._player.enableControl();
@@ -7443,29 +7857,29 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
break;
}
- subA2B2F();
+ enterArea();
- _item1.setDetails(16, 1550, 10, -1, -1);
+ _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);
if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
_sceneMode = 70;
- if (!R2_GLOBALS._sceneObjects->contains(&_actor7))
- _actor7.postInit();
+ if (!R2_GLOBALS._sceneObjects->contains(&_companion))
+ _companion.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
+ _companion.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.changeZoom(77);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
assert(_field419 >= 1550);
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1590, &_companion, NULL);
} else if ((_sceneMode != 1577) && (_sceneMode != 1578))
R2_GLOBALS._player.enableControl();
}
@@ -7481,7 +7895,7 @@ void Scene1550::signal() {
case 7:
_field412 = 0;
R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 20:
// No break on purpose
@@ -7522,14 +7936,14 @@ void Scene1550::signal() {
break;
case 40: {
_sceneMode = 41;
- Common::Point pt(_arrUnkObj15501[0]._position.x, _arrUnkObj15501[0]._position.y + 20);
+ Common::Point pt(_junk[0]._position.x, _junk[0]._position.y + 20);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 41:
_sceneMode = 42;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1502, 8, 1);
} else {
R2_GLOBALS._player.changeZoom(R2_GLOBALS._player._percent + 14);
@@ -7537,37 +7951,42 @@ void Scene1550::signal() {
}
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
- case 42:
+
+ case 42: {
_sceneMode = 43;
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- switch (_arrUnkObj15501[0]._frame - 1) {
- case 0:
- R2_INVENTORY.setObjectScene(26, R2_GLOBALS._player._characterIndex);
- break;
+ int junkRegionIndex = R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 3];
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[junkRegionIndex]);
+
+ switch (_junk[0]._frame) {
case 1:
- R2_INVENTORY.setObjectScene(17, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, R2_GLOBALS._player._characterIndex);
break;
case 2:
- R2_INVENTORY.setObjectScene(22, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_FUEL_CELL, R2_GLOBALS._player._characterIndex);
break;
case 3:
- R2_INVENTORY.setObjectScene(25, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, R2_GLOBALS._player._characterIndex);
break;
case 4:
- R2_INVENTORY.setObjectScene(45, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, R2_GLOBALS._player._characterIndex);
break;
case 5:
- R2_INVENTORY.setObjectScene(28, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_BATTERY, R2_GLOBALS._player._characterIndex);
+ break;
+ case 6:
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
break;
default:
break;
}
- _arrUnkObj15501[0].remove();
+
+ _junk[0].remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
+ }
case 43:
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 2] = 0;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setVisage(1500);
else {
R2_GLOBALS._player.changeZoom(-1);
@@ -7581,29 +8000,29 @@ void Scene1550::signal() {
warning("STUB: sub_1D227()");
++_sceneMode;
setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
- if (g_globals->_sceneObjects->contains(&_actor7))
+ if (g_globals->_sceneObjects->contains(&_companion))
signal();
else {
- _actor7.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setAction(&_sequenceManager2, this, 1590, &_actor7, NULL);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setVisage(1500);
+ _companion.changeZoom(77);
+ _companion.setAction(&_sequenceManager2, this, 1590, &_companion, NULL);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 51:
++_sceneMode;
break;
case 52:
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
_sceneMode = 1592;
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
else
- setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
break;
case 61:
R2_GLOBALS._player.enableControl(CURSOR_USE);
@@ -7618,9 +8037,8 @@ void Scene1550::signal() {
}
break;
case 70:
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
- R2_GLOBALS._v565EC[0] = 1;
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
+ //R2_GLOBALS._s1550PlayerAreas[0] = 1;
_sceneMode = 60;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(500, this);
@@ -7631,13 +8049,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(499 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(502 + R2_GLOBALS._v565AE, this);
@@ -7647,13 +8065,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 4) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(563 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(567 + R2_GLOBALS._v565AE, this);
@@ -7717,7 +8135,7 @@ void Scene1550::signal() {
// No break on purpose
case 1579:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7725,7 +8143,7 @@ void Scene1550::signal() {
// No break on purpose
case 1580:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7733,19 +8151,19 @@ void Scene1550::signal() {
// No break on purpose
case 1581:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1572:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1573:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7753,7 +8171,7 @@ void Scene1550::signal() {
// No break on purpose
case 1582:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7761,7 +8179,7 @@ void Scene1550::signal() {
// No break on purpose
case 1583:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7775,7 +8193,7 @@ void Scene1550::signal() {
// No break on purpose
case 1578:
_sceneMode = 0;
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.enableControl();
@@ -7788,19 +8206,17 @@ void Scene1550::signal() {
// No break on purpose
case 1587:
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.enableControl();
break;
case 1592:
_actor9.remove();
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
} else {
- R2_GLOBALS._v565EC[1] = R2_GLOBALS._v565EC[2];
- R2_GLOBALS._v565EC[3] = R2_GLOBALS._v565EC[4];
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN] = R2_GLOBALS._s1550PlayerArea[R2_SEEKER];
}
R2_GLOBALS._player.enableControl();
break;
@@ -7832,11 +8248,11 @@ void Scene1550::dispatch() {
Scene::dispatch();
// 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 == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 15) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 16)) {
+ 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 uninitialised variable.
+ // Original game contains a switch based on an uninitialized variable.
// Until we understand what should really happen there, this code is unused on purpose
int missingVariable = 0;
switch (missingVariable) {
@@ -7868,12 +8284,13 @@ void Scene1550::dispatch() {
case 0:
// No break on purpose
case 5:
+ // Exiting the top of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 1;
_field412 = 1;
- --R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 108) * 172) / 100), 145));
if (R2_GLOBALS._player._position.x < 160) {
@@ -7891,12 +8308,13 @@ void Scene1550::dispatch() {
}
break;
case 1:
+ // Exiting the bottom of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 3;
_field412 = 1;
- ++R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 172) * 108) / 100), 19));
if (R2_GLOBALS._player._position.x < 160) {
@@ -7914,14 +8332,15 @@ void Scene1550::dispatch() {
}
break;
case 2:
+ // Exiting the right of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 5;
_field412 = 1;
- ++R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
- subA2B2F();
+ enterArea();
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y + 20);
@@ -7941,16 +8360,20 @@ void Scene1550::dispatch() {
}
break;
case 3:
+ // Exiting to the left of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 7;
_field412 = 1;
- --R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 24) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
+
+ enterArea();
+
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 24) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y / 2));
Common::Point pt(265, 29);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ } else if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y + 20);
@@ -7975,7 +8398,7 @@ void Scene1550::dispatch() {
}
void Scene1550::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
@@ -8165,7 +8588,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
}
-void Scene1550::subA2B2F() {
+void Scene1550::enterArea() {
Rect tmpRect;
_field419 = 0;
_field415 = 0;
@@ -8173,19 +8596,19 @@ void Scene1550::subA2B2F() {
tmpRect = R2_GLOBALS._v5589E;
_actor14.remove();
- _actor17.remove();
- _actor15.remove();
- _actor19.remove();
+ _westWall.remove();
+ _northWall.remove();
+ _southWall.remove();
_actor16.remove();
- _actor18.remove();
+ _eastWall.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15501[i].remove();
+ _junk[i].remove();
- _actor6.remove();
+ _wreckage.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15502[i].remove();
+ _shipComponents[i].remove();
_actor8.remove();
_actor9.remove();
@@ -8194,18 +8617,19 @@ void Scene1550::subA2B2F() {
_actor11.remove();
if ((_sceneMode != 1577) && (_sceneMode != 1578))
- _actor1.remove();
+ _landingStrut.remove();
_actor2.remove();
- _actor7.remove();
+ _companion.remove();
_actor13.remove();
_actor5.remove();
_actor12.remove();
_actor4.remove();
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2]) {
+ // Set up of special walk regions for certain areas
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 3:
R2_GLOBALS._walkRegions.load(1554);
_field419 = 1554;
@@ -8221,7 +8645,7 @@ void Scene1550::subA2B2F() {
case 3:
// No break on purpose
case 4:
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 23) || (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex])) {
+ 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;
@@ -8229,7 +8653,7 @@ void Scene1550::subA2B2F() {
}
break;
case 7:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 10:
R2_GLOBALS._walkRegions.load(1555);
_field419 = 1555;
@@ -8243,7 +8667,7 @@ void Scene1550::subA2B2F() {
}
break;
case 11:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 24:
R2_GLOBALS._walkRegions.load(1558);
_field419 = 1558;
@@ -8257,7 +8681,7 @@ void Scene1550::subA2B2F() {
}
break;
case 16:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 2:
R2_GLOBALS._walkRegions.load(1552);
_field419 = 1552;
@@ -8280,12 +8704,12 @@ void Scene1550::subA2B2F() {
int varA = 0;
if (!R2_GLOBALS.getFlag(16)) {
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] - 2) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y - 2) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 22) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 22) {
case 0:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
case 1:
// No break on purpose
@@ -8298,7 +8722,7 @@ void Scene1550::subA2B2F() {
break;
case 5:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
default:
break;
@@ -8307,14 +8731,14 @@ void Scene1550::subA2B2F() {
case 1:
// No break on purpose
case 2:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(9, 0);
+ _northWall.subA4D14(9, 0);
break;
case 1:
varA = 1552;
- _actor15.subA4D14(10, 0);
+ _northWall.subA4D14(10, 0);
break;
case 2:
// No break on purpose
@@ -8327,25 +8751,25 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1552;
- _actor15.subA4D14(7, 0);
+ _northWall.subA4D14(7, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(8, 0);
+ _northWall.subA4D14(8, 0);
break;
default:
break;
}
break;
case 3:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(4, 0);
+ _northWall.subA4D14(4, 0);
break;
case 1:
varA = 1550;
- _actor15.subA4D14(3, 0);
+ _northWall.subA4D14(3, 0);
break;
case 2:
// No break on purpose
@@ -8358,11 +8782,11 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1550;
- _actor15.subA4D14(2, 0);
+ _northWall.subA4D14(2, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(1, 0);
+ _northWall.subA4D14(1, 0);
break;
default:
break;
@@ -8371,21 +8795,22 @@ void Scene1550::subA2B2F() {
default:
break;
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 0) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] <= 29) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] >= 20) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 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)) {
R2_GLOBALS.setFlag(16);
R2_GLOBALS._sceneManager.changeScene(1500);
}
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
- if (R2_GLOBALS._sceneManager._sceneNumber != 1234) {
+ 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 (R2_GLOBALS._sceneManager._sceneNumber == 1234) {
+ if (_screenNumber == 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1550);
R2_GLOBALS._sceneManager._hasPalette = false;
@@ -8433,71 +8858,75 @@ void Scene1550::subA2B2F() {
}
}
- switch (k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ // Scene setup dependent on the type of cell specified in the scene map
+ 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) {
R2_GLOBALS._walkRegions.load(1550);
_field419 = 1550;
}
break;
case 1:
+ // North end of the spaceport
if (_field419 == 0) {
R2_GLOBALS._walkRegions.load(1560);
_field419 = 1560;
}
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 2:
R2_GLOBALS._walkRegions.load(1561);
_field419 = 1561;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
- _actor15.subA4D14(1, 3);
+ _westWall.subA4D14(2, 2);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 3:
R2_GLOBALS._walkRegions.load(1562);
_field419 = 1562;
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 4:
R2_GLOBALS._walkRegions.load(1563);
_field419 = 1563;
- _actor15.subA4D14(2, 3);
+ _northWall.subA4D14(2, 3);
break;
case 5:
R2_GLOBALS._walkRegions.load(1564);
_field419 = 1564;
- _actor19.subA4D14(2, 4);
+ _southWall.subA4D14(2, 4);
break;
case 6:
R2_GLOBALS._walkRegions.load(1565);
_field419 = 1565;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(3, 3);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(3, 3);
break;
case 7:
R2_GLOBALS._walkRegions.load(1566);
_field419 = 1566;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(2, 4);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(2, 4);
break;
case 8:
R2_GLOBALS._walkRegions.load(1567);
_field419 = 1567;
- _actor17.subA4D14(5, 2);
+ _westWall.subA4D14(5, 2);
break;
case 9:
R2_GLOBALS._walkRegions.load(1568);
_field419 = 1568;
- _actor17.subA4D14(4, 2);
+ _westWall.subA4D14(4, 2);
break;
case 10:
R2_GLOBALS._walkRegions.load(1569);
@@ -8508,56 +8937,57 @@ void Scene1550::subA2B2F() {
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
+ _westWall.subA4D14(1, 2);
break;
case 12:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 13:
R2_GLOBALS._walkRegions.load(1572);
_field419 = 1572;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor19.subA4D14(1, 4);
+ _westWall.subA4D14(1, 2);
+ _southWall.subA4D14(1, 4);
break;
case 14:
R2_GLOBALS._walkRegions.load(1573);
_field419 = 1573;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 15:
+ // South wall
R2_GLOBALS._walkRegions.load(1574);
_field419 = 1574;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
break;
case 16:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
+ _westWall.subA4D14(2, 2);
break;
case 17:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(3, 2);
+ _westWall.subA4D14(3, 2);
break;
case 18:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 19:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(3, 6);
+ _eastWall.subA4D14(3, 6);
break;
default:
break;
@@ -8565,24 +8995,27 @@ void Scene1550::subA2B2F() {
int di = 0;
int tmpIdx = 0;
- // Original game was checking "i < 129" but it was clearly a bug as it's out of bounds
- for (int i = 0; i < 129 * 4; i += 4) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k562CC[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k562CC[i + 1]) && (k562CC[i + 2] != 0)) {
- tmpIdx = k562CC[i + 3];
- _arrUnkObj15501[di].postInit();
- _arrUnkObj15501[di]._effect = 6;
- _arrUnkObj15501[di]._shade = 0;
- _arrUnkObj15501[di]._fieldA4 = tmpIdx;
- _arrUnkObj15501[di]._fieldA6 = i;
- _arrUnkObj15501[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
- if (k562CC[i + 2] == 41) {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setPosition(Common::Point(150, 70));
- _arrUnkObj15501[di].setup(1562, 1, 1);
- R2_GLOBALS._walkRegions.enableRegion(k5A78C);
- R2_GLOBALS._walkRegions.enableRegion(k5A78D);
- R2_GLOBALS._walkRegions.enableRegion(k5A790);
- R2_GLOBALS._walkRegions.enableRegion(k5A791);
+ 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]) &&
+ (R2_GLOBALS._scene1550JunkLocations[i + 2] != 0)) {
+ tmpIdx = R2_GLOBALS._scene1550JunkLocations[i + 3];
+ _junk[di].postInit();
+ _junk[di]._effect = 6;
+ _junk[di]._shade = 0;
+ _junk[di]._fieldA4 = tmpIdx;
+ _junk[di]._junkNumber = i;
+ _junk[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] == 41) {
+ _junk[di].changeZoom(-1);
+ _junk[di].setPosition(Common::Point(150, 70));
+ _junk[di].setup(1562, 1, 1);
+
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[2]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[3]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[6]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[7]);
+
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
_actor9.postInit();
_actor9.setup(1562, 3, 1);
@@ -8591,35 +9024,36 @@ void Scene1550::subA2B2F() {
_actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
}
} else {
- if (k562CC[i + 2] > 40) {
- _arrUnkObj15501[di].changeZoom(100);
- _arrUnkObj15501[di].setup(1561, 1, k562CC[i + 2] - 40);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] > 40) {
+ _junk[di].changeZoom(100);
+ _junk[di].setup(1561, 1, R2_GLOBALS._scene1550JunkLocations[i + 2] - 40);
} else {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setup(1552, ((k562CC[i + 2] - 1) / 5) + 1, ((k562CC[i + 2] - 1) % 5) + 1);
+ _junk[di].changeZoom(-1);
+ _junk[di].setup(1552, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) / 5) + 1, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) % 5) + 1);
}
- _arrUnkObj15501[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
- if (k5A78A[tmpIdx] != 0)
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[tmpIdx]);
+ _junk[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
+ if (scene1550JunkRegions[tmpIdx] != 0)
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[tmpIdx]);
di++;
}
}
}
for (int i = 0; i < 15 * 3; i++) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k5A79B[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k5A79B[i + 1])) {
+ 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:
if (!R2_GLOBALS.getFlag(16)) {
- _actor1.postInit();
- if (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 3)
- _actor1.setup(1555, 2, 1);
+ _landingStrut.postInit();
+ if (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 3)
+ _landingStrut.setup(1555, 2, 1);
else
- _actor1.setup(1555, 1, 1);
- _actor1.setPosition(Common::Point(150, 100));
- _actor1.fixPriority(92);
- _actor1.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
+ _landingStrut.setup(1555, 1, 1);
+ _landingStrut.setPosition(Common::Point(150, 100));
+ _landingStrut.fixPriority(92);
+ _landingStrut.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 1:
@@ -8658,20 +9092,20 @@ void Scene1550::subA2B2F() {
_actor4.setPosition(Common::Point(172, 48));
_actor4.fixPriority(169);
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[15]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[15]);
break;
case 2:
- _actor6.postInit();
- _actor6.setup(1550, 1, 1);
- _actor6.setPosition(Common::Point(259, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 2);
- _actor1.setPosition(Common::Point(259, 133));
- _actor1.fixPriority(105);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _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);
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
_actor10.postInit();
_actor10.setup(1550, 7, 2);
@@ -8681,16 +9115,16 @@ void Scene1550::subA2B2F() {
}
break;
case 3:
- _actor6.postInit();
- _actor6.setup(1550, 1, 4);
- _actor6.setPosition(Common::Point(76, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 3);
- _actor1.setPosition(Common::Point(76, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _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);
if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
_actor11.postInit();
_actor11.setup(1504, 4, 1);
@@ -8709,48 +9143,48 @@ void Scene1550::subA2B2F() {
}
break;
case 4:
- _actor6.postInit();
- _actor6.setup(1550, 2, 4);
- _actor6.setPosition(Common::Point(243, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 3);
- _actor1.setPosition(Common::Point(243, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _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);
break;
case 5:
- _actor6.postInit();
- _actor6.setup(1550, 2, 1);
- _actor6.setPosition(Common::Point(60, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 2);
- _actor1.setPosition(Common::Point(60, 133));
- _actor1.fixPriority(106);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _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);
break;
case 6:
- _actor6.postInit();
- _actor6.setup(1550, 3, 1);
- _actor6.setPosition(Common::Point(281, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _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:
- _actor6.postInit();
- _actor6.setup(1550, 3, 2);
- _actor6.setPosition(Common::Point(57, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 3, 3);
- _actor1.setPosition(Common::Point(145, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _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);
@@ -8764,17 +9198,17 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 8:
- _actor6.postInit();
- _actor6.setup(1550, 4, 2);
- _actor6.setPosition(Common::Point(262, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 4, 3);
- _actor1.setPosition(Common::Point(174, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _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);
@@ -8788,55 +9222,56 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 9:
- _actor6.postInit();
- _actor6.setup(1550, 4, 1);
- _actor6.setPosition(Common::Point(38, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _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:
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[0].subA5CDF(1);
- _arrUnkObj15502[1].subA5CDF(2);
- _arrUnkObj15502[2].subA5CDF(3);
- _arrUnkObj15502[3].subA5CDF(4);
- _arrUnkObj15502[4].subA5CDF(5);
- _arrUnkObj15502[5].subA5CDF(6);
- _arrUnkObj15502[6].subA5CDF(7);
+ // Intact ship
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[0].setupShipComponent(1);
+ _shipComponents[1].setupShipComponent(2);
+ _shipComponents[2].setupShipComponent(3);
+ _shipComponents[3].setupShipComponent(4);
+ _shipComponents[4].setupShipComponent(5);
+ _shipComponents[5].setupShipComponent(6);
+ _shipComponents[6].setupShipComponent(7);
default:
break;
}
}
}
- if ((R2_GLOBALS._v565EC[1] == R2_GLOBALS._v565EC[2]) && (R2_GLOBALS._v565EC[3] == R2_GLOBALS._v565EC[4])) {
- _actor7.postInit();
- _actor7._effect = 7;
- _actor7.changeZoom(-1);
+ if (R2_GLOBALS._s1550PlayerArea[R2_QUINN] == R2_GLOBALS._s1550PlayerArea[R2_SEEKER]) {
+ _companion.postInit();
+ _companion._effect = 7;
+ _companion.changeZoom(-1);
assert((_field419 >= 1550) && (_field419 <= 2008));
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- _actor7.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
- if (R2_GLOBALS._player._characterIndex == 1) {
+ _companion.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS._player._characterScene[2] == 1580) {
- _actor7.setup(1516, 3, 17);
- _actor7.setPosition(Common::Point(272, 94));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ _companion.setup(1516, 3, 17);
+ _companion.setPosition(Common::Point(272, 94));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1505, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1505, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
} else {
if (R2_GLOBALS._player._characterScene[1] == 1580) {
- _actor7.setup(1516, 2, 14);
- _actor7.setPosition(Common::Point(276, 97));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ _companion.setup(1516, 2, 14);
+ _companion.setPosition(Common::Point(276, 97));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1500, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1500, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
}
}
@@ -8934,7 +9369,7 @@ void Scene1575::Hotspot1::process(Event &event) {
di -= 2;
scene->_field41A -= 2;
- for (int i = 0; i < 178; i++)
+ 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));
@@ -9241,7 +9676,7 @@ bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_JOYSTICK) {
- R2_INVENTORY.setObjectScene(26, 1580);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1580);
R2_GLOBALS._sceneItems.remove(&scene->_item1);
scene->_actor2.postInit();
scene->_actor2.setup(1580, 1, 4);
@@ -9260,7 +9695,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_DIAGNOSTICS_DISPLAY) {
- R2_INVENTORY.setObjectScene(28, 1580);
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1580);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._sceneItems.remove(&scene->_item2);
@@ -9269,7 +9704,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
scene->_actor3.setPosition(Common::Point(124, 108));
scene->_actor3.fixPriority(10);
- if (R2_INVENTORY.getObjectScene(26) == 1580)
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580)
scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
else
scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
@@ -9289,15 +9724,15 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
- if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(28) == 1580)
- && (R2_INVENTORY.getObjectScene(17) == 0) && (R2_INVENTORY.getObjectScene(22) == 0)
- && (R2_INVENTORY.getObjectScene(25) == 0) && (R2_INVENTORY.getObjectScene(18) == 0)
- && (R2_INVENTORY.getObjectScene(23) == 0) && (R2_INVENTORY.getObjectScene(27) == 0)) {
+ 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)
+ && (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 0) && (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 0)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 31;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(536, scene);
else
scene->_stripManager.start(537, scene);
@@ -9309,10 +9744,10 @@ bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(51) == 1580)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
- R2_INVENTORY.setObjectScene(51, R2_GLOBALS._player._characterIndex);
+ 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();
remove();
@@ -9355,8 +9790,8 @@ bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(23, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 1);
remove();
return true;
}
@@ -9387,8 +9822,8 @@ bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(27, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_IGNITOR, 1);
remove();
return true;
}
@@ -9428,7 +9863,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(26) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580) {
_actor2.postInit();
_actor2.setup(1580, 1, 4);
_actor2.setPosition(Common::Point(159, 163));
@@ -9437,7 +9872,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
}
- if (R2_INVENTORY.getObjectScene(51) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9448,7 +9883,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor1.setup(1580, 1, 3);
_actor1.setPosition(Common::Point(124, 96));
_actor1.fixPriority(20);
- } else if (R2_INVENTORY.getObjectScene(28) == 1580) {
+ } else if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9466,7 +9901,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(58) == 0) {
+ if (R2_GLOBALS.getFlag(58) == 0) {
_actor4.setup(1580, 5, 1);
_actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
} else {
@@ -9481,8 +9916,8 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor5.setPosition(Common::Point(291, 147));
_actor5.fixPriority(100);
_actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
-
- if (R2_INVENTORY.getObjectScene(23) == 1580) {
+
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 1580) {
_actor6.postInit();
_actor6.setup(1580, 6, 2);
_actor6.setPosition(Common::Point(222, 108));
@@ -9490,7 +9925,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
}
- if (R2_INVENTORY.getObjectScene(27) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 1580) {
_actor7.postInit();
_actor7.setup(1580, 6, 1);
_actor7.setPosition(Common::Point(195, 108));
@@ -9499,11 +9934,9 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1580;
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);
-
}
void Scene1580::signal() {
@@ -9515,49 +9948,49 @@ void Scene1580::signal() {
_actor1.setup(1580, 1, 2);
_actor1.setPosition(Common::Point(124, 94));
- if (R2_INVENTORY.getObjectScene(18) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) != 0) {
_arrActor[0].postInit();
_arrActor[0].setup(1580, 2, 1);
_arrActor[0].setPosition(Common::Point(138, 56));
}
- if (R2_INVENTORY.getObjectScene(25) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) != 0) {
_arrActor[1].postInit();
_arrActor[1].setup(1580, 2, 2);
_arrActor[1].setPosition(Common::Point(140, 66));
}
- if (R2_INVENTORY.getObjectScene(27) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) != 0) {
_arrActor[2].postInit();
_arrActor[2].setup(1580, 2, 3);
_arrActor[2].setPosition(Common::Point(142, 85));
}
- if (R2_INVENTORY.getObjectScene(23) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) != 0) {
_arrActor[3].postInit();
_arrActor[3].setup(1580, 2, 4);
_arrActor[3].setPosition(Common::Point(142, 92));
}
- if (R2_INVENTORY.getObjectScene(22) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) != 0) {
_arrActor[4].postInit();
_arrActor[4].setup(1580, 2, 5);
_arrActor[4].setPosition(Common::Point(108, 54));
}
- if (R2_INVENTORY.getObjectScene(26) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) != 1580) {
_arrActor[5].postInit();
_arrActor[5].setup(1580, 2, 6);
_arrActor[5].setPosition(Common::Point(110, 64));
}
- if (R2_INVENTORY.getObjectScene(45) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) != 0) {
_arrActor[6].postInit();
_arrActor[6].setup(1580, 2, 7);
_arrActor[6].setPosition(Common::Point(108, 80));
}
- if (R2_INVENTORY.getObjectScene(17) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) != 0) {
_arrActor[7].postInit();
_arrActor[7].setup(1580, 2, 8);
_arrActor[7].setPosition(Common::Point(111, 92));
@@ -9802,7 +10235,7 @@ void Scene1625::signal() {
_actor6.postInit();
warning("_actor6._actorName = \"arm\";");
- R2_INVENTORY.setObjectScene(40, 3);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3);
_sceneMode = 14;
setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
@@ -9849,9 +10282,10 @@ void Scene1625::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 1700 -
+ * Scene 1700 - Rim
*
*--------------------------------------------------------------------------*/
+
Scene1700::Scene1700() {
_field77A = 0;
_field77C = 0;
@@ -9870,7 +10304,7 @@ bool Scene1700::Item2::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1700::Actor11::startAction(CursorType action, Event &event) {
+bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -9898,7 +10332,7 @@ bool Scene1700::Actor12::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1700::Exit1::changeScene() {
+void Scene1700::NorthExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -9910,7 +10344,7 @@ void Scene1700::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::Exit2::changeScene() {
+void Scene1700::SouthExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -9922,7 +10356,7 @@ void Scene1700::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::Exit3::changeScene() {
+void Scene1700::WestExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -9934,20 +10368,20 @@ void Scene1700::Exit3::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::subAF3F8() {
+void Scene1700::enterArea() {
Rect tmpRect;
R2_GLOBALS._walkRegions.load(1700);
- _actor3.remove();
- _actor4.remove();
- _actor5.remove();
- _actor6.remove();
- _actor7.remove();
- _actor8.remove();
- _actor11.remove();
-
+ _slabWest.remove();
+ _slabEast.remove();
+ _slabShadowWest.remove();
+ _slabShadowEast.remove();
+ _westPlatform.remove();
+ _rimTransportDoor.remove();
+ _rimTransport.remove();
+
if (_sceneMode != 40) {
- _actor9.remove();
+ _ledgeHopper.remove();
_actor10.remove();
}
@@ -9963,68 +10397,72 @@ void Scene1700::subAF3F8() {
warning("set_pane_p(_paneNumber);");
- if ((_sceneMode != 40) && (R2_GLOBALS._v565F6 != 0)){
- _actor9.postInit();
- _actor9.setup(1701, 1, 1);
- _actor9.setPosition(Common::Point(220, 137));
- _actor9.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
+ if (_sceneMode != 40 && R2_GLOBALS._rimLocation == 0) {
+ // Crashed ledge hopper
+ _ledgeHopper.postInit();
+ _ledgeHopper.setup(1701, 1, 1);
+ _ledgeHopper.setPosition(Common::Point(220, 137));
+ _ledgeHopper.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(12);
}
- if ((R2_GLOBALS._v565F6 + 2) % 4 == 0) {
- _actor3.postInit();
- _actor3.setup(1700, 1, 1);
- _actor3.setPosition(Common::Point(222, 82));
- _actor3.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+ if ((R2_GLOBALS._rimLocation + 2) % 4 == 0) {
+ // The slabs forming the bottom of the regular rings the rim transport travels through
+ _slabWest.postInit();
+ _slabWest.setup(1700, 1, 1);
+ _slabWest.setPosition(Common::Point(222, 82));
+ _slabWest.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5.setup(1700, 2, 1);
- _actor5.setPosition(Common::Point(177, 82));
- _actor5.fixPriority(0);
+ _slabShadowWest.postInit();
+ _slabShadowWest.setup(1700, 2, 1);
+ _slabShadowWest.setPosition(Common::Point(177, 82));
+ _slabShadowWest.fixPriority(0);
- _actor6.postInit();
- _actor6.setup(1700, 2, 2);
- _actor6.setPosition(Common::Point(332, 96));
- _actor6.fixPriority(0);
+ _slabShadowEast.postInit();
+ _slabShadowEast.setup(1700, 2, 2);
+ _slabShadowEast.setPosition(Common::Point(332, 96));
+ _slabShadowEast.fixPriority(0);
- _actor4.postInit();
- _actor4.setup(1700, 1, 2);
- _actor4.setPosition(Common::Point(424, 84));
+ _slabEast.postInit();
+ _slabEast.setup(1700, 1, 2);
+ _slabEast.setPosition(Common::Point(424, 84));
R2_GLOBALS._walkRegions.enableRegion(11);
}
- if ((R2_GLOBALS._v565F6 + 399) % 800 == 0) {
- _actor7.postInit();
- _actor7.setup(1700, 3, 2);
- _actor7.setPosition(Common::Point(51, 141));
- _actor7.fixPriority(0);
- _actor7.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+ if ((R2_GLOBALS._rimLocation + 399) % 800 == 0) {
+ // Enable west exit to lift
+ _westPlatform.postInit();
+ _westPlatform.setup(1700, 3, 2);
+ _westPlatform.setPosition(Common::Point(51, 141));
+ _westPlatform.fixPriority(0);
+ _westPlatform.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
- _exit3._enabled = true;
+ _westExit._enabled = true;
} else {
R2_GLOBALS._walkRegions.enableRegion(1);
- _exit3._enabled = false;
+ _westExit._enabled = false;
}
- if ( ((!R2_GLOBALS.getFlag(15)) && ((R2_GLOBALS._v565F6 == 25) || (R2_GLOBALS._v565F6 == -3)))
- || ((R2_GLOBALS.getFlag(15)) && (R2_GLOBALS._v565F6 == R2_GLOBALS._v565FA))
+ if ( ((!R2_GLOBALS.getFlag(15)) && ((R2_GLOBALS._rimLocation == 25) || (R2_GLOBALS._rimLocation == -3)))
+ || ((R2_GLOBALS.getFlag(15)) && (R2_GLOBALS._rimLocation == R2_GLOBALS._rimTransportLocation))
) {
- R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+ // Rim transport vechile located
+ R2_GLOBALS._rimTransportLocation = R2_GLOBALS._rimLocation;
if (!R2_GLOBALS.getFlag(15))
_field77C = 1;
- _actor11.postInit();
- _actor11.setup(1700, 3, 1);
- _actor11.setPosition(Common::Point(338, 150));
- _actor11.setDetails(1700, 9, -1, -1, 2, (SceneItem *) NULL);
- _actor11.fixPriority(15);
+ _rimTransport.postInit();
+ _rimTransport.setup(1700, 3, 1);
+ _rimTransport.setPosition(Common::Point(338, 150));
+ _rimTransport.setDetails(1700, 9, -1, -1, 2, (SceneItem *) NULL);
+ _rimTransport.fixPriority(15);
- _actor8.postInit();
- _actor8.setup(1700, 4, 1);
- _actor8.setPosition(Common::Point(312, 106));
- _actor8.fixPriority(130);
+ _rimTransportDoor.postInit();
+ _rimTransportDoor.setup(1700, 4, 1);
+ _rimTransportDoor.setPosition(Common::Point(312, 106));
+ _rimTransportDoor.fixPriority(130);
}
}
@@ -10038,12 +10476,9 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _field77A = 0;
- _field77C = 0;
-
- _exit1.setDetails(Rect(94, 0, 319, 12), EXITCURSOR_N, 1700);
- _exit2.setDetails(Rect(0, 161, 319, 168), EXITCURSOR_S, 1700);
- _exit3.setDetails(Rect(0, 0, 2, 138), EXITCURSOR_W, 1800);
+ _northExit.setDetails(Rect(94, 0, 319, 12), EXITCURSOR_N, 1700);
+ _southExit.setDetails(Rect(0, 161, 319, 168), EXITCURSOR_S, 1700);
+ _westExit.setDetails(Rect(0, 0, 12, 138), EXITCURSOR_W, 1800);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setPosition(Common::Point(0, 0));
@@ -10108,14 +10543,14 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
warning("_actor10._actorName = \"hatch\";");
_actor10.hide();
- _actor9.postInit();
- _actor9.setup(1701, 1, 1);
- _actor9.setPosition(Common::Point(220, 137));
- _actor9.setDetails(1700, 6, -1, -1, 1, (SceneItem *) NULL);
+ _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();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(539, this);
_sceneMode = 40;
break;
@@ -10168,7 +10603,7 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._oldCharacterScene[2] = 1700;
R2_GLOBALS._v558B6.set(20, 0, 320, 200);
- subAF3F8();
+ enterArea();
_item1.setDetails(1, 1700, 3, -1, -1);
_item2.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
}
@@ -10182,9 +10617,9 @@ void Scene1700::signal() {
switch (_sceneMode) {
case 1: {
_sceneMode = 3;
- if ((R2_GLOBALS._v565F6 < 2400) && (R2_GLOBALS._v565F6 >= 0))
- ++R2_GLOBALS._v565F6;
- subAF3F8();
+ if (R2_GLOBALS._rimLocation < 2400)
+ ++R2_GLOBALS._rimLocation;
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 103) * 167) / 100), 170));
Common::Point pt(R2_GLOBALS._player._position.x, 160);
NpcMover *mover = new NpcMover();
@@ -10207,9 +10642,9 @@ void Scene1700::signal() {
break;
case 2: {
_sceneMode = 3;
- if ((R2_GLOBALS._v565F6 > -2400) && (R2_GLOBALS._v565F6 < 0))
- R2_GLOBALS._v565F6--;
- subAF3F8();
+ if (R2_GLOBALS._rimLocation > -2400)
+ --R2_GLOBALS._rimLocation;
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 167) * 103) / 100), 0));
Common::Point pt(R2_GLOBALS._player._position.x, 10);
NpcMover *mover = new NpcMover();
@@ -10232,12 +10667,12 @@ void Scene1700::signal() {
break;
case 3:
if (_field77C == 0) {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
R2_GLOBALS.setFlag(15);
_field77C = 0;
_sceneMode = 31;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(542, this);
else
@@ -10249,10 +10684,10 @@ void Scene1700::signal() {
Common::Point pt(271, 90);
PlayerMover *mover = new PlayerMover();
_actor12.addMover(mover, &pt, NULL);
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_actor8, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_rimTransportDoor, NULL);
else
- setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_rimTransportDoor, NULL);
}
break;
case 5:
@@ -10266,13 +10701,13 @@ void Scene1700::signal() {
R2_GLOBALS._player._strip = 1;
_actor12.setObjectWrapper(new SceneObjectWrapper());
_actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.enableRegion(14);
break;
case 8:
R2_GLOBALS._player._strip = 2;
_actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.enableRegion(12);
break;
case 30:
@@ -10291,7 +10726,7 @@ void Scene1700::signal() {
case 40:
R2_GLOBALS._player.disableControl();
_sceneMode = 1704;
- setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_actor9, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_ledgeHopper, &_actor1, &_actor2, NULL);
break;
case 50:
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -10307,7 +10742,7 @@ void Scene1700::signal() {
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(12);
R2_GLOBALS._player.fixPriority(-1);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
R2_GLOBALS._player.enableControl();
@@ -10316,162 +10751,171 @@ void Scene1700::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1750 -
+ * Scene 1750 - Maintaiance Vechile
*
*--------------------------------------------------------------------------*/
-Scene1750::Actor4::Actor4() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
- _fieldAA = 0;
- _fieldAC = 0;
- _fieldAE = 0;
+
+Scene1750::Button::Button() {
+ _buttonId = 0;
}
-void Scene1750::Actor4::synchronize(Serializer &s) {
+void Scene1750::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
- s.syncAsSint16LE(_fieldAC);
- s.syncAsSint16LE(_fieldAE);
+ s.syncAsSint16LE(_buttonId);
}
-Scene1750::Actor5::Actor5() {
- _fieldA4 = 0;
-}
+bool Scene1750::Button::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
-void Scene1750::Actor5::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
+ Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
- s.syncAsSint16LE(_fieldA4);
+ switch (_buttonId) {
+ case 1:
+ // Forward button
+ show();
+ scene->_backwardButton.hide();
+ if (scene->_speed < 0)
+ scene->_speed = -scene->_speed;
+ scene->_direction = 1;
+ break;
+ case 2:
+ // Backwards button
+ show();
+ scene->_forwardButton.hide();
+ if (scene->_speed > 0)
+ scene->_speed = -scene->_speed;
+ scene->_direction = -1;
+ break;
+ case 3:
+ // Exit button
+ if (scene->_rotation->_idxChange == 0) {
+ show();
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ } else {
+ scene->_speed = 0;
+ scene->_speedSlider._moveRate = 20;
+ scene->_forwardButton._moveDiff.y = 1;
+ Common::Point pt(286, 143);
+ NpcMover *mover = new NpcMover();
+ scene->_speedSlider.addMover(mover, &pt, NULL);
+ }
+ default:
+ break;
+ }
+
+ return true;
}
-Scene1750::Scene1750() {
- _field412 = 0;
- _field413 = 0;
- _field415 = 0;
- _field417 = 0;
- _field419 = 0;
- _field41B = 0;
- _field41D = 0;
+/*------------------------------------------------------------------------*/
+
+Scene1750::SpeedSlider::SpeedSlider() {
+ _incrAmount = 0;
+ _xp = 0;
+ _ys = 0;
+ _height = 0;
+ _thumbHeight = 0;
+ _mouseDown = false;
}
-void Scene1750::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- SYNC_POINTER(_rotation);
+void Scene1750::SpeedSlider::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field413);
- s.syncAsSint16LE(_field415);
- s.syncAsSint16LE(_field417);
- s.syncAsSint16LE(_field419);
- s.syncAsSint16LE(_field41B);
- s.syncAsSint16LE(_field41D);
+ s.syncAsSint16LE(_incrAmount);
+ s.syncAsSint16LE(_xp);
+ s.syncAsSint16LE(_ys);
+ s.syncAsSint16LE(_height);
+ s.syncAsSint16LE(_thumbHeight);
+ s.syncAsSint16LE(_mouseDown);
}
-void Scene1750::Actor4::subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5) {
- _fieldA4 = arg1;
- _fieldAE = 0;
- _fieldA6 = arg2;
- _fieldA8 = arg3;
- _fieldAA = arg4;
- _fieldAC = arg5;
+void Scene1750::SpeedSlider::setupSlider(int incrAmount, int xp, int ys, int height, int thumbHeight) {
+ _mouseDown = false;
+ _incrAmount = incrAmount;
+ _xp = xp;
+ _ys = ys;
+ _height = height;
+ _thumbHeight = thumbHeight;
postInit();
setup(1750, 1, 1);
fixPriority(255);
- setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * (arg1 - 1)) / (_fieldAC - 1))));
+ setPosition(Common::Point(_xp, _ys + ((_height * (incrAmount - 1)) / (_thumbHeight - 1))));
}
-void Scene1750::Actor4::subB1B27() {
+void Scene1750::SpeedSlider::calculateSlider() {
Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
- int tmpVar = (_fieldAA / (_fieldAC - 1)) / 2;
- int tmpVar2 = ((_position.y - _fieldA8 + tmpVar) * _fieldAC) / (_fieldAA + 2 * tmpVar);
+ int tmpVar = (_height / (_thumbHeight - 1)) / 2;
+ int tmpVar2 = ((_position.y - _ys + tmpVar) * _thumbHeight) / (_height + 2 * tmpVar);
- setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * tmpVar2) / (_fieldAC - 1))));
- scene->_field415 = scene->_field412 * tmpVar2;
+ setPosition(Common::Point(_xp, _ys + ((_height * tmpVar2) / (_thumbHeight - 1))));
+ scene->_speed = scene->_direction * tmpVar2;
}
-void Scene1750::Actor4::remove() {
+void Scene1750::SpeedSlider::remove() {
// Function kept to match IDA. Could be removed.
SceneActor::remove();
}
-void Scene1750::Actor4::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
- _fieldAE = 1;
+void Scene1750::SpeedSlider::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ (_bounds.contains(event.mousePos))) {
+ _mouseDown = true;
event.eventType = EVENT_NONE;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
- _fieldAE = 0;
+ if ((event.eventType == EVENT_BUTTON_UP) && _mouseDown) {
+ _mouseDown = false;
event.handled = true;
addMover(NULL);
- subB1B27();
+ calculateSlider();
}
- if (_fieldAE != 0) {
+ if (_mouseDown) {
event.handled = true;
- if (event.mousePos.y >= _fieldA8) {
- if (_fieldA8 + _fieldAA >= event.mousePos.y)
- setPosition(Common::Point(_fieldA6, event.mousePos.y));
+ if (event.mousePos.y >= _ys) {
+ if (_ys + _height >= event.mousePos.y)
+ setPosition(Common::Point(_xp, event.mousePos.y));
else
- setPosition(Common::Point(_fieldA6, _fieldA8 + _fieldAA));
+ setPosition(Common::Point(_xp, _ys + _height));
} else {
- setPosition(Common::Point(_fieldA6, _fieldA8));
+ setPosition(Common::Point(_xp, _ys));
}
}
}
-bool Scene1750::Actor4::startAction(CursorType action, Event &event) {
+bool Scene1750::SpeedSlider::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return SceneActor::startAction(action, event);
return false;
}
-bool Scene1750::Actor5::startAction(CursorType action, Event &event) {
- if (action != CURSOR_USE)
- return SceneActor::startAction(action, event);
+/*------------------------------------------------------------------------*/
- Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
+Scene1750::Scene1750() {
+ _direction = 0;
+ _field413 = 0;
+ _speed = 0;
+ _field417 = 0;
+ _field419 = 0;
+ _field41B = 0;
+ _field41D = 0;
+}
- switch (_fieldA4) {
- case 1:
- show();
- scene->_actor6.hide();
- if (scene->_field415 < 0)
- scene->_field415 ^= 0xFFFE;
- scene->_field412 = 1;
- break;
- case 2:
- show();
- scene->_actor5.hide();
- if (scene->_field415 > 0)
- scene->_field415 ^= 0xFFFE;
- scene->_field412 = -1;
- break;
- case 3:
- if (scene->_rotation->_idxChange == 0) {
- show();
- R2_GLOBALS._sceneManager.changeScene(1700);
- } else {
- scene->_field415 = 0;
- scene->_actor4._moveRate = 20;
- scene->_actor5._moveDiff.y = 1;
- Common::Point pt(286, 143);
- NpcMover *mover = new NpcMover();
- scene->_actor4.addMover(mover, &pt, NULL);
- }
- default:
- break;
- }
+void Scene1750::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
- return true;
+ s.syncAsSint16LE(_direction);
+ s.syncAsSint16LE(_field413);
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_field417);
+ s.syncAsSint16LE(_field419);
+ s.syncAsSint16LE(_field41B);
+ s.syncAsSint16LE(_field41D);
}
void Scene1750::postInit(SceneObjectList *OwnerList) {
@@ -10491,7 +10935,7 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
_rotation->_idxChange = 0;
_rotation->_countdown = 2;
- switch ((R2_GLOBALS._v565F6 + 2) % 4) {
+ switch ((R2_GLOBALS._rimLocation + 2) % 4) {
case 0:
_rotation->_currIndex = 247;
break;
@@ -10537,7 +10981,7 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
_actor1.postInit();
_actor1.setup(1750, 2, 1);
- _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._v565F6 % 800) * 4) - 1440));
+ _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
_actor1.fixPriority(8);
_actor2.postInit();
@@ -10552,51 +10996,49 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
else
_actor2.setPosition(Common::Point(148, (tmpVar * 7) + 122));
- _actor4.subB1A76(1, 286, 143, 41, 15);
- _actor4.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
-
- _actor5.postInit();
- _actor5._fieldA4 = 1;
- _actor5.setup(1750, 1, 2);
- _actor5.setPosition(Common::Point(192, 140));
- _actor5.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
-
- _actor6.postInit();
- _actor6._fieldA4 = 2;
- _actor6.setup(1750, 1, 3);
- _actor6.setPosition(Common::Point(192, 163));
- _actor6.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
- _actor6.hide();
-
- _actor7.postInit();
- _actor7._fieldA4 = 3;
- _actor7.setup(1750, 1, 5);
- _actor7.setPosition(Common::Point(230, 183));
- _actor7.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
-
- _field412 = 1;
+ _speedSlider.setupSlider(1, 286, 143, 41, 15);
+ _speedSlider.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
+
+ _forwardButton.postInit();
+ _forwardButton._buttonId = 1;
+ _forwardButton.setup(1750, 1, 2);
+ _forwardButton.setPosition(Common::Point(192, 140));
+ _forwardButton.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+
+ _backwardButton.postInit();
+ _backwardButton._buttonId = 2;
+ _backwardButton.setup(1750, 1, 3);
+ _backwardButton.setPosition(Common::Point(192, 163));
+ _backwardButton.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+ _backwardButton.hide();
+
+ _exitButton.postInit();
+ _exitButton._buttonId = 3;
+ _exitButton.setup(1750, 1, 5);
+ _exitButton.setPosition(Common::Point(230, 183));
+ _exitButton.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
+
+ _direction = 1; // Forward by default
_field417 = 0;
_field413 = 0;
- _field415 = 0;
+ _speed = 0;
_field419 = ((_rotation->_currIndex - 218) / 4) % 4;
- _item2.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
- _item3.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
- _item4.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
- _item5.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1750, 6, 1, -1, 1, NULL);
+ _redLights.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);
+ _background.setDetails(Rect(0, 0, 320, 200), 1750, 6, 1, -1, 1, NULL);
}
void Scene1750::remove() {
- _rotation->remove();
+ if (R2_GLOBALS._rimLocation == 2400)
+ R2_GLOBALS._rimLocation = 2399;
- if (R2_GLOBALS._v565F6 == 2400)
- R2_GLOBALS._v565F6 = 2399;
+ if (R2_GLOBALS._rimLocation == -2400)
+ R2_GLOBALS._rimLocation = -2399;
- if (R2_GLOBALS._v565F6 == -2400)
- R2_GLOBALS._v565F6 = -2399;
-
- R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+ R2_GLOBALS._rimTransportLocation = R2_GLOBALS._rimLocation;
SceneExt::remove();
R2_GLOBALS._sound1.fadeOut2(NULL);
@@ -10612,26 +11054,95 @@ void Scene1750::signal() {
void Scene1750::process(Event &event) {
Scene::process(event);
if (!event.handled)
- _actor4.process(event);
+ _speedSlider.process(event);
}
-void Scene1750::dispatch() {}
+void Scene1750::dispatch() {
+ if (_rotation) {
+ if (!_field417 && (_speed != _field413)) {
+ if (_field413 >= _speed)
+ --_field413;
+ else
+ ++_field413;
+
+ _field417 = 21 - ABS(_field413);
+ }
+
+ if (_field417 == 1) {
+ if (_field413 == 0) {
+ _actor3.show();
+ _rotation->_idxChange = 0;
+ } else {
+ if (_rotation->_idxChange == 0)
+ _actor3.hide();
+
+ if (_field413 < -12) {
+ _rotation->setDelay(15 - ABS(_field413));
+ _rotation->_idxChange = -2;
+ } else if (_field413 < 0) {
+ _rotation->setDelay(10 - ABS(_field413));
+ _rotation->_idxChange = -1;
+ } else if (_field413 < 11) {
+ _rotation->setDelay(10 - _field413);
+ _rotation->_idxChange = 1;
+ } else {
+ _rotation->setDelay(15 - _field413);
+ _rotation->_idxChange = 2;
+ }
+ }
+ }
+
+ if (_field417)
+ --_field417;
+
+ _field41B = _field419;
+ _field419 = ((_rotation->_currIndex - 218) / 4) / 4;
+
+ if ((_field41B + 1) == _field419 || (_field41B - 3) == _field419) {
+ if (R2_GLOBALS._rimLocation < 2400) {
+ ++R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if ((_field41B - 1) == _field419 || (_field41B + 3) == _field419) {
+ if (R2_GLOBALS._rimLocation > -2400) {
+ --R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if (_rotation->_currIndex != _field41D) {
+ _field41D = _rotation->_currIndex;
+ _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) +
+ ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
+ }
+ }
+
+ int v = ABS(_actor1._position.y - 158) / 100;
+ if (v < 8) {
+ _actor2.show();
+ _actor2.setPosition(Common::Point((_actor1._position.y <= 158) ? 137 : 148,
+ v * 7 + 122));
+ } else {
+ _actor2.hide();
+ }
+}
/*--------------------------------------------------------------------------
- * Scene 1800 -
+ * Scene 1800 - Rim Lift Exterior
*
*--------------------------------------------------------------------------*/
+
Scene1800::Scene1800() {
- _field412 = 0;
+ _locationMode = 0;
}
void Scene1800::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_locationMode);
}
-bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
+bool Scene1800::Background::startAction(CursorType action, Event &event) {
if ((action != R2_COM_SCANNER) && (action != R2_COM_SCANNER_2))
return false;
@@ -10640,7 +11151,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS._v565F6 == 1201) {
+ if (R2_GLOBALS._rimLocation == 1201) {
scene->_stripManager.start(548, this);
} else if (R2_GLOBALS.getFlag(66)) {
return false;
@@ -10648,7 +11159,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
scene->_stripManager.start(546, this);
}
} else {
- if (R2_GLOBALS._v565F6 == 1201) {
+ if (R2_GLOBALS._rimLocation == 1201) {
scene->_stripManager.start(549, this);
} else if (R2_GLOBALS.getFlag(66)) {
return false;
@@ -10661,7 +11172,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1800::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1800::Lever::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -10677,31 +11188,34 @@ bool Scene1800::Actor6::startAction(CursorType action, Event &event) {
if (_frame == 1) {
R2_GLOBALS.setFlag(64);
scene->_sceneMode = 1810;
- scene->setAction(&scene->_sequenceManager, scene, 1810, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1810, &R2_GLOBALS._player, &scene->_lever, &scene->_leftStaircase, &scene->_rightStaircase, NULL);
} else {
R2_GLOBALS.clearFlag(64);
scene->_sceneMode = 1811;
- scene->setAction(&scene->_sequenceManager, scene, 1811, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1811, &R2_GLOBALS._player, &scene->_lever, &scene->_leftStaircase, &scene->_rightStaircase, NULL);
}
return true;
}
-bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1800::Doors::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ // Seeker trying to force open the door
R2_GLOBALS._player.disableControl();
- if (scene->_field412 >= 2) {
+ if (scene->_locationMode >= 2) {
if (R2_GLOBALS.getFlag(14)) {
+ // Allow door to close
scene->_sceneMode = 1809;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
+ // Force open door
scene->_sceneMode = 1808;
- scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.setFlag(14);
}
} else {
@@ -10711,6 +11225,7 @@ bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
} else if (R2_GLOBALS.getFlag(14)) {
return SceneActor::startAction(action, event);
} else {
+ // Quinn trying to force open doors
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1812;
scene->setAction(&scene->_sequenceManager, scene, 1812, &R2_GLOBALS._player, NULL);
@@ -10719,40 +11234,40 @@ bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1800::PassengerDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
if (_position.x < 160) {
- if (scene->_actor4._frame == 1) {
+ if (scene->_leftStaircase._frame == 1) {
return SceneActor::startAction(action, event);
} else {
R2_GLOBALS.setFlag(29);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
- scene->_sceneMode = 1804;
- scene->setAction(&scene->_sequenceManager, scene, 1804, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
- } else {
scene->_sceneMode = 1;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1804;
+ scene->setAction(&scene->_sequenceManager, scene, 1804, &R2_GLOBALS._player, &scene->_companion, &scene->_leftDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 1;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1805;
- scene->setAction(&scene->_sequenceManager, scene, 1805, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1805, &R2_GLOBALS._player, &scene->_companion, &scene->_leftDoor, NULL);
}
}
}
} else {
- if (scene->_actor4._frame == 1) {
+ if (scene->_leftStaircase._frame == 1) {
return SceneActor::startAction(action, event);
} else {
R2_GLOBALS.clearFlag(29);
@@ -10760,20 +11275,20 @@ bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ 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->_actor2, &scene->_actor9, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ 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->_actor2, &scene->_actor9, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
}
}
}
@@ -10791,16 +11306,16 @@ void Scene1800::Exit1::changeScene() {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 3;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
else
- scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_actor2, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1802;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_companion, NULL);
else
- scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_companion, NULL);
}
}
@@ -10812,95 +11327,98 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS._v565F6 = 1201;
+ R2_GLOBALS._rimLocation = 1201;
- if (R2_GLOBALS._v565F6 == 1201)
- _field412 = 2;
+ // Set the mode based on whether this is the "correct" lift or not
+ if (R2_GLOBALS._rimLocation == 1201)
+ _locationMode = 2;
else
- _field412 = 0;
+ _locationMode = 0;
scalePalette(65, 65, 65);
_exit1.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
- _item5.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
-
- _actor6.postInit();
- _actor6.setup(1801, 4, 1);
- _actor6.setPosition(Common::Point(170, 24));
- _actor6.setDetails(1800, 13, 14, 15, 1, (SceneItem *) NULL);
-
- _actor7.postInit();
- _actor7.setup(1801, 3, 1);
- _actor7.setPosition(Common::Point(160, 139));
- _actor7.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
-
- _actor8.postInit();
- _actor8.setup(1800, 1, 1);
- _actor8.setPosition(Common::Point(110, 78));
- _actor8.fixPriority(135);
- _actor8.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
-
- _actor9.postInit();
- _actor9.setup(1800, 2, 1);
- _actor9.setPosition(Common::Point(209, 78));
- _actor9.fixPriority(135);
- _actor9.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
-
- _actor4.postInit();
- if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
- _actor4.setup(1801, 2, 1);
+ _background.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
+
+ _lever.postInit();
+ _lever.setup(1801, 4, 1);
+ _lever.setPosition(Common::Point(170, 124));
+ _lever.setDetails(1800, 13, 14, 15, 1, (SceneItem *) NULL);
+
+ _doors.postInit();
+ _doors.setup(1801, 3, 1);
+ _doors.setPosition(Common::Point(160, 139));
+ _doors.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
+
+ _leftDoor.postInit();
+ _leftDoor.setup(1800, 1, 1);
+ _leftDoor.setPosition(Common::Point(110, 78));
+ _leftDoor.fixPriority(135);
+ _leftDoor.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _rightDoor.postInit();
+ _rightDoor.setup(1800, 2, 1);
+ _rightDoor.setPosition(Common::Point(209, 78));
+ _rightDoor.fixPriority(135);
+ _rightDoor.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _leftStaircase.postInit();
+ if ((_locationMode != 1) && (_locationMode != 3) && (!R2_GLOBALS.getFlag(64)))
+ _leftStaircase.setup(1801, 2, 1);
else
- _actor4.setup(1801, 2, 10);
- _actor4.setPosition(Common::Point(76, 142));
- _actor4.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+ _leftStaircase.setup(1801, 2, 10);
+ _leftStaircase.setPosition(Common::Point(76, 142));
+ _leftStaircase.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
- _actor5.setup(1801, 1, 1);
+ _rightStaircase.postInit();
+ if ((_locationMode != 1) && (_locationMode != 3) && (!R2_GLOBALS.getFlag(64)))
+ _rightStaircase.setup(1801, 1, 1);
else
- _actor5.setup(1801, 1, 10);
- _actor5.setPosition(Common::Point(243, 142));
- _actor5.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+ _rightStaircase.setup(1801, 1, 10);
+ _rightStaircase.setPosition(Common::Point(243, 142));
+ _rightStaircase.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // Standard Quinn setup
+ R2_GLOBALS._player.setVisage(1503);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ } else {
+ // Seeker setup dependent on whether he's holding the doors or not
if (R2_GLOBALS.getFlag(14)) {
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player.setup(1801, 5, 12);
R2_GLOBALS._player.setPosition(Common::Point(160, 139));
R2_GLOBALS._walkRegions.enableRegion(9);
- _actor7.hide();
+ _doors.hide();
} else {
R2_GLOBALS._player.setVisage(1507);
}
R2_GLOBALS._player._moveDiff = Common::Point(4, 2);
- } else {
- R2_GLOBALS._player.setVisage(1503);
- R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
}
- _actor2.postInit();
- _actor2.animate(ANIM_MODE_1, NULL);
- _actor2.setObjectWrapper(new SceneObjectWrapper());
+ _companion.postInit();
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
- _actor2.animate(ANIM_MODE_NONE, NULL);
- _actor2.setObjectWrapper(NULL);
- _actor2.setup(1801, 5, 12);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
+ _companion.setup(1801, 5, 12);
R2_GLOBALS._walkRegions.enableRegion(9);
- _actor7.hide();
+ _doors.hide();
} else {
- _actor2.setup(1507, 1, 1);
- _actor2.setPosition(Common::Point(180, 160));
+ _companion.setup(1507, 1, 1);
+ _companion.setPosition(Common::Point(180, 160));
}
- _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
- _actor2._moveDiff = Common::Point(4, 2);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _companion._moveDiff = Common::Point(4, 2);
} else {
- _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor2.setVisage(1503);
- _actor2._moveDiff = Common::Point(2, 2);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _companion.setVisage(1503);
+ _companion._moveDiff = Common::Point(2, 2);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
@@ -10908,11 +11426,11 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(114, 150));
R2_GLOBALS._player.setStrip(5);
if (R2_GLOBALS.getFlag(14)) {
- _actor2.setPosition(Common::Point(160, 139));
+ _companion.setPosition(Common::Point(160, 139));
R2_GLOBALS._walkRegions.enableRegion(8);
} else {
- _actor2.setPosition(Common::Point(209, 150));
- _actor2.setStrip(6);
+ _companion.setPosition(Common::Point(209, 150));
+ _companion.setStrip(6);
R2_GLOBALS._walkRegions.enableRegion(8);
}
} else {
@@ -10923,18 +11441,18 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(209, 150));
R2_GLOBALS._player.setStrip(6);
}
- _actor2.setPosition(Common::Point(114, 150));
- _actor2.setStrip(5);
+ _companion.setPosition(Common::Point(114, 150));
+ _companion.setStrip(5);
R2_GLOBALS._walkRegions.enableRegion(10);
R2_GLOBALS._walkRegions.enableRegion(11);
}
} else {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setPosition(Common::Point(140, 160));
- _actor2.setPosition(Common::Point(180, 160));
+ _companion.setPosition(Common::Point(180, 160));
} else {
R2_GLOBALS._player.setPosition(Common::Point(180, 160));
- _actor2.setPosition(Common::Point(140, 160));
+ _companion.setPosition(Common::Point(140, 160));
}
}
@@ -10960,7 +11478,7 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_actor3._effect = 5;
_actor3._field9C = _field312;
- _actor2._linkedActor = &_actor3;
+ _companion._linkedActor = &_actor3;
R2_GLOBALS._player._characterScene[1] = 1800;
R2_GLOBALS._player._characterScene[2] = 1800;
@@ -10985,27 +11503,27 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS.getFlag(29)) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1814;
- setAction(&_sequenceManager, this, 1814, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1814, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
} else {
_sceneMode = 1815;
- setAction(&_sequenceManager, this, 1815, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ 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, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
_sceneMode = 1817;
- setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ 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, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_companion, NULL);
} else {
_sceneMode = 1801;
- setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_companion, NULL);
}
}
@@ -11018,27 +11536,27 @@ void Scene1800::signal() {
case 1:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1804;
- setAction(&_sequenceManager, this, 1804, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1804, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
} else {
_sceneMode = 1805;
- setAction(&_sequenceManager, this, 1805, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1805, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
break;
case 2:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1806;
- setAction(&_sequenceManager, this, 1806, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1806, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
_sceneMode = 1807;
- setAction(&_sequenceManager, this, 1807, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1807, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
}
break;
case 3:
_sceneMode = 1802;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- setAction(&_sequenceManager, this, 1802, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1802, &R2_GLOBALS._player, &_companion, NULL);
else
- setAction(&_sequenceManager, this, 1803, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1803, &R2_GLOBALS._player, &_companion, NULL);
break;
case 10:
// No break on purpose
@@ -11108,7 +11626,7 @@ void Scene1800::signal() {
break;
case 1808:
_sceneMode = 12;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(553, this);
break;
case 1812:
@@ -12360,7 +12878,7 @@ void Scene1900::signal() {
R2_GLOBALS._sceneManager.changeScene(1925);
break;
case 1910:
- R2_INVENTORY.setObjectScene(22, 2535);
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 2535);
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
R2_GLOBALS._player._oldCharacterScene[1] = 1900;
R2_GLOBALS._player._oldCharacterScene[2] = 1900;
@@ -13110,7 +13628,6 @@ void Scene1950::Area1::remove() {
_areaActor.remove();
SceneArea::remove();
R2_GLOBALS._insetUp--;
- //
if (!R2_GLOBALS.getFlag(37))
R2_GLOBALS._sound2.play(278);
@@ -13130,7 +13647,7 @@ void Scene1950::Area1::remove() {
}
void Scene1950::Area1::process(Event &event) {
-// This is a copy of Scene1200::LaserPanel::process
+ // This is a copy of Scene1200::LaserPanel::process
if (_field20 != R2_GLOBALS._insetUp)
return;
@@ -13138,19 +13655,16 @@ void Scene1950::Area1::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -13211,14 +13725,14 @@ bool Scene1950::Actor2::startAction(CursorType action, Event &event) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(31, 0);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
scene->_sceneMode = 1958;
scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_actor2, NULL);
return true;
}
bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(35) != 1950))
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
return SceneActor::startAction(action, event);
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
@@ -13487,7 +14001,7 @@ void Scene1950::Exit6::changeScene() {
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
R2_GLOBALS._v566A5 = 5;
if (R2_GLOBALS._v566A4 == 2) {
- if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(34) == 2) && (R2_INVENTORY.getObjectScene(35) == 2)) {
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
scene->_sceneMode = 1961;
Common::Point pt(-20, 160);
NpcMover *mover = new NpcMover();
@@ -13495,7 +14009,7 @@ void Scene1950::Exit6::changeScene() {
} else {
if (!R2_GLOBALS.getFlag(36))
SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- if ((R2_INVENTORY.getObjectScene(34) == 1950) || (R2_INVENTORY.getObjectScene(35) == 1950))
+ 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);
scene->_sceneMode = 0;
Common::Point pt(30, 160);
@@ -13806,7 +14320,7 @@ void Scene1950::subBDC1E() {
switch (R2_GLOBALS._v566A4 - 1) {
case 0:
_exit7._enabled = true;
- if ((R2_INVENTORY.getObjectScene(31) == 0) && (R2_INVENTORY.getObjectScene(34) == 1950))
+ if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
_exit8._enabled = true;
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(3);
@@ -14324,7 +14838,7 @@ void Scene1950::subBE59B() {
_field416 = 1;
}
}
- if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(31) != 0)) {
+ if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
_actor2.postInit();
_actor2.setVisage(1948);
_actor2.setStrip(3);
@@ -14360,7 +14874,7 @@ void Scene1950::subBE59B() {
_item2.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
- if (R2_INVENTORY.getObjectScene(34) == 1950) {
+ if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
_actor5.postInit();
_actor5.setVisage(1970);
_actor5.setStrip(1);
@@ -14391,7 +14905,7 @@ void Scene1950::subBE59B() {
_actor3.setPosition(Common::Point(76, 94));
_actor3.fixPriority(25);
_actor3.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(35) == 2)
+ if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
_actor3.setFrame(2);
else
_actor3.setFrame(1);
@@ -14410,7 +14924,7 @@ void Scene1950::subBE59B() {
switch (R2_GLOBALS._v566A5) {
case 0:
_sceneMode = 1950;
- if (R2_INVENTORY.getObjectScene(31) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) {
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
} else {
@@ -14625,8 +15139,8 @@ void Scene1950::postInit(SceneObjectList *OwnerList) {
_exit8.setDest(Common::Point(268, 149));
R2_GLOBALS._player.postInit();
- if ( (R2_INVENTORY.getObjectScene(32) == 0) && (R2_INVENTORY.getObjectScene(33) == 0)
- && (R2_INVENTORY.getObjectScene(46) == 0) && (!R2_GLOBALS.getFlag(36)) )
+ if ( (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 0) && (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_SOAKED_FACEMASK) == 0) && (!R2_GLOBALS.getFlag(36)) )
R2_GLOBALS._player.setVisage(22);
else
R2_GLOBALS._player.setVisage(20);
@@ -14729,7 +15243,7 @@ void Scene1950::signal() {
_exit8._enabled = true;
break;
case 1959:
- R2_INVENTORY.setObjectScene(46, 0);
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
_exit8._enabled = true;
@@ -14760,7 +15274,7 @@ void Scene1950::signal() {
_actor5.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
case 1967: {
_sceneMode = 0;
- R2_INVENTORY.setObjectScene(34, 2);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
_actor5.remove();
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -14775,7 +15289,7 @@ void Scene1950::signal() {
break;
case 1968:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(35, 2);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
_actor3.setFrame(2);
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -14795,7 +15309,7 @@ void Scene1950::process(Event &event) {
&& (R2_GLOBALS._player._uiEnabled)
&& (R2_GLOBALS._events.getCursor() == R2_LIGHT_BULB)
&& (R2_GLOBALS._player._bounds.contains(event.mousePos))
- && (R2_INVENTORY.getObjectScene(31) == 0)) {
+ && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
event.handled = true;
R2_GLOBALS._player.disableControl();
_exit7._enabled = false;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index 1b6ca768ef..8b2b130ff7 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -39,6 +39,24 @@ namespace Ringworld2 {
using namespace TsAGE;
+class Scene1000 : public SceneExt {
+public:
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ SpeakerGameText _gameTextSpeaker;
+ AnimationPlayer _animationPlayer;
+
+ int _animCounter;
+ bool _forceCheckAnimationFl;
+public:
+ Scene1000();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+};
+
class Scene1010 : public SceneExt {
public:
SequenceManager _sequenceManager;
@@ -57,21 +75,21 @@ public:
};
class Scene1100 : public SceneExt {
- class Actor16 : public SceneActor {
+ class Seeker : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor17 : public SceneActor {
+ class Trooper : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor18 : public SceneActor {
+ class Chief : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412, _field414;
+ int _nextStripNum, _paletteRefreshStatus;
SpeakerSeeker1100 _seekerSpeaker;
SpeakerQuinn1100 _quinnSpeaker;
SpeakerChief1100 _chiefSpeaker;
@@ -85,24 +103,24 @@ public:
NamedHotspot _item7;
SceneActor _actor1;
SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
- SceneActor _actor12;
- SceneActor _actor13;
- SceneActor _actor14;
- SceneActor _actor15;
- BackgroundSceneObject _object1;
+ SceneActor _shipFormation;
+ SceneActor _shipFormationShadow;
+ SceneActor _shotImpact1;
+ SceneActor _shotImpact2;
+ SceneActor _shotImpact3;
+ SceneActor _shotImpact4;
+ SceneActor _shotImpact5;
+ SceneActor _laserShot;
+ SceneActor _animation;
+ SceneActor _leftImpacts;
+ SceneActor _runningGuy1;
+ SceneActor _runningGuy2;
+ SceneActor _runningGuy3;
+ BackgroundSceneObject _rightLandslide;
BackgroundSceneObject _object2;
- Actor16 _actor16;
- Actor17 _actor17;
- Actor18 _actor18;
+ Seeker _seeker;
+ Trooper _trooper;
+ Chief _chief;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
@@ -120,7 +138,7 @@ public:
class Scene1200 : public SceneExt {
enum CrawlDirection { CRAWL_EAST = 1, CRAWL_WEST = 2, CRAWL_SOUTH = 3, CRAWL_NORTH = 4 };
- class LaserPanel: public SceneArea {
+ class LaserPanel: public ModalWindow {
public:
class Jumper : public SceneActorExt {
public:
@@ -128,21 +146,14 @@ class Scene1200 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- SceneActor _actor2;
Jumper _jumper1;
Jumper _jumper2;
Jumper _jumper3;
- byte _field20;
-
LaserPanel();
- void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
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);
};
public:
@@ -416,26 +427,26 @@ class Scene1550 : public SceneExt {
void subA4D14(int frameNumber, int strip);
};
- class UnkObj15501 : public SceneActor {
+ class Junk : public SceneActor {
public:
int _fieldA4;
- int _fieldA6;
+ int _junkNumber;
- UnkObj15501();
+ Junk();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
- class UnkObj15502 : public SceneActor {
+ class ShipComponent : public SceneActor {
public:
- int _fieldA4;
+ int _componentId;
- UnkObj15502();
+ ShipComponent();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
- void subA5CDF(int strip);
+ void setupShipComponent(int componentId);
};
class UnkObj15503 : public SceneActor {
@@ -461,7 +472,7 @@ class Scene1550 : public SceneExt {
virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
- class Hotspot1 : public NamedHotspot {
+ class WorkingShip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -471,12 +482,12 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Wreckage : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Companion : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -511,7 +522,7 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor14 : public SceneActor1550 {
+ class Wall : public SceneActor1550 {
// Nothing specific found in the original
// TODO: check if it's an useless class
};
@@ -519,30 +530,30 @@ class Scene1550 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot1 _item2;
+ WorkingShip _shipHull;
+ WorkingShip _item2;
Hotspot3 _item3;
- SceneActor _actor1;
+ SceneActor _landingStrut;
SceneActor _actor2;
SceneActor _actor3;
SceneActor _actor4;
SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
+ Wreckage _wreckage;
+ Companion _companion;
Actor8 _actor8;
Actor9 _actor9;
Actor10 _actor10;
Actor11 _actor11;
Actor12 _actor12;
Actor13 _actor13;
- UnkObj15501 _arrUnkObj15501[8];
- Actor14 _actor14;
- Actor14 _actor15;
- Actor14 _actor16;
- Actor14 _actor17;
- Actor14 _actor18;
- Actor14 _actor19;
- UnkObj15502 _arrUnkObj15502[8];
+ Junk _junk[8];
+ Wall _actor14;
+ Wall _northWall; // Is also reused for landing strip
+ Wall _actor16;
+ Wall _westWall; // Is also reused for left hand space
+ Wall _eastWall;
+ Wall _southWall;
+ ShipComponent _shipComponents[8];
UnkArea1550 _unkArea1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -555,7 +566,7 @@ public:
Scene1550();
void synchronize(Serializer &s);
- void subA2B2F();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -710,7 +721,7 @@ class Scene1700 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor11 : public SceneActor {
+ class RimTransport : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -719,15 +730,15 @@ class Scene1700 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -738,19 +749,19 @@ public:
Item2 _item2;
SceneActor _actor1;
SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
+ SceneActor _slabWest;
+ SceneActor _slabEast;
+ SceneActor _slabShadowWest;
+ SceneActor _slabShadowEast;
+ SceneActor _westPlatform;
+ SceneActor _rimTransportDoor;
+ SceneActor _ledgeHopper;
SceneActor _actor10;
- Actor11 _actor11;
+ RimTransport _rimTransport;
Actor12 _actor12;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
+ NorthExit _northExit;
+ SouthExit _southExit;
+ WestExit _westExit;
SequenceManager _sequenceManager;
int _field77A;
@@ -758,7 +769,7 @@ public:
Scene1700();
void synchronize(Serializer &s);
- void subAF3F8();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -766,54 +777,54 @@ public:
};
class Scene1750 : public SceneExt {
- class Actor4 : public SceneActor {
+ class SpeedSlider : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
- int _fieldAA;
- int _fieldAC;
- int _fieldAE;
+ int _incrAmount;
+ int _xp;
+ int _ys;
+ int _height;
+ int _thumbHeight;
+ bool _mouseDown;
- Actor4();
+ SpeedSlider();
virtual void synchronize(Serializer &s);
- void subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5);
- void subB1B27();
+ 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);
};
- class Actor5 : public SceneActor {
+ class Button : public SceneActor {
public:
- int _fieldA4;
+ int _buttonId;
- Actor5();
+ Button();
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
+ NamedHotspot _background;
+ NamedHotspot _redLights;
+ NamedHotspot _greenLights;
+ NamedHotspot _frontView;
+ NamedHotspot _rearView;
SceneActor _actor1;
SceneActor _actor2;
SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor5 _actor6;
- Actor5 _actor7;
+ SpeedSlider _speedSlider;
+ Button _forwardButton;
+ Button _backwardButton;
+ Button _exitButton;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
- int _field412;
+ int _direction;
int _field413;
- int _field415;
+ int _speed;
int _field417;
int _field419;
int _field41B;
@@ -830,20 +841,20 @@ public:
};
class Scene1800 : public SceneExt {
- class Hotspot5 : public NamedHotspot {
+ class Background : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Lever : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Doors : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class PassengerDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -853,23 +864,23 @@ class Scene1800 : public SceneExt {
virtual void changeScene();
};
public:
- int _field412;
+ int _locationMode;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
NamedHotspot _item1;
NamedHotspot _item2;
NamedHotspot _item3;
NamedHotspot _item4;
- Hotspot5 _item5;
+ Background _background;
SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _companion;
SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- Actor8 _actor9;
+ SceneActor _leftStaircase;
+ SceneActor _rightStaircase;
+ Lever _lever;
+ Doors _doors;
+ PassengerDoor _leftDoor;
+ PassengerDoor _rightDoor;
Exit1 _exit1;
SequenceManager _sequenceManager;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index 02a0c05c0c..f802f0b2e5 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -762,13 +762,14 @@ Scene2000::Scene2000(): SceneExt() {
R2_GLOBALS._v56605[1] = 21;
R2_GLOBALS._v56605[2] = 21;
}
- if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]
- != R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex])
+ if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]
+ != R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex])
&& (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 2350)) {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 0;
}
_exitingFlag = false;
+ _mazePlayerMode = 0;
}
void Scene2000::postInit(SceneObjectList *OwnerList) {
@@ -1116,7 +1117,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
_actor3.postInit();
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(20) == 2350) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2350) {
_actor3.hide();
_actor4.hide();
} else {
@@ -1176,12 +1177,12 @@ void Scene2350::signal() {
break;
case 21:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(36, 1);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 1);
_sceneMode = 2354;
setAction(&_sequenceManager, this, 2354, &R2_GLOBALS._player, NULL);
break;
case 2354:
- R2_INVENTORY.setObjectScene(20, 2350);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2350);
g_globals->_sceneManager.changeScene(2900);
break;
case 2355:
@@ -1534,7 +1535,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(37) == 2430) {
+ if (R2_INVENTORY.getObjectScene(R2_GUNPOWDER) == 2430) {
_actor2.postInit();
_actor2.setup(2435, 1, 5);
_actor2.setPosition(Common::Point(205, 119));
@@ -1542,7 +1543,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_actor2.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(50) == 2435) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2435) {
_actor3.postInit();
_actor3.setup(2435, 1, 1);
_actor3.setPosition(Common::Point(31, 65));
@@ -1820,7 +1821,7 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
// Fix exit cursor, the original was using NW
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(49) == 2440) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2440) {
_actor2.postInit();
_actor2.setup(2435, 1, 1);
_actor2.setPosition(Common::Point(94, 80));
@@ -1885,7 +1886,7 @@ void Scene2440::signal() {
break;
case 2440:
_actor2.remove();
- R2_INVENTORY.setObjectScene(49, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2);
// No break on purpose
default:
R2_GLOBALS._player.enableControl();
@@ -2212,7 +2213,7 @@ bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_GLASS_DOME) {
- if ((R2_INVENTORY.getObjectScene(49) == 2455) || (R2_INVENTORY.getObjectScene(50) == 2455)) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2458;
scene->_actor2._lookLineNum = 9;
@@ -2232,7 +2233,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
switch (action) {
case R2_ALCOHOL_LAMP_2:
- if (R2_INVENTORY.getObjectScene(50) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2244,7 +2245,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
}
break;
case R2_ALCOHOL_LAMP_3:
- if (R2_INVENTORY.getObjectScene(49) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2290,15 +2291,15 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(29, 2);
- R2_INVENTORY.setObjectScene(50, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2);
}
R2_GLOBALS._sound1.play(200);
_exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
- if ((R2_INVENTORY.getObjectScene(50) == 2455) || (R2_INVENTORY.getObjectScene(49) == 2455)) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455)) {
_actor1.postInit();
_actor1.setup(2456, 3, 3);
_actor1.setPosition(Common::Point(162, 165));
@@ -2312,11 +2313,11 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.postInit();
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
_actor2.setup(2456, 3, 2);
_actor2.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
} else {
- if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455))
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) && (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455))
_actor2.setup(2455, 1, 1);
else
_actor2.setup(2456, 1, 1);
@@ -2324,7 +2325,7 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.setPosition(Common::Point(162, 165));
_actor2.fixPriority(20);
- if (R2_INVENTORY.getObjectScene(29) != 2455)
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) != 2455)
_actor2.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.postInit();
@@ -2356,23 +2357,23 @@ void Scene2455::signal() {
g_globals->_sceneManager.changeScene(2425);
break;
case 11:
- R2_INVENTORY.setObjectScene(49, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 12:
- R2_INVENTORY.setObjectScene(50, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2458:
- R2_INVENTORY.setObjectScene(29, 2455);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2459:
_actor3.remove();
- R2_INVENTORY.setObjectScene(31, 2);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 2);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
@@ -2542,7 +2543,7 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
- if (R2_INVENTORY.getObjectScene(29) == 2525) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2525) {
_actor3.postInit();
_actor3.setup(2435, 1, 2);
_actor3.setPosition(Common::Point(78, 155));
@@ -2615,7 +2616,7 @@ void Scene2525::signal() {
break;
case 2525:
_actor3.remove();
- R2_INVENTORY.setObjectScene(29, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
R2_GLOBALS._player.enableControl();
break;
case 2526:
@@ -2698,7 +2699,7 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(33) == 2530) {
+ if (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 2530) {
_actor2.postInit();
_actor2.setup(2435, 1, 3);
_actor2.setPosition(Common::Point(299, 80));
@@ -2766,7 +2767,7 @@ void Scene2530::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2530:
- R2_INVENTORY.setObjectScene(33, 2);
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 2);
_actor2.remove();
break;
case 2531:
@@ -2798,7 +2799,7 @@ bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterIndex == 1) {
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
scene->_sceneMode = 2536;
scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL);
} else {
@@ -2846,12 +2847,12 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS.setFlag(73);
- R2_INVENTORY.setObjectScene(20, 2535);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
}
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(32) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 2535) {
_actor4.postInit();
_actor4.setup(2435, 1, 4);
_actor4.setPosition(Common::Point(47, 74));
@@ -2859,7 +2860,7 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
_actor4.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
_actor3.postInit();
_actor3.setup(2535, 3, 1);
_actor3.setPosition(Common::Point(203, 131));
@@ -2867,7 +2868,7 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(6);
}
- if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) {
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 0) && (R2_GLOBALS.getFlag(73))) {
_actor3.postInit();
_actor3.setup(2536, 1, 2);
_actor3.setPosition(Common::Point(164, 133));
@@ -2933,12 +2934,12 @@ void Scene2535::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2535:
- R2_INVENTORY.setObjectScene(32, 2);
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 2);
_actor4.remove();
R2_GLOBALS._player.enableControl();
break;
case 2536:
- R2_INVENTORY.setObjectScene(20, 0);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 0);
R2_GLOBALS._walkRegions.disableRegion(6);
if (!R2_GLOBALS.getFlag(73)) {
_actor3.remove();
@@ -2958,7 +2959,7 @@ void Scene2535::signal() {
break;
case 2537:
_actor3.remove();
- R2_INVENTORY.setObjectScene(20, 1);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
R2_GLOBALS._player.enableControl();
break;
case 20:
@@ -3056,7 +3057,7 @@ void Scene2700::Action4::signal() {
void Scene2700::Area1::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ 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;
@@ -3106,7 +3107,7 @@ void Scene2700::Area1::process(Event &event) {
void Scene2700::Area2::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ 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;
@@ -3211,7 +3212,7 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0)
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0)
R2_GLOBALS._sound1.changeSound(234);
if (R2_GLOBALS._sceneManager._previousScene == 2750) {
@@ -3452,7 +3453,7 @@ void Scene2700::signal() {
}
break;
case 11:
- R2_INVENTORY.setObjectScene(36, 0);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 0);
R2_GLOBALS._player.disableControl();
_field412 = 0;
_sceneMode = 2700;
@@ -3854,7 +3855,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_rect2.set(130, 142, 210, 167);
_rect3.set(-1, 137, 290, 147);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.changeSound(235);
_actor2.postInit();
_actor2.setup(2751, 1, 1);
@@ -3929,7 +3930,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_nejSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
_actor1.postInit();
_actor1.setup(2752, 5, 1);
_actor1.animate(ANIM_MODE_NONE, NULL);
@@ -3943,7 +3944,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._sceneManager._previousScene == 2700) {
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setVisage(2752);
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
@@ -4448,7 +4449,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_nejSpeaker);
_stripManager.addSpeaker(&_guardSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.fadeSound(237);
if (R2_GLOBALS.getFlag(47)) {
_item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
@@ -4469,7 +4470,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(47)) {
R2_GLOBALS._player.setVisage(3110);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index d5e7b1b9c1..7703d49188 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -378,7 +378,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_INVENTORY.getObjectScene(47) != 3150)
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150)
return SceneHotspot::startAction(action, event);
R2_GLOBALS._player.disableControl();
@@ -386,7 +386,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_actor3, NULL);
return true;
case R2_SUPERCONDUCTOR_WIRE:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_GLOBALS.getFlag(75))) {
R2_GLOBALS._player.disableControl();
scene->_actor3.postInit();
scene->_actor3._effect = 3;
@@ -417,7 +417,7 @@ bool Scene3150::Item6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_actor4, NULL);
return true;
case R2_FOOD_TRAY:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_INVENTORY.getObjectScene(40) == 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) && (R2_GLOBALS.getFlag(75))) {
scene->_actor5.postInit();
scene->_actor5._effect = 6;
scene->_actor5._shade = 3;
@@ -535,7 +535,7 @@ void Scene3150::Exit2::changeScene() {
void Scene3150::postInit(SceneObjectList *OwnerList) {
loadScene(3150);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(35, 2000);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2000);
R2_GLOBALS._player._oldCharacterScene[1] = 3100;
R2_GLOBALS._player._oldCharacterScene[3] = 0;
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
@@ -583,7 +583,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor7.fixPriority(50);
_actor7.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(41) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_PILLOW) == 3150) {
_actor4.postInit();
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(76)) {
@@ -608,13 +608,13 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
}
}
- if (R2_INVENTORY.getObjectScene(47) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 1);
_actor3.setPosition(Common::Point(73, 83));
}
- if (R2_INVENTORY.getObjectScene(40) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 3);
_actor3.setPosition(Common::Point(70, 55));
@@ -623,7 +623,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor3._shade = 5;
}
- if (R2_INVENTORY.getObjectScene(42) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_FOOD_TRAY) == 3150) {
_actor5.postInit();
if (R2_GLOBALS.getFlag(77)) {
_actor5.setup(3152, 7, 8);
@@ -675,7 +675,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
break;
}
default:
- if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(35) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
+ if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
++R2_GLOBALS._v56AA0;
_sceneMode = 3156;
_actor1.postInit();
@@ -713,7 +713,7 @@ void Scene3150::signal() {
break;
case 3151:
_actor1.remove();
- R2_INVENTORY.setObjectScene(41, 3);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3);
R2_GLOBALS._player.enableControl();
break;
case 3153:
@@ -726,37 +726,37 @@ void Scene3150::signal() {
break;
case 3154:
_actor3.remove();
- R2_INVENTORY.setObjectScene(47, 3);
+ R2_INVENTORY.setObjectScene(R2_LIGHT_BULB, 3);
R2_GLOBALS._player.enableControl();
break;
case 3155:
- R2_INVENTORY.setObjectScene(40, 3150);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3156:
_actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3157:
_actor5.remove();
- R2_INVENTORY.setObjectScene(42, 3);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3);
R2_GLOBALS._player.enableControl();
break;
case 3158:
R2_GLOBALS.setFlag(75);
- R2_INVENTORY.setObjectScene(41, 3150);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3150);
_actor4.fixPriority(110);
_actor4.setDetails(3150, 13, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.enableControl();
break;
case 3159:
R2_GLOBALS.setFlag(77);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3160:
- R2_INVENTORY.setObjectScene(52, 3150);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3150);
R2_GLOBALS.setFlag(80);
R2_GLOBALS._sceneManager.changeScene(1200);
break;
@@ -1407,7 +1407,7 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
_actor13.setPosition(Common::Point(40, 106));
_actor13.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(52) == 3260) {
+ if (R2_INVENTORY.getObjectScene(R2_TOOLBOX) == 3260) {
_actor14.postInit();
_actor14.setup(3260, 7, 1);
_actor14.setPosition(Common::Point(202, 66));
@@ -1524,8 +1524,8 @@ void Scene3260::signal() {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(52, 3);
- R2_INVENTORY.setObjectScene(43, 3);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3);
+ R2_INVENTORY.setObjectScene(R2_LASER_HACKSAW, 3);
setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_actor14, NULL);
break;
case 3273:
@@ -2771,7 +2771,7 @@ void Scene3400::signal() {
_actor2.setStrip(6);
_actor3.setStrip(3);
_actor4.setStrip(1);
- R2_INVENTORY.setObjectScene(34, 0);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 0);
_stripManager.start(3307, this);
if (R2_GLOBALS._player._characterIndex == 2) {
_sceneMode = 3400;
@@ -4008,7 +4008,7 @@ void Scene3500::dispatch() {
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 != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
@@ -5319,7 +5319,7 @@ void Scene3800::signal() {
}
void Scene3800::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
case R2_NEGATOR_GUN:
@@ -5582,7 +5582,7 @@ void Scene3900::signal() {
}
void Scene3900::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
case R2_NEGATOR_GUN:
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
index da1449efdf..e7109829b0 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.cpp
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -40,7 +40,7 @@ VisualSpeaker::VisualSpeaker(): Speaker() {
_color1 = 8;
_color2 = 0;
_displayMode = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
}
void VisualSpeaker::remove() {
@@ -49,27 +49,104 @@ void VisualSpeaker::remove() {
_fieldF8 = 0;
_object1.setStrip(_object1._strip - 1);
_object1.setFrame(_object1.getFrameCount());
- _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL);
+ _object1.animate(ANIM_MODE_6, (_speakerMode == 0xff) ? this : NULL);
} else {
- _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL);
+ _object1.animate(ANIM_MODE_6, (_speakerMode == 0xff) ? this : NULL);
}
}
Speaker::remove();
}
+void VisualSpeaker::signal() {
+ // TODO: _action->_field18 = 1;
+ if (_speakerMode == 0xff)
+ proc16();
+
+ _speakerMode = 0;
+ if (_numFrames) {
+ if (_object2) {
+ _object1.setStrip(_object1._strip + 1);
+ _object1.animate(ANIM_MODE_2, NULL);
+ _fieldF8 = 1;
+ }
+
+ 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);
+ }
+ } else if (_action && _object2) {
+ _action->setDelay(1);
+ _sceneText.remove();
+
+ R2_GLOBALS._playStream.stop();
+ }
+}
+
+void VisualSpeaker::dispatch() {
+ uint32 frameNumber = R2_GLOBALS._events.getFrameNumber();
+
+ // Delay check for character animation
+ if (_delayAmount) {
+ if (frameNumber >= _frameNumber) {
+ _delayAmount = _delayAmount - (_frameNumber - frameNumber);
+ _frameNumber = frameNumber;
+
+ if (_delayAmount <= 0) {
+ _delayAmount = 0;
+ _object1.animate(ANIM_MODE_NONE, NULL);
+ _object1.setFrame(1);
+ }
+ }
+ }
+
+ // 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)) {
+ _numFrames = 2;
+ _soundId = 0;
+ } else {
+ _sceneText.show();
+ }
+ }
+ }
+ }
+
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && (_numFrames == 2) &&
+ !R2_GLOBALS._playStream.isPlaying()) {
+ _numFrames = 0;
+ _object1.animate(ANIM_MODE_NONE);
+ _object1.setFrame(1);
+
+ if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ _action->setDelay(1);
+ }
+ }
+}
+
void VisualSpeaker::synchronize(Serializer &s) {
Speaker::synchronize(s);
SYNC_POINTER(_object2);
- s.syncAsSint16LE(_fieldF6);
+ s.syncAsSint16LE(_speakerMode);
s.syncAsSint16LE(_fieldF8);
s.syncAsSint16LE(_displayMode);
s.syncAsSint16LE(_soundId);
- s.syncAsSint16LE(_delayAmount);
s.syncAsByte(_removeObject);
- s.syncAsSint32LE(_frameNumber);
s.syncAsSint16LE(_numFrames);
+ s.syncAsSint16LE(_delayAmount);
+ s.syncAsUint32LE(_frameNumber);
+ s.syncAsSint16LE(_delayAmount2);
+ s.syncAsUint32LE(_frameNumber2);
}
void VisualSpeaker::setText(const Common::String &msg) {
@@ -127,13 +204,12 @@ void VisualSpeaker::setText(const Common::String &msg) {
_sceneText._textMode = _textMode;
_sceneText.setup(s);
- //_sceneText.clone();
-
_sceneText.setPosition(_textPos);
_sceneText.fixPriority(256);
// If subtitles are turned off, don't show the text
- if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) &&
+ !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
_sceneText.hide();
}
@@ -159,8 +235,7 @@ void VisualSpeaker::setText(const Common::String &msg) {
if (s.empty())
_numFrames = 0;
-
- if (_fieldF6) {
+ if (_speakerMode) {
if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId)
_sceneText.hide();
} else {
@@ -173,11 +248,11 @@ void VisualSpeaker::setText(const Common::String &msg) {
void VisualSpeaker::proc16() {
R2_GLOBALS._playStream.stop();
- _fieldF6 = 0;
+ _speakerMode = 0;
_object1.remove();
- assert(_object2);
- _object2->show();
+ if (_object2)
+ _object2->show();
_object2 = NULL;
_fieldF8 = 0;
}
@@ -187,6 +262,11 @@ void VisualSpeaker::setFrame(int numFrames) {
_frameNumber = R2_GLOBALS._events.getFrameNumber();
}
+void VisualSpeaker::setFrame2(int numFrames) {
+ _delayAmount2 = numFrames;
+ _frameNumber2 = R2_GLOBALS._events.getFrameNumber();
+}
+
void VisualSpeaker::setDelay(int delay) {
_delayAmount = delay;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
@@ -211,7 +291,7 @@ SpeakerCaptain3210::SpeakerCaptain3210() {
_speakerName = "Captain";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -220,7 +300,7 @@ SpeakerCaptain3210::SpeakerCaptain3210() {
}
void SpeakerCaptain3210::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -250,7 +330,7 @@ SpeakerCaretaker2450::SpeakerCaretaker2450() {
_speakerName = "CARETAKER";
_color1 = 43;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -266,7 +346,7 @@ SpeakerChief1100::SpeakerChief1100() {
_speakerName = "CHIEF";
_color1 = 8;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -275,11 +355,11 @@ SpeakerChief1100::SpeakerChief1100() {
}
void SpeakerChief1100::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor18;
+ _object2 = &scene->_chief;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -324,7 +404,7 @@ SpeakerGuard::SpeakerGuard() {
_speakerName = "GUARD";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -333,7 +413,7 @@ SpeakerGuard::SpeakerGuard() {
}
void SpeakerGuard2800::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -364,7 +444,7 @@ SpeakerJocko::SpeakerJocko() {
_speakerName = "Jocko";
_color1 = 45;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -373,7 +453,7 @@ SpeakerJocko::SpeakerJocko() {
}
void SpeakerJocko3200::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -396,7 +476,7 @@ void SpeakerJocko3200::proc15() {
}
void SpeakerJocko3220::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -419,7 +499,7 @@ void SpeakerJocko3220::proc15() {
}
void SpeakerJocko3230::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -449,7 +529,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
_speakerName = "MIRANDA";
_color1 = 154;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -458,7 +538,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
}
void SpeakerMiranda300::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3) {
@@ -498,7 +578,7 @@ void SpeakerMiranda300::proc15() {
}
void SpeakerMiranda1625::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
@@ -521,7 +601,7 @@ void SpeakerMiranda1625::proc15() {
}
void SpeakerMiranda3255::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -544,7 +624,7 @@ void SpeakerMiranda3255::proc15() {
void SpeakerMiranda3375::proc15() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3)
@@ -594,7 +674,7 @@ void SpeakerMiranda3375::proc15() {
void SpeakerMiranda3385::proc15() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3)
@@ -643,7 +723,7 @@ void SpeakerMiranda3385::proc15() {
void SpeakerMiranda3395::proc15() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3)
@@ -693,7 +773,7 @@ void SpeakerMiranda3395::proc15() {
void SpeakerMiranda3400::proc15() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3)
@@ -737,7 +817,7 @@ void SpeakerMiranda3400::proc15() {
void SpeakerMiranda3600::proc15() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3)
@@ -783,7 +863,7 @@ void SpeakerMiranda3600::proc15() {
void SpeakerMiranda3700::proc15() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor3;
@@ -840,7 +920,7 @@ SpeakerNej::SpeakerNej() {
_speakerName = "NEJ";
_color1 = 171;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -849,7 +929,7 @@ SpeakerNej::SpeakerNej() {
}
void SpeakerNej2700::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -884,7 +964,7 @@ void SpeakerNej2700::proc15() {
}
void SpeakerNej2750::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -916,7 +996,7 @@ void SpeakerNej2750::proc15() {
}
void SpeakerNej2800::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -948,7 +1028,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
_speakerName = "PHARISHA";
_color1 = 151;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -957,7 +1037,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
}
void SpeakerPharisha2435::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -984,7 +1064,7 @@ SpeakerPrivate3210::SpeakerPrivate3210() {
_speakerName = "Private";
_color1 = 45;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -993,7 +1073,7 @@ SpeakerPrivate3210::SpeakerPrivate3210() {
}
void SpeakerPrivate3210::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1023,7 +1103,7 @@ SpeakerProtector3600::SpeakerProtector3600() {
_speakerName = "Protector";
_color1 = 170;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1032,7 +1112,7 @@ SpeakerProtector3600::SpeakerProtector3600() {
}
void SpeakerProtector3600::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1084,7 +1164,7 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
_speakerName = "QUINN";
_color1 = 60;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1093,12 +1173,13 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
}
void SpeakerQuinn300::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 3) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_quinn;
}
@@ -1139,8 +1220,53 @@ void SpeakerQuinn300::proc15() {
}
}
+void SpeakerQuinn500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+
+ _object1.postInit();
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ switch (_object2->_visage) {
+ case 10:
+ _object1.setup(4021, (v == 1) ? 5 : 7, 1);
+ break;
+
+ case 1500:
+ _object1.setup(4021, (v == 1) ? 1 : 3, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerQuinn1100::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (v == 0)
@@ -1149,8 +1275,9 @@ void SpeakerQuinn1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -1188,12 +1315,13 @@ void SpeakerQuinn1100::proc15() {
}
void SpeakerQuinn2435::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -1214,12 +1342,13 @@ void SpeakerQuinn2435::proc15() {
}
void SpeakerQuinn2450::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -1242,7 +1371,7 @@ void SpeakerQuinn2450::proc15() {
}
void SpeakerQuinn2700::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1273,7 +1402,7 @@ void SpeakerQuinn2700::proc15() {
}
void SpeakerQuinn2750::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1304,7 +1433,7 @@ void SpeakerQuinn2750::proc15() {
}
void SpeakerQuinn2800::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1345,7 +1474,7 @@ void SpeakerQuinn2800::proc15() {
void SpeakerQuinn3255::proc15() {
Scene3255 *scene = (Scene3255 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor4;
@@ -1368,7 +1497,7 @@ void SpeakerQuinn3255::proc15() {
void SpeakerQuinn3375::proc15() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1)
@@ -1419,7 +1548,7 @@ void SpeakerQuinn3375::proc15() {
void SpeakerQuinn3385::proc15() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1)
@@ -1474,7 +1603,7 @@ void SpeakerQuinn3385::proc15() {
void SpeakerQuinn3395::proc15() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1)
@@ -1529,7 +1658,7 @@ void SpeakerQuinn3395::proc15() {
void SpeakerQuinn3400::proc15() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1)
@@ -1578,7 +1707,7 @@ void SpeakerQuinn3400::proc15() {
void SpeakerQuinn3600::proc15() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 1)
@@ -1626,7 +1755,7 @@ void SpeakerQuinn3600::proc15() {
void SpeakerQuinn3700::setText(const Common::String &msg) {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- switch (_fieldF6) {
+ switch (_speakerMode) {
case 2:
scene->_actor3.setup(30, 1, 1);
R2_GLOBALS._sound2.play(44);
@@ -1644,7 +1773,7 @@ void SpeakerQuinn3700::setText(const Common::String &msg) {
void SpeakerQuinn3700::proc15() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor1;
@@ -1701,7 +1830,7 @@ SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() {
_speakerName = "QUINNL";
_color1 = 35;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1718,7 +1847,7 @@ SpeakerRalf3245::SpeakerRalf3245() {
_speakerName = "Ralf";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1727,7 +1856,7 @@ SpeakerRalf3245::SpeakerRalf3245() {
}
void SpeakerRalf3245::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1770,7 +1899,7 @@ SpeakerRocko::SpeakerRocko() {
_speakerName = "Rocko";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1779,7 +1908,7 @@ SpeakerRocko::SpeakerRocko() {
}
void SpeakerRocko3200::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1802,7 +1931,7 @@ void SpeakerRocko3200::proc15() {
}
void SpeakerRocko3220::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1825,7 +1954,7 @@ void SpeakerRocko3220::proc15() {
}
void SpeakerRocko3230::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -1855,7 +1984,7 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
_speakerName = "SEEKER";
_color1 = 35;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1864,12 +1993,12 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
}
void SpeakerSeeker300::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
- } else {
+ } else {assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_seeker;
}
@@ -1899,8 +2028,45 @@ void SpeakerSeeker300::proc15() {
}
}
+void SpeakerSeeker500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ if (v == 1)
+ _object1.setup(4041, 3, 1);
+ else
+ _object1.setup(4041, 1, 1);
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerSeeker1100::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (v == 0)
@@ -1909,8 +2075,9 @@ void SpeakerSeeker1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -1959,12 +2126,13 @@ void SpeakerSeeker1100::proc15() {
}
void SpeakerSeeker1900::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1900);
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -1989,12 +2157,13 @@ void SpeakerSeeker1900::proc15() {
}
void SpeakerSeeker2435::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2015,12 +2184,13 @@ void SpeakerSeeker2435::proc15() {
}
void SpeakerSeeker2450::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2450);
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2042,7 +2212,7 @@ void SpeakerSeeker2450::proc15() {
void SpeakerSeeker3375::proc15() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2)
@@ -2091,7 +2261,7 @@ void SpeakerSeeker3375::proc15() {
void SpeakerSeeker3385::proc15() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2)
@@ -2140,7 +2310,7 @@ void SpeakerSeeker3385::proc15() {
void SpeakerSeeker3395::proc15() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2)
@@ -2189,7 +2359,7 @@ void SpeakerSeeker3395::proc15() {
void SpeakerSeeker3400::proc15() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2)
@@ -2248,7 +2418,7 @@ void SpeakerSeeker3400::proc15() {
void SpeakerSeeker3600::proc15() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
if (R2_GLOBALS._player._characterIndex == 2)
@@ -2295,7 +2465,7 @@ void SpeakerSeeker3600::proc15() {
void SpeakerSeeker3700::setText(const Common::String &msg) {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- if (_fieldF6 == 1) {
+ if (_speakerMode == 1) {
R2_GLOBALS._sound2.play(44);
scene->_actor3.setup(30, 8, 1);
} else {
@@ -2307,7 +2477,7 @@ void SpeakerSeeker3700::setText(const Common::String &msg) {
void SpeakerSeeker3700::proc15() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor2;
@@ -2359,7 +2529,7 @@ SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() {
_speakerName = "SEEKERL";
_color1 = 35;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2376,7 +2546,7 @@ SpeakerSocko3200::SpeakerSocko3200() {
_speakerName = "Socko";
_color1 = 10;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2385,7 +2555,7 @@ SpeakerSocko3200::SpeakerSocko3200() {
}
void SpeakerSocko3200::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -2411,11 +2581,11 @@ void SpeakerSocko3200::proc15() {
// Classes related to SOLDIER
//----------------------------------------------------------------------------
-SpeakerSoldier::SpeakerSoldier(int colour) {
+SpeakerSoldier::SpeakerSoldier(int color) {
_speakerName = "SOLDIER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2424,7 +2594,7 @@ SpeakerSoldier::SpeakerSoldier(int colour) {
}
void SpeakerSoldier300::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
@@ -2455,7 +2625,7 @@ SpeakerTeal::SpeakerTeal(): VisualSpeaker() {
_speakerName = "TEAL";
_color1 = 22;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2468,7 +2638,7 @@ SpeakerTealMode7::SpeakerTealMode7(): SpeakerTeal() {
}
void SpeakerTeal300::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
@@ -2492,7 +2662,7 @@ void SpeakerTeal300::proc15() {
}
void SpeakerTeal1625::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
@@ -2516,7 +2686,7 @@ void SpeakerTeal1625::proc15() {
}
void SpeakerTeal3240::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -2541,7 +2711,7 @@ void SpeakerTeal3240::proc15() {
void SpeakerTeal3400::proc15() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor4;
@@ -2598,7 +2768,7 @@ void SpeakerTeal3400::proc15() {
void SpeakerTeal3600::proc15() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor5;
@@ -2659,7 +2829,7 @@ SpeakerTomko3245::SpeakerTomko3245() {
_speakerName = "Tomko";
_color1 = 10;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2668,7 +2838,7 @@ SpeakerTomko3245::SpeakerTomko3245() {
}
void SpeakerTomko3245::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -2707,11 +2877,11 @@ void SpeakerTomko3245::proc15() {
// Classes related to WEBBSTER
//----------------------------------------------------------------------------
-SpeakerWebbster::SpeakerWebbster(int colour) {
+SpeakerWebbster::SpeakerWebbster(int color) {
_speakerName = "WEBBSTER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2720,7 +2890,7 @@ SpeakerWebbster::SpeakerWebbster(int colour) {
}
void SpeakerWebbster3240::proc15() {
- int v = _fieldF6;
+ int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
@@ -2745,7 +2915,7 @@ void SpeakerWebbster3240::proc15() {
void SpeakerWebbster3375::proc15() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor3;
@@ -2789,7 +2959,7 @@ void SpeakerWebbster3375::proc15() {
void SpeakerWebbster3385::proc15() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor3;
@@ -2833,7 +3003,7 @@ void SpeakerWebbster3385::proc15() {
void SpeakerWebbster3395::proc15() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor3;
@@ -2877,7 +3047,7 @@ void SpeakerWebbster3395::proc15() {
void SpeakerWebbster3400::proc15() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_actor3;
@@ -2925,7 +3095,7 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
_speakerName = "DUTYOFFICER";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2936,7 +3106,7 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
void SpeakerDutyOfficer::proc15() {
Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
_object2 = &scene->_object2;
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
index fa2946d56c..4dfb500f2d 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.h
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -41,21 +41,27 @@ class VisualSpeaker : public Speaker {
public:
SceneActor _object1;
SceneObject *_object2;
- int _fieldF6, _fieldF8;
+ int _speakerMode;
+ int _fieldF8;
int _displayMode;
int _soundId;
int _delayAmount;
bool _removeObject;
- int _frameNumber;
+ uint32 _frameNumber;
int _numFrames;
+ int _delayAmount2;
+ uint32 _frameNumber2;
private:
void setFrame(int numFrames);
+ void setFrame2(int numFrames);
public:
VisualSpeaker();
virtual Common::String getClassName() { return "VisualSpeaker"; }
virtual void synchronize(Serializer &s);
virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
virtual void setText(const Common::String &msg);
virtual void proc15() {}
virtual void proc16();
@@ -276,6 +282,12 @@ public:
virtual void proc15();
};
+class SpeakerQuinn500 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn500"; }
+ virtual void proc15();
+};
+
class SpeakerQuinn1100 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
@@ -414,6 +426,12 @@ public:
virtual void proc15();
};
+class SpeakerSeeker500 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker500"; }
+ virtual void proc15();
+};
+
class SpeakerSeeker1100 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
@@ -498,7 +516,7 @@ public:
class SpeakerSoldier : public VisualSpeaker {
public:
- SpeakerSoldier(int colour);
+ SpeakerSoldier(int color);
virtual Common::String getClassName() { return "SpeakerSoldier"; }
};
@@ -573,7 +591,7 @@ public:
class SpeakerWebbster : public VisualSpeaker {
public:
- SpeakerWebbster(int colour);
+ SpeakerWebbster(int color);
virtual Common::String getClassName() { return "SpeakerWebbster"; }
};
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index af2f3566ad..7143305586 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -289,7 +289,7 @@ void Saver::writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &h
// Create a thumbnail and save it
Graphics::Surface *thumb = new Graphics::Surface();
Graphics::Surface s = g_globals->_screenSurface.lockSurface();
- ::createThumbnail(thumb, (const byte *)s.pixels, SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
+ ::createThumbnail(thumb, (const byte *)s.getPixels(), SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
Graphics::saveThumbnail(*out, *thumb);
g_globals->_screenSurface.unlockSurface();
thumb->free();
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 4126e31822..d43ef792bc 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -150,6 +150,16 @@ public:
if (i != this->end()) ++i;
this->insert(i, newItem);
}
+
+ bool contains(T item) {
+ typename SynchronizedList<T>::iterator i = this->begin();
+ for (; i != this->end(); ++i) {
+ if (*i == item)
+ return true;
+ }
+
+ return false;
+ }
};
/**
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index a273ec2a0b..db38862365 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -244,7 +244,7 @@ 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.";
-const byte k562CC[] = {
+const byte scene1550JunkLocationsDefault[] = {
20, 7, 41, 6,
3, 6, 42, 11,
10, 15, 43, 6,
@@ -374,7 +374,7 @@ const byte k562CC[] = {
28, 18, 21, 1
};
-const byte k5A4D6[] = {
+const byte scene1550AreaMap[] = {
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18,
17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
@@ -409,7 +409,7 @@ const byte k5A76D[] = {
3, 3, 3, 7, 3, 7, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3
};
-const byte k5A78A[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
+const byte scene1550JunkRegions[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
const byte k5A79B[] = {
23, 3, 1,
23, 4, 1,
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index e3daf73333..8c21147191 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -199,13 +199,13 @@ extern char const *const NEED_INSTRUCTIONS;
extern char const *const WRONG_ANSWER_MSG;
// Scene 1550 arrays of constants
-extern const byte k562CC[];
-extern const byte k5A4D6[];
+extern const byte scene1550JunkLocationsDefault[];
+extern const byte scene1550AreaMap[];
extern const byte k5A72E[];
extern const byte k5A73F[];
extern const byte k5A750[];
extern const byte k5A76D[];
-extern const byte k5A78A[];
+extern const byte scene1550JunkRegions[];
extern const byte k5A79B[];
extern const byte k5A7F6[];
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index 4bd9e49875..09cc2fd56d 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -84,7 +84,10 @@ void UIQuestion::showDescription(CursorType cursor) {
case GType_Ringworld2:
if ((cursor == R2_COM_SCANNER) || (cursor == R2_COM_SCANNER_2)) {
// Show communicator
- warning("TODO: Communicator");
+ 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);
} else {
// Show object description
SceneItem::display2(3, (int)cursor);
@@ -399,7 +402,7 @@ void UIElements::setup(const Common::Point &pt) {
}
// Setup bottom-right hand buttons
- xp += 62;
+ xp = (g_vm->getGameID() == GType_Ringworld2) ? 255 : 253;
int yp = (g_vm->getGameID() == GType_BlueForce) ? 16 : 17;
_question.setup(1, 4, 7, xp, yp, 255);
_question.setEnabled(false);
@@ -410,7 +413,7 @@ void UIElements::setup(const Common::Point &pt) {
add(&_scrollLeft);
_scrollLeft._isLeft = true;
- xp += 22;
+ xp += (g_vm->getGameID() == GType_Ringworld2) ? 21 : 22;
_scrollRight.setup(1, 4, 4, xp, yp, 255);
add(&_scrollRight);
_scrollRight._isLeft = false;
@@ -451,7 +454,7 @@ void UIElements::add(UIElement *obj) {
/**
* Handles updating the visual inventory in the user interface
*/
-void UIElements::updateInventory() {
+void UIElements::updateInventory(int objectNumber) {
switch (g_vm->getGameID()) {
case GType_BlueForce:
// Update the score
@@ -480,6 +483,17 @@ void UIElements::updateInventory() {
else if (_slotStart > (lastPage - 1))
_slotStart = 0;
+ // Handle changing the page, if necessary, to ensure an optionally supplied
+ // object number will be on-screen
+ if (objectNumber != 0) {
+ for (uint idx = 0; idx < _itemList.size(); ++idx) {
+ if (_itemList[idx] == objectNumber) {
+ _slotStart = idx / 4;
+ break;
+ }
+ }
+ }
+
// Handle refreshing slot graphics
UIInventorySlot *slotList[4] = { &_slot1, &_slot2, &_slot3, &_slot4 };
diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h
index 0fbfc5a00f..d06dccd9a4 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -137,7 +137,7 @@ public:
virtual void process(Event &event);
void setup(const Common::Point &pt);
- void updateInventory();
+ void updateInventory(int objectNumber = 0);
void addScore(int amount);
void scrollInventory(bool isLeft);
diff --git a/engines/tucker/sequences.cpp b/engines/tucker/sequences.cpp
index 16c4f4f6f0..bd03eed00b 100644
--- a/engines/tucker/sequences.cpp
+++ b/engines/tucker/sequences.cpp
@@ -763,7 +763,7 @@ bool AnimationSequencePlayer::decodeNextAnimationFrame(int index, bool copyDirty
if (!copyDirtyRects) {
for (uint16 y = 0; (y < surface->h) && (y < kScreenHeight); y++)
- memcpy(_offscreenBuffer + y * kScreenWidth, (byte *)surface->pixels + y * surface->pitch, surface->w);
+ memcpy(_offscreenBuffer + y * kScreenWidth, (const byte *)surface->getBasePtr(0, y), surface->w);
} else {
_flicPlayer[index].copyDirtyRectsToBuffer(_offscreenBuffer, kScreenWidth);
}
@@ -811,7 +811,7 @@ void AnimationSequencePlayer::playIntroSeq19_20() {
if (surface)
for (int i = 0; i < kScreenWidth * kScreenHeight; ++i)
if (_offscreenBuffer[i] == 0)
- _offscreenBuffer[i] = *((byte *)surface->pixels + i);
+ _offscreenBuffer[i] = *((const byte *)surface->getPixels() + i);
if (!framesLeft)
_changeToNextSequence = true;
diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp
index 2bd7c47b62..04e83efbe5 100644
--- a/engines/tucker/tucker.cpp
+++ b/engines/tucker/tucker.cpp
@@ -941,7 +941,7 @@ void TuckerEngine::fadeOutPalette(int colorsCount) {
_system->getPaletteManager()->grabPalette(pal, 0, colorsCount);
for (int color = 0; color < colorsCount; ++color) {
for (int i = 0; i < 3; ++i) {
- const int c = int(pal[color * 3 + i]) + kFadePaletteStep * 3;
+ const int c = int(pal[color * 3 + i]) + kFadePaletteStep * 4;
pal[color * 3 + i] = MIN<int>(c, _currentPalette[color * 3 + i]);
}
}
@@ -954,7 +954,7 @@ void TuckerEngine::fadeInPalette(int colorsCount) {
_system->getPaletteManager()->grabPalette(pal, 0, colorsCount);
for (int color = 0; color < colorsCount; ++color) {
for (int i = 0; i < 3; ++i) {
- const int c = int(pal[color * 3 + i]) - kFadePaletteStep * 3;
+ const int c = int(pal[color * 3 + i]) - kFadePaletteStep * 4;
pal[color * 3 + i] = MAX<int>(c, 0);
}
}
@@ -2991,6 +2991,7 @@ enum TableInstructionCode {
kCode_gfg,
kCode_gv,
kCode_loc,
+ kCode_mof,
kCode_opt,
kCode_opf,
kCode_ofg,
@@ -3041,6 +3042,7 @@ static const struct {
{ "gfg", kCode_gfg },
{ "gv", kCode_gv },
{ "loc", kCode_loc },
+ { "mof", kCode_mof },
{ "opt", kCode_opt },
{ "opf", kCode_opf },
{ "ofg", kCode_ofg },
@@ -3062,8 +3064,9 @@ static const struct {
int TuckerEngine::readTableInstructionCode(int *index) {
bool match = false;
+ int nameLen = 0;
for (int i = 0; _instructions[i].name; ++i) {
- const int nameLen = strlen(_instructions[i].name);
+ nameLen = strlen(_instructions[i].name);
if (_instructions[i].name[1] == '0') {
if (_instructions[i].name[0] == _tableInstructionsPtr[0] && _instructions[i].name[2] == _tableInstructionsPtr[2]) {
const char digit = _tableInstructionsPtr[1];
@@ -3083,6 +3086,7 @@ int TuckerEngine::readTableInstructionCode(int *index) {
}
}
warning("Unhandled instruction '%c%c%c'", _tableInstructionsPtr[0], _tableInstructionsPtr[1], _tableInstructionsPtr[2]);
+ _tableInstructionsPtr += nameLen + 1;
return kCode_invalid;
}
@@ -3232,6 +3236,9 @@ int TuckerEngine::executeTableInstruction() {
case kCode_loc:
_nextLocationNum = readTableInstructionParam(2);
return 1;
+ case kCode_mof:
+ // TODO: Unknown opcode in Spanish version. Identify if this has any function.
+ return 0;
case kCode_opt:
_conversationOptionsCount = readTableInstructionParam(2);
for (i = 0; i < _conversationOptionsCount; ++i) {
diff --git a/engines/wintermute/ad/ad_actor.cpp b/engines/wintermute/ad/ad_actor.cpp
index e4c18d6287..94df17c543 100644
--- a/engines/wintermute/ad/ad_actor.cpp
+++ b/engines/wintermute/ad/ad_actor.cpp
@@ -1457,4 +1457,4 @@ bool AdActor::playAnim(const char *filename) {
return AdTalkHolder::playAnim(filename);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_actor.h b/engines/wintermute/ad/ad_actor.h
index 3630c6665b..582b41b8b0 100644
--- a/engines/wintermute/ad/ad_actor.h
+++ b/engines/wintermute/ad/ad_actor.h
@@ -103,6 +103,6 @@ private:
int32 _pFCount;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_entity.cpp b/engines/wintermute/ad/ad_entity.cpp
index c43f74b620..388accf34f 100644
--- a/engines/wintermute/ad/ad_entity.cpp
+++ b/engines/wintermute/ad/ad_entity.cpp
@@ -1134,4 +1134,4 @@ bool AdEntity::setSprite(const char *filename) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_entity.h b/engines/wintermute/ad/ad_entity.h
index c23b37366d..bdbd271667 100644
--- a/engines/wintermute/ad/ad_entity.h
+++ b/engines/wintermute/ad/ad_entity.h
@@ -68,6 +68,6 @@ private:
TEntityType _subtype;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp
index ead68f7729..d5799e851b 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -2282,4 +2282,4 @@ bool AdGame::onScriptShutdown(ScScript *script) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_game.h b/engines/wintermute/ad/ad_game.h
index 2032a1723f..cb5147501d 100644
--- a/engines/wintermute/ad/ad_game.h
+++ b/engines/wintermute/ad/ad_game.h
@@ -158,6 +158,6 @@ private:
AdInventoryBox *_inventoryBox;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_inventory.cpp b/engines/wintermute/ad/ad_inventory.cpp
index e9b6e56f16..544d8310d0 100644
--- a/engines/wintermute/ad/ad_inventory.cpp
+++ b/engines/wintermute/ad/ad_inventory.cpp
@@ -133,4 +133,4 @@ bool AdInventory::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_inventory.h b/engines/wintermute/ad/ad_inventory.h
index 999200b465..9de831b2a0 100644
--- a/engines/wintermute/ad/ad_inventory.h
+++ b/engines/wintermute/ad/ad_inventory.h
@@ -47,6 +47,6 @@ public:
int32 _scrollOffset;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_inventory_box.cpp b/engines/wintermute/ad/ad_inventory_box.cpp
index 110359917b..d703de1714 100644
--- a/engines/wintermute/ad/ad_inventory_box.cpp
+++ b/engines/wintermute/ad/ad_inventory_box.cpp
@@ -386,4 +386,4 @@ bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_inventory_box.h b/engines/wintermute/ad/ad_inventory_box.h
index 9792b1ea66..f65bd8d8f0 100644
--- a/engines/wintermute/ad/ad_inventory_box.h
+++ b/engines/wintermute/ad/ad_inventory_box.h
@@ -60,6 +60,6 @@ private:
int32 _itemWidth;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_item.cpp b/engines/wintermute/ad/ad_item.cpp
index 1a46eb783b..7d05461169 100644
--- a/engines/wintermute/ad/ad_item.cpp
+++ b/engines/wintermute/ad/ad_item.cpp
@@ -810,4 +810,4 @@ bool AdItem::getExtendedFlag(const char *flagName) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_item.h b/engines/wintermute/ad/ad_item.h
index b8351448a7..dd7039db43 100644
--- a/engines/wintermute/ad/ad_item.h
+++ b/engines/wintermute/ad/ad_item.h
@@ -64,6 +64,6 @@ private:
char *_amountString;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_layer.cpp b/engines/wintermute/ad/ad_layer.cpp
index 7bf79e4ae5..c833b59163 100644
--- a/engines/wintermute/ad/ad_layer.cpp
+++ b/engines/wintermute/ad/ad_layer.cpp
@@ -561,4 +561,4 @@ bool AdLayer::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_layer.h b/engines/wintermute/ad/ad_layer.h
index 8fe4d4f91e..b260b919fd 100644
--- a/engines/wintermute/ad/ad_layer.h
+++ b/engines/wintermute/ad/ad_layer.h
@@ -53,6 +53,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_node_state.cpp b/engines/wintermute/ad/ad_node_state.cpp
index d52201a08d..876c5a8bb4 100644
--- a/engines/wintermute/ad/ad_node_state.cpp
+++ b/engines/wintermute/ad/ad_node_state.cpp
@@ -192,4 +192,4 @@ bool AdNodeState::transferEntity(AdEntity *entity, bool includingSprites, bool s
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_node_state.h b/engines/wintermute/ad/ad_node_state.h
index e2050815a7..4b5b46ee60 100644
--- a/engines/wintermute/ad/ad_node_state.h
+++ b/engines/wintermute/ad/ad_node_state.h
@@ -55,6 +55,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_object.cpp b/engines/wintermute/ad/ad_object.cpp
index 741d6e6fc6..0d5011f92d 100644
--- a/engines/wintermute/ad/ad_object.cpp
+++ b/engines/wintermute/ad/ad_object.cpp
@@ -1299,4 +1299,4 @@ bool AdObject::updatePartEmitter() {
return _partEmitter->update();
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_object.h b/engines/wintermute/ad/ad_object.h
index c6573315da..9e30f69855 100644
--- a/engines/wintermute/ad/ad_object.h
+++ b/engines/wintermute/ad/ad_object.h
@@ -123,6 +123,6 @@ private:
AdInventory *_inventory;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_path.cpp b/engines/wintermute/ad/ad_path.cpp
index 5b36ed6471..91a24cbf7d 100644
--- a/engines/wintermute/ad/ad_path.cpp
+++ b/engines/wintermute/ad/ad_path.cpp
@@ -117,4 +117,4 @@ bool AdPath::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_path.h b/engines/wintermute/ad/ad_path.h
index 3f38355b94..9de0bcad2c 100644
--- a/engines/wintermute/ad/ad_path.h
+++ b/engines/wintermute/ad/ad_path.h
@@ -51,6 +51,6 @@ public:
bool _ready;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_path_point.cpp b/engines/wintermute/ad/ad_path_point.cpp
index be4b487466..d5108ad8c1 100644
--- a/engines/wintermute/ad/ad_path_point.cpp
+++ b/engines/wintermute/ad/ad_path_point.cpp
@@ -72,4 +72,4 @@ bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_path_point.h b/engines/wintermute/ad/ad_path_point.h
index 04648b1733..5e6b8c61ea 100644
--- a/engines/wintermute/ad/ad_path_point.h
+++ b/engines/wintermute/ad/ad_path_point.h
@@ -45,6 +45,6 @@ public:
int32 _distance;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_region.cpp b/engines/wintermute/ad/ad_region.cpp
index acd5f13397..bc9ac903c6 100644
--- a/engines/wintermute/ad/ad_region.cpp
+++ b/engines/wintermute/ad/ad_region.cpp
@@ -404,9 +404,9 @@ bool AdRegion::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha));
persistMgr->transfer(TMEMBER(_blocked));
persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_zoom));
+ persistMgr->transferFloat(TMEMBER(_zoom));
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_region.h b/engines/wintermute/ad/ad_region.h
index bc9eab085e..637c742c9c 100644
--- a/engines/wintermute/ad/ad_region.h
+++ b/engines/wintermute/ad/ad_region.h
@@ -59,6 +59,6 @@ private:
bool _decoration;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_response.cpp b/engines/wintermute/ad/ad_response.cpp
index 4483bbc667..fa05224b06 100644
--- a/engines/wintermute/ad/ad_response.cpp
+++ b/engines/wintermute/ad/ad_response.cpp
@@ -166,7 +166,7 @@ BaseFont *AdResponse::getFont() const {
int32 AdResponse::getID() const {
return _iD;
}
-
+
const char *AdResponse::getText() const {
return _text;
}
@@ -175,4 +175,4 @@ const char *AdResponse::getTextOrig() const {
return _textOrig;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response.h b/engines/wintermute/ad/ad_response.h
index 57cd302e9d..00ebafbdb0 100644
--- a/engines/wintermute/ad/ad_response.h
+++ b/engines/wintermute/ad/ad_response.h
@@ -68,6 +68,6 @@ private:
char *_textOrig;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_response_box.cpp b/engines/wintermute/ad/ad_response_box.cpp
index a589bf3a30..9d7c17ac74 100644
--- a/engines/wintermute/ad/ad_response_box.cpp
+++ b/engines/wintermute/ad/ad_response_box.cpp
@@ -737,4 +737,4 @@ bool AdResponseBox::getObjects(BaseArray<UIObject *> &objects, bool interactiveO
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response_box.h b/engines/wintermute/ad/ad_response_box.h
index cb57b98924..7598e8b569 100644
--- a/engines/wintermute/ad/ad_response_box.h
+++ b/engines/wintermute/ad/ad_response_box.h
@@ -94,6 +94,6 @@ private:
UIWindow *_window;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_response_context.cpp b/engines/wintermute/ad/ad_response_context.cpp
index 663ef49a24..0b58f5ba0c 100644
--- a/engines/wintermute/ad/ad_response_context.cpp
+++ b/engines/wintermute/ad/ad_response_context.cpp
@@ -68,4 +68,4 @@ void AdResponseContext::setContext(const char *context) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_response_context.h b/engines/wintermute/ad/ad_response_context.h
index dd0008a728..bc30b4a1c9 100644
--- a/engines/wintermute/ad/ad_response_context.h
+++ b/engines/wintermute/ad/ad_response_context.h
@@ -47,6 +47,6 @@ private:
char *_context;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_rot_level.cpp b/engines/wintermute/ad/ad_rot_level.cpp
index 4d7f27aec7..d925b0d57a 100644
--- a/engines/wintermute/ad/ad_rot_level.cpp
+++ b/engines/wintermute/ad/ad_rot_level.cpp
@@ -153,9 +153,9 @@ bool AdRotLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_rotation));
+ persistMgr->transferFloat(TMEMBER(_rotation));
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_rot_level.h b/engines/wintermute/ad/ad_rot_level.h
index 3466e46ba5..fe2d1691cd 100644
--- a/engines/wintermute/ad/ad_rot_level.h
+++ b/engines/wintermute/ad/ad_rot_level.h
@@ -45,6 +45,6 @@ public:
bool loadBuffer(byte *buffer, bool complete = true);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_scale_level.cpp b/engines/wintermute/ad/ad_scale_level.cpp
index e80f38bd0f..59e6d57787 100644
--- a/engines/wintermute/ad/ad_scale_level.cpp
+++ b/engines/wintermute/ad/ad_scale_level.cpp
@@ -154,9 +154,9 @@ bool AdScaleLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scale_level.h b/engines/wintermute/ad/ad_scale_level.h
index 516f507a5a..b2dd7aa91f 100644
--- a/engines/wintermute/ad/ad_scale_level.h
+++ b/engines/wintermute/ad/ad_scale_level.h
@@ -47,6 +47,6 @@ private:
float _scale;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_scene.cpp b/engines/wintermute/ad/ad_scene.cpp
index 4d0068fad1..668b39853b 100644
--- a/engines/wintermute/ad/ad_scene.cpp
+++ b/engines/wintermute/ad/ad_scene.cpp
@@ -2989,4 +2989,4 @@ bool AdScene::getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects,
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene.h b/engines/wintermute/ad/ad_scene.h
index cd144b77ef..5beb10e546 100644
--- a/engines/wintermute/ad/ad_scene.h
+++ b/engines/wintermute/ad/ad_scene.h
@@ -176,6 +176,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_scene_node.cpp b/engines/wintermute/ad/ad_scene_node.cpp
index e9b80b3cc8..8548da91db 100644
--- a/engines/wintermute/ad/ad_scene_node.cpp
+++ b/engines/wintermute/ad/ad_scene_node.cpp
@@ -79,4 +79,4 @@ bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene_state.cpp b/engines/wintermute/ad/ad_scene_state.cpp
index 8e022ab115..58cb5f514a 100644
--- a/engines/wintermute/ad/ad_scene_state.cpp
+++ b/engines/wintermute/ad/ad_scene_state.cpp
@@ -95,4 +95,4 @@ AdNodeState *AdSceneState::getNodeState(const char *name, bool saving) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scene_state.h b/engines/wintermute/ad/ad_scene_state.h
index 600aa4b581..067c737b2e 100644
--- a/engines/wintermute/ad/ad_scene_state.h
+++ b/engines/wintermute/ad/ad_scene_state.h
@@ -48,6 +48,6 @@ private:
BaseArray<AdNodeState *> _nodeStates;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_sentence.cpp b/engines/wintermute/ad/ad_sentence.cpp
index 70a57a624d..d5baa8291f 100644
--- a/engines/wintermute/ad/ad_sentence.cpp
+++ b/engines/wintermute/ad/ad_sentence.cpp
@@ -358,4 +358,4 @@ bool AdSentence::canSkip() {
return (_gameRef->getTimer()->getTime() - _startTime) > 300;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_sentence.h b/engines/wintermute/ad/ad_sentence.h
index 6f255578f7..c491ad99a2 100644
--- a/engines/wintermute/ad/ad_sentence.h
+++ b/engines/wintermute/ad/ad_sentence.h
@@ -80,6 +80,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_sprite_set.cpp b/engines/wintermute/ad/ad_sprite_set.cpp
index 6c802c4863..9eb3bd0686 100644
--- a/engines/wintermute/ad/ad_sprite_set.cpp
+++ b/engines/wintermute/ad/ad_sprite_set.cpp
@@ -353,4 +353,4 @@ bool AdSpriteSet::containsSprite(BaseSprite *sprite) {
return false;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_sprite_set.h b/engines/wintermute/ad/ad_sprite_set.h
index 61043aa3d6..ef5ef3a94f 100644
--- a/engines/wintermute/ad/ad_sprite_set.h
+++ b/engines/wintermute/ad/ad_sprite_set.h
@@ -48,6 +48,6 @@ public:
BaseSprite *_sprites[NUM_DIRECTIONS];
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_talk_def.cpp b/engines/wintermute/ad/ad_talk_def.cpp
index bf72b2916b..f10a0e2fb9 100644
--- a/engines/wintermute/ad/ad_talk_def.cpp
+++ b/engines/wintermute/ad/ad_talk_def.cpp
@@ -282,4 +282,4 @@ BaseSprite *AdTalkDef::getDefaultSprite(TDirection dir) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_def.h b/engines/wintermute/ad/ad_talk_def.h
index 2375360d89..726eefbe4c 100644
--- a/engines/wintermute/ad/ad_talk_def.h
+++ b/engines/wintermute/ad/ad_talk_def.h
@@ -53,6 +53,6 @@ public:
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_talk_holder.cpp b/engines/wintermute/ad/ad_talk_holder.cpp
index 33deab7805..6041105b93 100644
--- a/engines/wintermute/ad/ad_talk_holder.cpp
+++ b/engines/wintermute/ad/ad_talk_holder.cpp
@@ -399,4 +399,4 @@ bool AdTalkHolder::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_holder.h b/engines/wintermute/ad/ad_talk_holder.h
index 501acbc885..ab48c3aaf4 100644
--- a/engines/wintermute/ad/ad_talk_holder.h
+++ b/engines/wintermute/ad/ad_talk_holder.h
@@ -52,6 +52,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_talk_node.cpp b/engines/wintermute/ad/ad_talk_node.cpp
index f03c24ea94..ce86dccd8e 100644
--- a/engines/wintermute/ad/ad_talk_node.cpp
+++ b/engines/wintermute/ad/ad_talk_node.cpp
@@ -292,4 +292,4 @@ BaseSprite *AdTalkNode::getSprite(TDirection dir) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_talk_node.h b/engines/wintermute/ad/ad_talk_node.h
index 012fa2133e..01dfb6b4ff 100644
--- a/engines/wintermute/ad/ad_talk_node.h
+++ b/engines/wintermute/ad/ad_talk_node.h
@@ -58,6 +58,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_types.h b/engines/wintermute/ad/ad_types.h
index ae5882f4ee..dc1a54b91d 100644
--- a/engines/wintermute/ad/ad_types.h
+++ b/engines/wintermute/ad/ad_types.h
@@ -102,6 +102,6 @@ typedef enum {
GEOM_GENERIC
} TGeomNodeType;
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ad/ad_waypoint_group.cpp b/engines/wintermute/ad/ad_waypoint_group.cpp
index 96dece34b8..cc7982cb9d 100644
--- a/engines/wintermute/ad/ad_waypoint_group.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group.cpp
@@ -196,7 +196,7 @@ bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_active));
persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
persistMgr->transfer(TMEMBER(_lastMimicX));
persistMgr->transfer(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
@@ -267,4 +267,4 @@ bool AdWaypointGroup::mimic(AdWaypointGroup *wpt, float scale, int argX, int arg
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_waypoint_group.h b/engines/wintermute/ad/ad_waypoint_group.h
index 79b28e0d22..af97a21290 100644
--- a/engines/wintermute/ad/ad_waypoint_group.h
+++ b/engines/wintermute/ad/ad_waypoint_group.h
@@ -56,6 +56,6 @@ private:
int32 _lastMimicY;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base.cpp b/engines/wintermute/base/base.cpp
index d01972b82f..a64770c577 100644
--- a/engines/wintermute/base/base.cpp
+++ b/engines/wintermute/base/base.cpp
@@ -183,4 +183,4 @@ bool BaseClass::saveAsText(BaseDynamicBuffer *buffer, int indent) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base.h b/engines/wintermute/base/base.h
index 7f2796c6e0..48ebe49a97 100644
--- a/engines/wintermute/base/base.h
+++ b/engines/wintermute/base/base.h
@@ -57,6 +57,6 @@ protected:
Common::HashMap<Common::String, Common::String>::iterator _editorPropsIter;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_active_rect.cpp b/engines/wintermute/base/base_active_rect.cpp
index 7a91854c57..abeaa18d54 100644
--- a/engines/wintermute/base/base_active_rect.cpp
+++ b/engines/wintermute/base/base_active_rect.cpp
@@ -109,4 +109,4 @@ void BaseActiveRect::clipRect() {
BasePlatform::intersectRect(&_rect, &_rect, &rc);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_active_rect.h b/engines/wintermute/base/base_active_rect.h
index 982a0902d0..a3c0746618 100644
--- a/engines/wintermute/base/base_active_rect.h
+++ b/engines/wintermute/base/base_active_rect.h
@@ -55,6 +55,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_dynamic_buffer.cpp b/engines/wintermute/base/base_dynamic_buffer.cpp
index f684420b1e..5334ae46c4 100644
--- a/engines/wintermute/base/base_dynamic_buffer.cpp
+++ b/engines/wintermute/base/base_dynamic_buffer.cpp
@@ -201,4 +201,4 @@ void BaseDynamicBuffer::putTextForm(const char *format, va_list argptr) {
putBytes((byte *)buff, strlen(buff));
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_dynamic_buffer.h b/engines/wintermute/base/base_dynamic_buffer.h
index ad78ebad00..2804d78895 100644
--- a/engines/wintermute/base/base_dynamic_buffer.h
+++ b/engines/wintermute/base/base_dynamic_buffer.h
@@ -60,6 +60,6 @@ private:
void putTextForm(const char *format, va_list argptr);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_engine.cpp b/engines/wintermute/base/base_engine.cpp
index d4b17a0a64..acb12bbe5f 100644
--- a/engines/wintermute/base/base_engine.cpp
+++ b/engines/wintermute/base/base_engine.cpp
@@ -44,10 +44,11 @@ BaseEngine::BaseEngine() {
_classReg = nullptr;
_rnd = nullptr;
_gameId = "";
+ _language = Common::UNK_LANG;
}
-void BaseEngine::init(Common::Language lang) {
- _fileManager = new BaseFileManager(lang);
+void BaseEngine::init() {
+ _fileManager = new BaseFileManager(_language);
// Don't forget to register your random source
_rnd = new Common::RandomSource("Wintermute");
_classReg = new SystemClassRegistry();
@@ -60,9 +61,11 @@ BaseEngine::~BaseEngine() {
delete _classReg;
}
-void BaseEngine::createInstance(const Common::String &gameid, Common::Language lang) {
- instance()._gameId = gameid;
- instance().init(lang);
+void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang) {
+ instance()._targetName = targetName;
+ instance()._gameId = gameId;
+ instance()._language = lang;
+ instance().init();
}
void BaseEngine::LOG(bool res, const char *fmt, ...) {
@@ -122,4 +125,4 @@ const Timer *BaseEngine::getLiveTimer() {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_engine.h b/engines/wintermute/base/base_engine.h
index d972e6ebbc..a5eafd3597 100644
--- a/engines/wintermute/base/base_engine.h
+++ b/engines/wintermute/base/base_engine.h
@@ -44,17 +44,19 @@ class BaseRenderer;
class SystemClassRegistry;
class Timer;
class BaseEngine : public Common::Singleton<Wintermute::BaseEngine> {
- void init(Common::Language lang);
+ void init();
BaseFileManager *_fileManager;
Common::String _gameId;
+ Common::String _targetName;
BaseGame *_gameRef;
// We need random numbers
Common::RandomSource *_rnd;
SystemClassRegistry *_classReg;
+ Common::Language _language;
public:
BaseEngine();
~BaseEngine();
- static void createInstance(const Common::String &gameid, Common::Language lang);
+ static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang);
void setGameRef(BaseGame *gameRef) { _gameRef = gameRef; }
Common::RandomSource *getRandomSource() { return _rnd; }
@@ -68,9 +70,11 @@ public:
static const Timer *getTimer();
static const Timer *getLiveTimer();
static void LOG(bool res, const char *fmt, ...);
- const char *getGameId() { return _gameId.c_str(); }
+ const char *getGameTargetName() const { return _targetName.c_str(); }
+ Common::String getGameId() const { return _gameId; }
+ Common::Language getLanguage() const { return _language; }
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_fader.cpp b/engines/wintermute/base/base_fader.cpp
index 0d17b07a9d..7978230964 100644
--- a/engines/wintermute/base/base_fader.cpp
+++ b/engines/wintermute/base/base_fader.cpp
@@ -193,4 +193,4 @@ bool BaseFader::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_fader.h b/engines/wintermute/base/base_fader.h
index 845ce2f244..087b19bc44 100644
--- a/engines/wintermute/base/base_fader.h
+++ b/engines/wintermute/base/base_fader.h
@@ -58,6 +58,6 @@ private:
uint32 _startTime;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp
index 7d59b03684..bea7e53445 100644
--- a/engines/wintermute/base/base_file_manager.cpp
+++ b/engines/wintermute/base/base_file_manager.cpp
@@ -269,7 +269,7 @@ Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &f
bool BaseFileManager::hasFile(const Common::String &filename) {
if (scumm_strnicmp(filename.c_str(), "savegame:", 9) == 0) {
- BasePersistenceManager pm(BaseEngine::instance().getGameId());
+ BasePersistenceManager pm(BaseEngine::instance().getGameTargetName());
if (filename.size() <= 9) {
return false;
}
@@ -360,4 +360,4 @@ BaseFileManager *BaseFileManager::getEngineInstance() {
return nullptr;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_file_manager.h b/engines/wintermute/base/base_file_manager.h
index 7ed3a6c7cb..8c2876f681 100644
--- a/engines/wintermute/base/base_file_manager.h
+++ b/engines/wintermute/base/base_file_manager.h
@@ -74,6 +74,6 @@ private:
// the detector too, without launching the entire engine:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp
index 9fb5770f79..eaad024120 100644
--- a/engines/wintermute/base/base_frame.cpp
+++ b/engines/wintermute/base/base_frame.cpp
@@ -764,4 +764,4 @@ const char *BaseFrame::scToString() {
return "[frame]";
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_frame.h b/engines/wintermute/base/base_frame.h
index 954851c77f..bf1e40daa1 100644
--- a/engines/wintermute/base/base_frame.h
+++ b/engines/wintermute/base/base_frame.h
@@ -70,6 +70,6 @@ private:
BaseSound *_sound;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index 4d8e79b5c2..b2c05d271d 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -81,7 +81,7 @@ IMPLEMENT_PERSISTENT(BaseGame, true)
//////////////////////////////////////////////////////////////////////
-BaseGame::BaseGame(const Common::String &gameId) : BaseObject(this), _gameId(gameId), _timerNormal(), _timerLive() {
+BaseGame::BaseGame(const Common::String &targetName) : BaseObject(this), _targetName(targetName), _timerNormal(), _timerLive() {
_shuttingDown = false;
_state = GAME_RUNNING;
@@ -212,7 +212,7 @@ BaseGame::BaseGame(const Common::String &gameId) : BaseObject(this), _gameId(gam
#else*/
_touchInterface = false;
_constrainedMemory = false;
-
+
_settings = new BaseGameSettings(this);
//#endif
@@ -1276,11 +1276,7 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
stack->correctParams(2);
const char *key = stack->pop()->getString();
const char *initVal = stack->pop()->getString();
- Common::String privKey = "wme_" + StringUtil::encodeSetting(key);
- Common::String result = initVal;
- if (ConfMan.hasKey(privKey)) {
- result = StringUtil::decodeSetting(ConfMan.get(key));
- }
+ Common::String result = readRegistryString(key, initVal);
stack->pushString(result.c_str());
return STATUS_OK;
}
@@ -3072,8 +3068,8 @@ bool BaseGame::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_offsetX));
persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_offsetPercentX));
- persistMgr->transfer(TMEMBER(_offsetPercentY));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentX));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentY));
persistMgr->transfer(TMEMBER(_origInteractive));
persistMgr->transfer(TMEMBER_INT(_origState));
@@ -3734,7 +3730,7 @@ bool BaseGame::onWindowClose() {
bool BaseGame::displayDebugInfo() {
const uint32 strLength = 100;
char str[strLength];
-
+
if (_debugShowFPS) {
sprintf(str, "FPS: %d", _gameRef->_fps);
_systemFont->drawText((byte *)str, 0, 0, 100, TAL_LEFT);
@@ -3902,4 +3898,26 @@ char *BaseGame::getKeyFromStringTable(const char *str) const {
return _settings->getKeyFromStringTable(str);
}
-} // end of namespace Wintermute
+Common::String BaseGame::readRegistryString(const Common::String &key, const Common::String &initValue) const {
+ // Game specific hacks:
+ Common::String result = initValue;
+ // James Peris:
+ if (BaseEngine::instance().getGameId() == "jamesperis" && key == "Language") {
+ Common::Language language = BaseEngine::instance().getLanguage();
+ if (language == Common::EN_ANY) {
+ result = "english";
+ } else if (language == Common::ES_ESP) {
+ result = "spanish";
+ } else {
+ error("Invalid language set for James Peris");
+ }
+ } else { // Just fallback to using ConfMan for now
+ Common::String privKey = "wme_" + StringUtil::encodeSetting(key);
+ if (ConfMan.hasKey(privKey)) {
+ result = StringUtil::decodeSetting(ConfMan.get(key));
+ }
+ }
+ return result;
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h
index d51255d013..d295bb6b1a 100644
--- a/engines/wintermute/base/base_game.h
+++ b/engines/wintermute/base/base_game.h
@@ -137,7 +137,7 @@ public:
bool initialize2();
bool initialize3();
BaseTransitionMgr *_transMgr;
-
+
// String Table
void expandStringByStringTable(char **str) const;
char *getKeyFromStringTable(const char *str) const;
@@ -150,7 +150,7 @@ public:
BaseScriptable *_mathClass;
BaseSurfaceStorage *_surfaceStorage;
BaseFontStorage *_fontStorage;
- BaseGame(const Common::String &gameId);
+ BaseGame(const Common::String &targetName);
virtual ~BaseGame();
bool _debugDebugMode;
@@ -173,8 +173,8 @@ public:
// compatibility bits
bool _compatKillMethodThreads;
- const char* getGameId() const { return _gameId.c_str(); }
- void setGameId(const Common::String& gameId) { _gameId = gameId; }
+ const char* getGameTargetName() const { return _targetName.c_str(); }
+ void setGameTargetName(const Common::String& targetName) { _targetName = targetName; }
uint32 _surfaceGCCycleTime;
bool _smartCache; // RO
bool _subtitles; // RO
@@ -275,7 +275,7 @@ private:
bool _mouseRightDown;
bool _mouseMidlleDown;
-
+
BaseGameSettings *_settings;
int32 _soundBufferSizeSec;
@@ -295,7 +295,7 @@ private:
uint32 _lastTime;
uint32 _fpsTime;
uint32 _framesRendered;
- Common::String _gameId;
+ Common::String _targetName;
void setEngineLogCallback(ENGINE_LOG_CALLBACK callback = nullptr, void *data = nullptr);
ENGINE_LOG_CALLBACK _engineLogCallback;
@@ -343,6 +343,8 @@ private:
bool isDoubleClick(int32 buttonIndex);
uint32 _usedMem;
+// TODO: This should be expanded into a proper class eventually:
+ Common::String readRegistryString(const Common::String &key, const Common::String &initValue) const;
protected:
@@ -356,6 +358,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_game_music.cpp b/engines/wintermute/base/base_game_music.cpp
index ac23801e4c..c50969df76 100644
--- a/engines/wintermute/base/base_game_music.cpp
+++ b/engines/wintermute/base/base_game_music.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -65,10 +65,10 @@ bool BaseGameMusic::playMusic(int channel, const char *filename, bool looping, u
BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS);
return STATUS_FAILED;
}
-
+
delete _music[channel];
_music[channel] = nullptr;
-
+
_music[channel] = new BaseSound(_gameRef);
if (_music[channel] && DID_SUCCEED(_music[channel]->setSound(filename, Audio::Mixer::kMusicSoundType, true))) {
if (_musicStartTime[channel]) {
@@ -93,7 +93,7 @@ bool BaseGameMusic::stopMusic(int channel) {
BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS);
return STATUS_FAILED;
}
-
+
if (_music[channel]) {
_music[channel]->stop();
delete _music[channel];
@@ -111,7 +111,7 @@ bool BaseGameMusic::pauseMusic(int channel) {
BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS);
return STATUS_FAILED;
}
-
+
if (_music[channel]) {
return _music[channel]->pause();
} else {
@@ -126,7 +126,7 @@ bool BaseGameMusic::resumeMusic(int channel) {
BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS);
return STATUS_FAILED;
}
-
+
if (_music[channel]) {
return _music[channel]->resume();
} else {
@@ -141,7 +141,7 @@ bool BaseGameMusic::setMusicStartTime(int channel, uint32 time) {
BaseEngine::LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", channel, NUM_MUSIC_CHANNELS);
return STATUS_FAILED;
}
-
+
_musicStartTime[channel] = time;
if (_music[channel] && _music[channel]->isPlaying()) {
return _music[channel]->setPositionTime(time);
@@ -153,14 +153,14 @@ bool BaseGameMusic::setMusicStartTime(int channel, uint32 time) {
//////////////////////////////////////////////////////////////////////////
bool BaseGameMusic::updateMusicCrossfade() {
/* byte globMusicVol = _soundMgr->getVolumePercent(SOUND_MUSIC); */
-
+
if (!_musicCrossfadeRunning) {
return STATUS_OK;
}
if (_gameRef->_state == GAME_FROZEN) {
return STATUS_OK;
}
-
+
if (_musicCrossfadeChannel1 < 0 || _musicCrossfadeChannel1 >= NUM_MUSIC_CHANNELS || !_music[_musicCrossfadeChannel1]) {
_musicCrossfadeRunning = false;
return STATUS_OK;
@@ -169,34 +169,34 @@ bool BaseGameMusic::updateMusicCrossfade() {
_musicCrossfadeRunning = false;
return STATUS_OK;
}
-
+
if (!_music[_musicCrossfadeChannel1]->isPlaying()) {
_music[_musicCrossfadeChannel1]->play();
}
if (!_music[_musicCrossfadeChannel2]->isPlaying()) {
_music[_musicCrossfadeChannel2]->play();
}
-
+
uint32 currentTime = _gameRef->getLiveTimer()->getTime() - _musicCrossfadeStartTime;
-
+
if (currentTime >= _musicCrossfadeLength) {
_musicCrossfadeRunning = false;
//_music[_musicCrossfadeChannel2]->setVolume(GlobMusicVol);
_music[_musicCrossfadeChannel2]->setVolumePercent(100);
-
+
_music[_musicCrossfadeChannel1]->stop();
//_music[_musicCrossfadeChannel1]->setVolume(GlobMusicVol);
_music[_musicCrossfadeChannel1]->setVolumePercent(100);
-
-
+
+
if (_musicCrossfadeSwap) {
// swap channels
BaseSound *dummy = _music[_musicCrossfadeChannel1];
int dummyInt = _musicStartTime[_musicCrossfadeChannel1];
-
+
_music[_musicCrossfadeChannel1] = _music[_musicCrossfadeChannel2];
_musicStartTime[_musicCrossfadeChannel1] = _musicStartTime[_musicCrossfadeChannel2];
-
+
_music[_musicCrossfadeChannel2] = dummy;
_musicStartTime[_musicCrossfadeChannel2] = dummyInt;
}
@@ -205,10 +205,10 @@ bool BaseGameMusic::updateMusicCrossfade() {
//_music[_musicCrossfadeChannel2]->setVolume((float)CurrentTime / (float)_musicCrossfadeLength * GlobMusicVol);
_music[_musicCrossfadeChannel1]->setVolumePercent((int)(100.0f - (float)currentTime / (float)_musicCrossfadeLength * 100.0f));
_music[_musicCrossfadeChannel2]->setVolumePercent((int)((float)currentTime / (float)_musicCrossfadeLength * 100.0f));
-
+
//_gameRef->QuickMessageForm("%d %d", _music[_musicCrossfadeChannel1]->GetVolume(), _music[_musicCrossfadeChannel2]->GetVolume());
}
-
+
return STATUS_OK;
}
@@ -242,15 +242,15 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(4);
channel = stack->pop()->getInt();
}
-
+
const char *filename = stack->pop()->getString();
ScValue *valLooping = stack->pop();
bool looping = valLooping->isNULL() ? true : valLooping->getBool();
-
+
ScValue *valLoopStart = stack->pop();
uint32 loopStart = (uint32)(valLoopStart->isNULL() ? 0 : valLoopStart->getInt());
-
-
+
+
if (DID_FAIL(playMusic(channel, filename, looping, loopStart))) {
stack->pushBool(false);
} else {
@@ -258,20 +258,20 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// StopMusic / StopMusicChannel
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "StopMusic") == 0 || strcmp(name, "StopMusicChannel") == 0) {
int channel = 0;
-
+
if (strcmp(name, "StopMusic") == 0) {
stack->correctParams(0);
} else {
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (DID_FAIL(stopMusic(channel))) {
stack->pushBool(false);
} else {
@@ -279,20 +279,20 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// PauseMusic / PauseMusicChannel
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PauseMusic") == 0 || strcmp(name, "PauseMusicChannel") == 0) {
int channel = 0;
-
+
if (strcmp(name, "PauseMusic") == 0) {
stack->correctParams(0);
} else {
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (DID_FAIL(pauseMusic(channel))) {
stack->pushBool(false);
} else {
@@ -300,7 +300,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// ResumeMusic / ResumeMusicChannel
//////////////////////////////////////////////////////////////////////////
@@ -312,7 +312,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (DID_FAIL(resumeMusic(channel))) {
stack->pushBool(false);
} else {
@@ -320,7 +320,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// GetMusic / GetMusicChannel
//////////////////////////////////////////////////////////////////////////
@@ -343,7 +343,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// SetMusicPosition / SetMusicChannelPosition
//////////////////////////////////////////////////////////////////////////
@@ -355,18 +355,18 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(2);
channel = stack->pop()->getInt();
}
-
+
uint32 time = stack->pop()->getInt();
-
+
if (DID_FAIL(setMusicStartTime(channel, time))) {
stack->pushBool(false);
} else {
stack->pushBool(true);
}
-
+
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// GetMusicPosition / GetMusicChannelPosition
//////////////////////////////////////////////////////////////////////////
@@ -378,7 +378,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) {
stack->pushInt(0);
} else {
@@ -386,7 +386,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// IsMusicPlaying / IsMusicChannelPlaying
//////////////////////////////////////////////////////////////////////////
@@ -398,7 +398,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) {
stack->pushBool(false);
} else {
@@ -406,7 +406,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// SetMusicVolume / SetMusicChannelVolume
//////////////////////////////////////////////////////////////////////////
@@ -418,7 +418,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(2);
channel = stack->pop()->getInt();
}
-
+
int volume = stack->pop()->getInt();
if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) {
stack->pushBool(false);
@@ -431,7 +431,7 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// GetMusicVolume / GetMusicChannelVolume
//////////////////////////////////////////////////////////////////////////
@@ -443,16 +443,16 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
stack->correctParams(1);
channel = stack->pop()->getInt();
}
-
+
if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) {
stack->pushInt(0);
} else {
stack->pushInt(_music[channel]->getVolumePercent());
}
-
+
return STATUS_OK;
}
-
+
//////////////////////////////////////////////////////////////////////////
// MusicCrossfade
//////////////////////////////////////////////////////////////////////////
@@ -462,34 +462,34 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
int channel2 = stack->pop()->getInt(0);
uint32 fadeLength = (uint32)stack->pop()->getInt(0);
bool swap = stack->pop()->getBool(true);
-
+
if (_musicCrossfadeRunning) {
script->runtimeError("Game.MusicCrossfade: Music crossfade is already in progress.");
stack->pushBool(false);
return STATUS_OK;
}
-
+
_musicCrossfadeStartTime = _gameRef->getLiveTimer()->getTime();
_musicCrossfadeChannel1 = channel1;
_musicCrossfadeChannel2 = channel2;
_musicCrossfadeLength = fadeLength;
_musicCrossfadeSwap = swap;
-
+
_musicCrossfadeRunning = true;
-
+
stack->pushBool(true);
return STATUS_OK;
- }
+ }
//////////////////////////////////////////////////////////////////////////
// GetSoundLength
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetSoundLength") == 0) {
stack->correctParams(1);
-
+
int length = 0;
const char *filename = stack->pop()->getString();
-
+
BaseSound *sound = new BaseSound(_gameRef);
if (sound && DID_SUCCEED(sound->setSound(filename, Audio::Mixer::kMusicSoundType, true))) {
length = sound->getLength();
@@ -503,4 +503,4 @@ bool BaseGameMusic::scCallMethod(ScScript *script, ScStack *stack, ScStack *this
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_game_music.h b/engines/wintermute/base/base_game_music.h
index 0ac904b8c1..72c7a171a6 100644
--- a/engines/wintermute/base/base_game_music.h
+++ b/engines/wintermute/base/base_game_music.h
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -53,7 +53,7 @@ public:
bool stopMusic(int channel);
bool playMusic(int channel, const char *filename, bool looping = true, uint32 loopStart = 0);
bool updateMusicCrossfade();
-
+
bool persistChannels(BasePersistenceManager *persistMgr);
bool persistCrossfadeSettings(BasePersistenceManager *persistMgr);
private:
@@ -68,6 +68,6 @@ private:
int32 _musicCrossfadeChannel2;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp
index 55fbe39fd2..1de8b31ca7 100644
--- a/engines/wintermute/base/base_game_settings.cpp
+++ b/engines/wintermute/base/base_game_settings.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -47,7 +47,7 @@ BaseGameSettings::BaseGameSettings(BaseGame *gameRef) {
_allowAccessTab = true;
_allowAboutTab = true;
_allowDesktopRes = false;
-
+
_compressedSavegames = true;
_richSavedGames = false;
_savedGameExt = "dsv";
@@ -101,21 +101,21 @@ bool BaseGameSettings::loadSettings(const char *filename) {
TOKEN_TABLE(SAVED_GAME_EXT)
TOKEN_TABLE(GUID)
TOKEN_TABLE_END
-
-
+
+
byte *origBuffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (origBuffer == nullptr) {
BaseEngine::LOG(0, "BaseGame::LoadSettings failed for file '%s'", filename);
return STATUS_FAILED;
}
-
+
bool ret = STATUS_OK;
-
+
byte *buffer = origBuffer;
byte *params;
int cmd;
BaseParser parser;
-
+
if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SETTINGS) {
BaseEngine::LOG(0, "'SETTINGS' keyword expected in game settings file.");
return STATUS_FAILED;
@@ -130,61 +130,61 @@ bool BaseGameSettings::loadSettings(const char *filename) {
strcpy(_gameFile, (char *)params);
}
break;
-
+
case TOKEN_STRING_TABLE:
if (DID_FAIL(_stringTable->loadFile((char *)params))) {
cmd = PARSERR_GENERIC;
}
break;
-
+
case TOKEN_RESOLUTION:
parser.scanStr((char *)params, "%d,%d", &_resWidth, &_resHeight);
break;
-
+
case TOKEN_REQUIRE_3D_ACCELERATION:
parser.scanStr((char *)params, "%b", &_requireAcceleration);
break;
-
+
case TOKEN_REQUIRE_SOUND:
parser.scanStr((char *)params, "%b", &_requireSound);
break;
-
+
case TOKEN_HWTL_MODE:
parser.scanStr((char *)params, "%d", &_TLMode);
break;
-
+
case TOKEN_ALLOW_WINDOWED_MODE:
parser.scanStr((char *)params, "%b", &_allowWindowed);
break;
-
+
case TOKEN_ALLOW_DESKTOP_RES:
parser.scanStr((char *)params, "%b", &_allowDesktopRes);
break;
-
+
case TOKEN_ALLOW_ADVANCED:
parser.scanStr((char *)params, "%b", &_allowAdvanced);
break;
-
+
case TOKEN_ALLOW_ACCESSIBILITY_TAB:
parser.scanStr((char *)params, "%b", &_allowAccessTab);
break;
-
+
case TOKEN_ALLOW_ABOUT_TAB:
parser.scanStr((char *)params, "%b", &_allowAboutTab);
break;
-
+
case TOKEN_REGISTRY_PATH:
//BaseEngine::instance().getRegistry()->setBasePath((char *)params);
break;
-
+
case TOKEN_RICH_SAVED_GAMES:
parser.scanStr((char *)params, "%b", &_richSavedGames);
break;
-
+
case TOKEN_SAVED_GAME_EXT:
_savedGameExt = (char *)params;
break;
-
+
case TOKEN_GUID:
break;
}
@@ -197,12 +197,12 @@ bool BaseGameSettings::loadSettings(const char *filename) {
BaseEngine::LOG(0, "Error loading game settings '%s'", filename);
ret = STATUS_FAILED;
}
-
+
_allowWindowed = true; // TODO: These two settings should probably be cleaned out altogether.
_compressedSavegames = true;
-
+
delete[] origBuffer;
-
+
return ret;
}
@@ -219,4 +219,4 @@ char *BaseGameSettings::getKeyFromStringTable(const char *str) const {
return _stringTable->getKey(str);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_game_settings.h b/engines/wintermute/base/base_game_settings.h
index 1dfb0b50cc..38a2fd1042 100644
--- a/engines/wintermute/base/base_game_settings.h
+++ b/engines/wintermute/base/base_game_settings.h
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -66,6 +66,6 @@ private:
bool _richSavedGames;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_keyboard_state.cpp b/engines/wintermute/base/base_keyboard_state.cpp
index 072a1bb71b..aeb56ad282 100644
--- a/engines/wintermute/base/base_keyboard_state.cpp
+++ b/engines/wintermute/base/base_keyboard_state.cpp
@@ -310,4 +310,4 @@ Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_keyboard_state.h b/engines/wintermute/base/base_keyboard_state.h
index b62ece02b7..14a57ee7b8 100644
--- a/engines/wintermute/base/base_keyboard_state.h
+++ b/engines/wintermute/base/base_keyboard_state.h
@@ -61,7 +61,7 @@ private:
bool _currentPrintable;
uint32 _currentKeyData;
uint32 _currentCharCode;
-
+
bool _currentShift;
bool _currentAlt;
bool _currentControl;
@@ -71,6 +71,6 @@ private:
Common::KeyCode vKeyToKeyCode(uint32 vkey); //TODO, reimplement using ScummVM-backend
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_named_object.cpp b/engines/wintermute/base/base_named_object.cpp
index f99ec2f5db..3d1df5ab84 100644
--- a/engines/wintermute/base/base_named_object.cpp
+++ b/engines/wintermute/base/base_named_object.cpp
@@ -68,4 +68,4 @@ void BaseNamedObject::setName(const char *name) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_named_object.h b/engines/wintermute/base/base_named_object.h
index d25fec4a82..ee4a3bba6a 100644
--- a/engines/wintermute/base/base_named_object.h
+++ b/engines/wintermute/base/base_named_object.h
@@ -46,6 +46,6 @@ public:
void setName(const char *name);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_object.cpp b/engines/wintermute/base/base_object.cpp
index ad181b922e..ea754f8f23 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -968,9 +968,9 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_movable));
persistMgr->transfer(TMEMBER(_posX));
persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_relativeScale));
+ persistMgr->transferFloat(TMEMBER(_relativeScale));
persistMgr->transfer(TMEMBER(_rotatable));
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transferPtr(TMEMBER_PTR(_sFX));
persistMgr->transfer(TMEMBER(_sFXStart));
persistMgr->transfer(TMEMBER(_sFXVolume));
@@ -982,21 +982,21 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_soundEvent));
persistMgr->transfer(TMEMBER(_zoomable));
- persistMgr->transfer(TMEMBER(_scaleX));
- persistMgr->transfer(TMEMBER(_scaleY));
+ persistMgr->transferFloat(TMEMBER(_scaleX));
+ persistMgr->transferFloat(TMEMBER(_scaleY));
- persistMgr->transfer(TMEMBER(_rotate));
+ persistMgr->transferFloat(TMEMBER(_rotate));
persistMgr->transfer(TMEMBER(_rotateValid));
- persistMgr->transfer(TMEMBER(_relativeRotate));
+ persistMgr->transferFloat(TMEMBER(_relativeRotate));
persistMgr->transfer(TMEMBER(_saveState));
persistMgr->transfer(TMEMBER(_nonIntMouseEvents));
persistMgr->transfer(TMEMBER_INT(_sFXType));
- persistMgr->transfer(TMEMBER(_sFXParam1));
- persistMgr->transfer(TMEMBER(_sFXParam2));
- persistMgr->transfer(TMEMBER(_sFXParam3));
- persistMgr->transfer(TMEMBER(_sFXParam4));
+ persistMgr->transferFloat(TMEMBER(_sFXParam1));
+ persistMgr->transferFloat(TMEMBER(_sFXParam2));
+ persistMgr->transferFloat(TMEMBER(_sFXParam3));
+ persistMgr->transferFloat(TMEMBER(_sFXParam4));
persistMgr->transfer(TMEMBER_INT(_blendMode));
@@ -1242,4 +1242,4 @@ bool BaseObject::afterMove() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_object.h b/engines/wintermute/base/base_object.h
index 7afe9cf94c..42041c5e3c 100644
--- a/engines/wintermute/base/base_object.h
+++ b/engines/wintermute/base/base_object.h
@@ -142,6 +142,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_parser.cpp b/engines/wintermute/base/base_parser.cpp
index a7e3bd5efb..0b677b6cb2 100644
--- a/engines/wintermute/base/base_parser.cpp
+++ b/engines/wintermute/base/base_parser.cpp
@@ -464,4 +464,4 @@ int32 BaseParser::scanStr(const char *in, const char *format, ...) {
return num;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_parser.h b/engines/wintermute/base/base_parser.h
index 4953ac3c0b..4bf48cc016 100644
--- a/engines/wintermute/base/base_parser.h
+++ b/engines/wintermute/base/base_parser.h
@@ -83,6 +83,6 @@ private:
char *_whiteSpace;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index 5dbacb157b..e5542d96b7 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -94,7 +94,7 @@ BasePersistenceManager::BasePersistenceManager(const char *savePrefix, bool dele
if (savePrefix) {
_savePrefix = savePrefix;
} else if (_gameRef) {
- _savePrefix = _gameRef->getGameId();
+ _savePrefix = _gameRef->getGameTargetName();
} else {
_savePrefix = "wmesav";
}
@@ -282,7 +282,7 @@ bool BasePersistenceManager::initSave(const char *desc) {
} else {
_saveStream->writeUint32LE(0);
}
-
+
thumbnailOK = true;
}
}
@@ -465,44 +465,53 @@ uint32 BasePersistenceManager::getDWORD() {
//////////////////////////////////////////////////////////////////////////
-void BasePersistenceManager::putString(const Common::String &val) {
- if (!val.size()) {
- putString("(null)");
- } else {
- _saveStream->writeUint32LE(val.size());
- _saveStream->writeString(val);
+void BasePersistenceManager::putString(const char *val) {
+ if (!val) {
+ _saveStream->writeUint32LE(0);
+ return;
}
-}
-Common::String BasePersistenceManager::getStringObj() {
- uint32 len = _loadStream->readUint32LE();
- char *ret = new char[len + 1];
- _loadStream->read(ret, len);
- ret[len] = '\0';
+ uint32 len = strlen(val);
- Common::String retString = ret;
- delete[] ret;
-
- if (retString == "(null)") {
- retString = "";
- }
+ _saveStream->writeUint32LE(len + 1);
+ _saveStream->write(val, len);
+}
- return retString;
+Common::String BasePersistenceManager::getStringObj() {
+ return getString();
}
//////////////////////////////////////////////////////////////////////////
char *BasePersistenceManager::getString() {
uint32 len = _loadStream->readUint32LE();
- char *ret = new char[len + 1];
- _loadStream->read(ret, len);
- ret[len] = '\0';
- if (!strcmp(ret, "(null)")) {
- delete[] ret;
- return nullptr;
+ if (checkVersion(1,2,2)) {
+ // Version 1.2.2 and above: len == strlen() + 1, NULL has len == 0
+
+ if (len == 0)
+ return nullptr;
+
+ char *ret = new char[len];
+ _loadStream->read(ret, len - 1);
+ ret[len - 1] = '\0';
+
+ return ret;
+
} else {
+
+ // Version 1.2.1 and older: NULL strings are represented as "(null)"
+ char *ret = new char[len + 1];
+ _loadStream->read(ret, len);
+ ret[len] = '\0';
+
+ if (!strcmp(ret, "(null)")) {
+ delete[] ret;
+ return nullptr;
+ }
+
return ret;
}
+
}
bool BasePersistenceManager::putTimeDate(const TimeDate &t) {
@@ -536,8 +545,7 @@ void BasePersistenceManager::putFloat(float val) {
int exponent = 0;
float significand = frexp(val, &exponent);
Common::String str = Common::String::format("FS%f", significand);
- _saveStream->writeUint32LE(str.size());
- _saveStream->writeString(str);
+ putString(str.c_str());
_saveStream->writeSint32LE(exponent);
}
@@ -559,8 +567,7 @@ void BasePersistenceManager::putDouble(double val) {
int exponent = 0;
double significand = frexp(val, &exponent);
Common::String str = Common::String::format("DS%f", significand);
- _saveStream->writeUint32LE(str.size());
- _saveStream->writeString(str);
+ putString(str.c_str());
_saveStream->writeSint32LE(exponent);
}
@@ -637,7 +644,7 @@ bool BasePersistenceManager::transfer(const char *name, uint32 *val) {
//////////////////////////////////////////////////////////////////////////
// float
-bool BasePersistenceManager::transfer(const char *name, float *val) {
+bool BasePersistenceManager::transferFloat(const char *name, float *val) {
if (_saving) {
putFloat(*val);
if (_saveStream->err()) {
@@ -711,7 +718,7 @@ bool BasePersistenceManager::transfer(const char *name, const char **val) {
// Common::String
bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
if (_saving) {
- putString(*val);
+ putString(val->c_str());
return STATUS_OK;
} else {
char *str = getString();
@@ -887,4 +894,4 @@ bool BasePersistenceManager::checkVersion(byte verMajor, byte verMinor, byte ver
return true;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_persistence_manager.h b/engines/wintermute/base/base_persistence_manager.h
index 7b578085ba..3c0587b362 100644
--- a/engines/wintermute/base/base_persistence_manager.h
+++ b/engines/wintermute/base/base_persistence_manager.h
@@ -52,7 +52,7 @@ public:
void putDWORD(uint32 val);
char *getString();
Common::String getStringObj();
- void putString(const Common::String &val);
+ void putString(const char *val);
float getFloat();
void putFloat(float val);
double getDouble();
@@ -76,7 +76,7 @@ public:
bool transferPtr(const char *name, void *val);
bool transfer(const char *name, int32 *val);
bool transfer(const char *name, uint32 *val);
- bool transfer(const char *name, float *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);
@@ -115,6 +115,6 @@ private:
BaseGame *_gameRef;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_point.cpp b/engines/wintermute/base/base_point.cpp
index fbd8960894..fe6ca941f3 100644
--- a/engines/wintermute/base/base_point.cpp
+++ b/engines/wintermute/base/base_point.cpp
@@ -60,4 +60,4 @@ bool BasePoint::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_point.h b/engines/wintermute/base/base_point.h
index 26568d5d0b..cf8a5be336 100644
--- a/engines/wintermute/base/base_point.h
+++ b/engines/wintermute/base/base_point.h
@@ -45,6 +45,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_quick_msg.cpp b/engines/wintermute/base/base_quick_msg.cpp
index 9f19dfd74a..ac0c107d3b 100644
--- a/engines/wintermute/base/base_quick_msg.cpp
+++ b/engines/wintermute/base/base_quick_msg.cpp
@@ -52,4 +52,4 @@ uint32 BaseQuickMsg::getStartTime() const {
return _startTime;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_quick_msg.h b/engines/wintermute/base/base_quick_msg.h
index 377f7733fd..b706424c18 100644
--- a/engines/wintermute/base/base_quick_msg.h
+++ b/engines/wintermute/base/base_quick_msg.h
@@ -44,6 +44,6 @@ private:
uint32 _startTime;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_region.cpp b/engines/wintermute/base/base_region.cpp
index 2dabe6ae44..36036a1f18 100644
--- a/engines/wintermute/base/base_region.cpp
+++ b/engines/wintermute/base/base_region.cpp
@@ -432,7 +432,7 @@ bool BaseRegion::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_active));
persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
persistMgr->transfer(TMEMBER(_lastMimicX));
persistMgr->transfer(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
@@ -532,4 +532,4 @@ bool BaseRegion::mimic(BaseRegion *region, float scale, int x, int y) {
return createRegion() ? STATUS_OK : STATUS_FAILED;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_region.h b/engines/wintermute/base/base_region.h
index 67ca158897..93ad6a6fbe 100644
--- a/engines/wintermute/base/base_region.h
+++ b/engines/wintermute/base/base_region.h
@@ -65,6 +65,6 @@ private:
int32 _lastMimicY;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp
index 036bac1dd8..25b8775a98 100644
--- a/engines/wintermute/base/base_script_holder.cpp
+++ b/engines/wintermute/base/base_script_holder.cpp
@@ -500,4 +500,4 @@ bool BaseScriptHolder::sendEvent(const char *eventName) {
return DID_SUCCEED(applyEvent(eventName));
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_script_holder.h b/engines/wintermute/base/base_script_holder.h
index 38a3f935d3..c34b0378a1 100644
--- a/engines/wintermute/base/base_script_holder.h
+++ b/engines/wintermute/base/base_script_holder.h
@@ -71,6 +71,6 @@ public:
virtual bool sendEvent(const char *eventName);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_scriptable.cpp b/engines/wintermute/base/base_scriptable.cpp
index 5753b0482b..be1e18c2c4 100644
--- a/engines/wintermute/base/base_scriptable.cpp
+++ b/engines/wintermute/base/base_scriptable.cpp
@@ -188,4 +188,4 @@ ScScript *BaseScriptable::invokeMethodThread(const char *methodName) {
return nullptr;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_scriptable.h b/engines/wintermute/base/base_scriptable.h
index f23d7faa5b..08fd32081a 100644
--- a/engines/wintermute/base/base_scriptable.h
+++ b/engines/wintermute/base/base_scriptable.h
@@ -78,6 +78,6 @@ BaseScriptable *makeSXObject(BaseGame *inGame, ScStack *stack);
BaseScriptable *makeSXStore(BaseGame *inGame);
BaseScriptable *makeSXString(BaseGame *inGame, ScStack *stack);
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp
index c920da9ee9..ab78c5ac7c 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -817,4 +817,4 @@ bool BaseSprite::killAllSounds() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_sprite.h b/engines/wintermute/base/base_sprite.h
index 05cb9fc936..1387796895 100644
--- a/engines/wintermute/base/base_sprite.h
+++ b/engines/wintermute/base/base_sprite.h
@@ -32,6 +32,7 @@
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/base/base_script_holder.h"
+#include "engines/wintermute/graphics/transform_tools.h"
namespace Wintermute {
class BaseFrame;
@@ -44,17 +45,17 @@ public:
void setDefaults();
DECLARE_PERSISTENT(BaseSprite, BaseScriptHolder)
- bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = 100, float scaleY = 100);
+ bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = kDefaultZoomX, float scaleY = kDefaultZoomY);
int32 _moveY;
int32 _moveX;
- bool display(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, uint32 alpha = 0xFFFFFFFF, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
- bool getCurrentFrame(float zoomX = 100, float zoomY = 100);
+ bool display(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY, uint32 alpha = kDefaultRgbaMod, float rotate = kDefaultAngle, TSpriteBlendMode blendMode = BLEND_NORMAL);
+ bool getCurrentFrame(float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY);
void reset();
bool isChanged();
bool isFinished();
bool loadBuffer(byte *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 = 100, float zoomY = 100, uint32 alpha = 0xFFFFFFFF);
+ bool draw(int x, int y, BaseObject *Register = nullptr, float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY, uint32 alpha = kDefaultRgbaMod);
bool _looping;
int32 _currentFrame;
bool addFrame(const char *filename, uint32 delay = 0, int hotspotX = 0, int hotspotY = 0, Rect32 *rect = nullptr);
@@ -88,6 +89,6 @@ private:
bool killAllSounds();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_string_table.cpp b/engines/wintermute/base/base_string_table.cpp
index 8207c32244..3d9cc4f8b3 100644
--- a/engines/wintermute/base/base_string_table.cpp
+++ b/engines/wintermute/base/base_string_table.cpp
@@ -253,4 +253,4 @@ bool BaseStringTable::loadFile(const char *filename, bool clearOld) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_string_table.h b/engines/wintermute/base/base_string_table.h
index 128807bd1a..f8808f5b27 100644
--- a/engines/wintermute/base/base_string_table.h
+++ b/engines/wintermute/base/base_string_table.h
@@ -50,6 +50,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp
index d93cf667f1..8a8f63240b 100644
--- a/engines/wintermute/base/base_sub_frame.cpp
+++ b/engines/wintermute/base/base_sub_frame.cpp
@@ -38,6 +38,8 @@
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/graphics/transform_tools.h"
+#include "engines/wintermute/graphics/transform_struct.h"
namespace Wintermute {
@@ -46,8 +48,9 @@ IMPLEMENT_PERSISTENT(BaseSubFrame, false)
//////////////////////////////////////////////////////////////////////////
BaseSubFrame::BaseSubFrame(BaseGame *inGame) : BaseScriptable(inGame, true) {
_surface = nullptr;
- _hotspotX = _hotspotY = 0;
- _alpha = 0xFFFFFFFF;
+ _hotspotX = kDefaultHotspotX;
+ _hotspotY = kDefaultHotspotY;
+ _alpha = kDefaultRgbaMod;
_transparent = 0xFFFF00FF;
_wantsDefaultRect = false;
@@ -233,12 +236,18 @@ const char* BaseSubFrame::getSurfaceFilename() {
//////////////////////////////////////////////////////////////////////
bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, float rotate, TSpriteBlendMode blendMode) {
+
+ rotate = fmod(rotate, 360.0f);
+ if (rotate < 0) {
+ rotate += 360.0f;
+ }
+
if (!_surface) {
return STATUS_OK;
}
if (registerOwner != nullptr && !_decoration) {
- if (zoomX == 100 && zoomY == 100) {
+ if (zoomX == kDefaultZoomX && zoomY == kDefaultZoomY) {
BaseEngine::getRenderer()->addRectToList(new BaseActiveRect(_gameRef, registerOwner, this, x - _hotspotX + getRect().left, y - _hotspotY + getRect().top, getRect().right - getRect().left, getRect().bottom - getRect().top, zoomX, zoomY, precise));
} else {
BaseEngine::getRenderer()->addRectToList(new BaseActiveRect(_gameRef, registerOwner, this, (int)(x - (_hotspotX + getRect().left) * (zoomX / 100)), (int)(y - (_hotspotY + getRect().top) * (zoomY / 100)), (int)((getRect().right - getRect().left) * (zoomX / 100)), (int)((getRect().bottom - getRect().top) * (zoomY / 100)), zoomX, zoomY, precise));
@@ -251,17 +260,24 @@ bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, fl
bool res;
//if (Alpha==0xFFFFFFFF) Alpha = _alpha; // TODO: better (combine owner's and self alpha)
- if (_alpha != 0xFFFFFFFF) {
+ if (_alpha != kDefaultRgbaMod) {
alpha = _alpha;
}
- if (rotate != 0.0f) {
- res = _surface->displayTransform((int)(x - _hotspotX * (zoomX / 100)), (int)(y - _hotspotY * (zoomY / 100)), _hotspotX, _hotspotY, getRect(), zoomX, zoomY, alpha, rotate, blendMode, _mirrorX, _mirrorY);
+ if (rotate != kDefaultAngle) {
+ Point32 boxOffset, rotatedHotspot, hotspotOffset, newOrigin;
+ Point32 origin(x, y);
+ Rect32 oldRect = getRect();
+ Point32 newHotspot;
+ TransformStruct transform = TransformStruct(zoomX, zoomY, rotate, _hotspotX, _hotspotY, blendMode, alpha, _mirrorX, _mirrorY, 0, 0);
+ Rect32 newRect = TransformTools::newRect (oldRect, transform, &newHotspot);
+ newOrigin = origin - newHotspot;
+ res = _surface->displayTransform(newOrigin.x, newOrigin.y, oldRect, newRect, transform);
} else {
- if (zoomX == 100 && zoomY == 100) {
+ if (zoomX == kDefaultZoomX && zoomY == kDefaultZoomY) {
res = _surface->displayTrans(x - _hotspotX, y - _hotspotY, getRect(), alpha, blendMode, _mirrorX, _mirrorY);
} else {
- res = _surface->displayTransZoom((int)(x - _hotspotX * (zoomX / 100)), (int)(y - _hotspotY * (zoomY / 100)), getRect(), zoomX, zoomY, alpha, blendMode, _mirrorX, _mirrorY);
+ res = _surface->displayTransZoom((int)(x - _hotspotX * (zoomX / kDefaultZoomX)), (int)(y - _hotspotY * (zoomY / kDefaultZoomY)), getRect(), zoomX, zoomY, alpha, blendMode, _mirrorX, _mirrorY);
}
}
@@ -657,4 +673,4 @@ bool BaseSubFrame::setSurfaceSimple() {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_sub_frame.h b/engines/wintermute/base/base_sub_frame.h
index 37ba34b748..ba3d5b955a 100644
--- a/engines/wintermute/base/base_sub_frame.h
+++ b/engines/wintermute/base/base_sub_frame.h
@@ -88,6 +88,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_surface_storage.cpp b/engines/wintermute/base/base_surface_storage.cpp
index 8dbd6a6d2a..f1d068674b 100644
--- a/engines/wintermute/base/base_surface_storage.cpp
+++ b/engines/wintermute/base/base_surface_storage.cpp
@@ -203,4 +203,4 @@ bool BaseSurfaceStorage::surfaceSortCB(const BaseSurface *s1, const BaseSurface
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_surface_storage.h b/engines/wintermute/base/base_surface_storage.h
index 61738e69a2..c0049d676c 100644
--- a/engines/wintermute/base/base_surface_storage.h
+++ b/engines/wintermute/base/base_surface_storage.h
@@ -52,6 +52,6 @@ public:
Common::Array<BaseSurface *> _surfaces;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_transition_manager.cpp b/engines/wintermute/base/base_transition_manager.cpp
index 1c869e6a2b..eee5f1aae7 100644
--- a/engines/wintermute/base/base_transition_manager.cpp
+++ b/engines/wintermute/base/base_transition_manager.cpp
@@ -135,4 +135,4 @@ bool BaseTransitionMgr::update() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_transition_manager.h b/engines/wintermute/base/base_transition_manager.h
index edb3045a58..82edb9ff88 100644
--- a/engines/wintermute/base/base_transition_manager.h
+++ b/engines/wintermute/base/base_transition_manager.h
@@ -49,6 +49,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/base_viewport.cpp b/engines/wintermute/base/base_viewport.cpp
index f79e5c9f13..09ac80e9de 100644
--- a/engines/wintermute/base/base_viewport.cpp
+++ b/engines/wintermute/base/base_viewport.cpp
@@ -97,4 +97,4 @@ int BaseViewport::getHeight() const {
return _rect.bottom - _rect.top;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_viewport.h b/engines/wintermute/base/base_viewport.h
index 584e5a78f9..0225c02c7c 100644
--- a/engines/wintermute/base/base_viewport.h
+++ b/engines/wintermute/base/base_viewport.h
@@ -52,6 +52,6 @@ private:
Rect32 _rect;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/base_disk_file.cpp b/engines/wintermute/base/file/base_disk_file.cpp
index 3c1ecc7a73..7391d819fc 100644
--- a/engines/wintermute/base/file/base_disk_file.cpp
+++ b/engines/wintermute/base/file/base_disk_file.cpp
@@ -66,12 +66,6 @@ static Common::FSNode getNodeForRelativePath(const Common::String &filename) {
const Common::FSNode gameDataDir(ConfMan.get("path"));
Common::FSNode curNode = gameDataDir;
- Common::String fixedPath = "";
- while (!path.empty()) {
- fixedPath += path.nextToken() + "/";
- }
- fixedPath.deleteLastChar();
-
// Parse all path-elements
while (!path.empty()) {
// Get the next path-component by slicing on '\\'
@@ -198,4 +192,4 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
return nullptr;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/file/base_disk_file.h b/engines/wintermute/base/file/base_disk_file.h
index c9f93b80d9..81cc22b86d 100644
--- a/engines/wintermute/base/file/base_disk_file.h
+++ b/engines/wintermute/base/file/base_disk_file.h
@@ -36,6 +36,6 @@ namespace Wintermute {
Common::SeekableReadStream *openDiskFile(const Common::String &filename);
bool diskFileExists(const Common::String &filename);
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/base_file.cpp b/engines/wintermute/base/file/base_file.cpp
index f52a13211e..42eea69824 100644
--- a/engines/wintermute/base/file/base_file.cpp
+++ b/engines/wintermute/base/file/base_file.cpp
@@ -65,4 +65,4 @@ Common::SeekableReadStream *BaseFile::getMemStream() {
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/file/base_file.h b/engines/wintermute/base/file/base_file.h
index 8eda6d51d9..9acda7ffce 100644
--- a/engines/wintermute/base/file/base_file.h
+++ b/engines/wintermute/base/file/base_file.h
@@ -62,6 +62,6 @@ public:
virtual Common::SeekableReadStream *getMemStream();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/base_file_entry.cpp b/engines/wintermute/base/file/base_file_entry.cpp
index 1968da6f47..846f56b55c 100644
--- a/engines/wintermute/base/file/base_file_entry.cpp
+++ b/engines/wintermute/base/file/base_file_entry.cpp
@@ -70,4 +70,4 @@ BaseFileEntry::~BaseFileEntry() {
_package = nullptr; // ref only
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/file/base_file_entry.h b/engines/wintermute/base/file/base_file_entry.h
index 6e4823d994..9d738c8c11 100644
--- a/engines/wintermute/base/file/base_file_entry.h
+++ b/engines/wintermute/base/file/base_file_entry.h
@@ -55,6 +55,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/base_package.cpp b/engines/wintermute/base/file/base_package.cpp
index 73f767c3ef..512279b72c 100644
--- a/engines/wintermute/base/file/base_package.cpp
+++ b/engines/wintermute/base/file/base_package.cpp
@@ -273,4 +273,4 @@ Common::SeekableReadStream *PackageSet::createReadStreamForMember(const Common::
return nullptr;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/file/base_package.h b/engines/wintermute/base/file/base_package.h
index bcf088aaea..18156c4f65 100644
--- a/engines/wintermute/base/file/base_package.h
+++ b/engines/wintermute/base/file/base_package.h
@@ -85,6 +85,6 @@ private:
Common::HashMap<Common::String, Common::ArchiveMemberPtr>::iterator _filesIter;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/base_save_thumb_file.cpp b/engines/wintermute/base/file/base_save_thumb_file.cpp
index 2c4ddf4875..bb172ca66a 100644
--- a/engines/wintermute/base/file/base_save_thumb_file.cpp
+++ b/engines/wintermute/base/file/base_save_thumb_file.cpp
@@ -150,4 +150,4 @@ bool BaseSaveThumbFile::seek(uint32 pos, int whence) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/file/base_save_thumb_file.h b/engines/wintermute/base/file/base_save_thumb_file.h
index 3b217525fd..faf1af9255 100644
--- a/engines/wintermute/base/file/base_save_thumb_file.h
+++ b/engines/wintermute/base/file/base_save_thumb_file.h
@@ -47,6 +47,6 @@ private:
byte *_data;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/file/dcpackage.h b/engines/wintermute/base/file/dcpackage.h
index 2234139408..a2ec5d28d5 100644
--- a/engines/wintermute/base/file/dcpackage.h
+++ b/engines/wintermute/base/file/dcpackage.h
@@ -75,6 +75,6 @@ v2: uint32 TimeDate1
*/
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/font/base_font.cpp b/engines/wintermute/base/font/base_font.cpp
index 596f9fb5c6..26bc0e7985 100644
--- a/engines/wintermute/base/font/base_font.cpp
+++ b/engines/wintermute/base/font/base_font.cpp
@@ -137,4 +137,4 @@ bool BaseFont::isTrueType(BaseGame *gameRef, const Common::String &filename) {
return ret;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font.h b/engines/wintermute/base/font/base_font.h
index 50587fa7eb..d75d3f4fb5 100644
--- a/engines/wintermute/base/font/base_font.h
+++ b/engines/wintermute/base/font/base_font.h
@@ -56,6 +56,6 @@ private:
static bool isTrueType(BaseGame *game, const Common::String &filename);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/font/base_font_bitmap.cpp b/engines/wintermute/base/font/base_font_bitmap.cpp
index 03bd471636..890a9a2f83 100644
--- a/engines/wintermute/base/font/base_font_bitmap.cpp
+++ b/engines/wintermute/base/font/base_font_bitmap.cpp
@@ -587,4 +587,4 @@ int BaseFontBitmap::getLetterHeight() {
return _tileHeight;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_bitmap.h b/engines/wintermute/base/font/base_font_bitmap.h
index 0bdac64026..c810777446 100644
--- a/engines/wintermute/base/font/base_font_bitmap.h
+++ b/engines/wintermute/base/font/base_font_bitmap.h
@@ -66,6 +66,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/font/base_font_storage.cpp b/engines/wintermute/base/font/base_font_storage.cpp
index 3286742478..8abd368b70 100644
--- a/engines/wintermute/base/font/base_font_storage.cpp
+++ b/engines/wintermute/base/font/base_font_storage.cpp
@@ -138,4 +138,4 @@ bool BaseFontStorage::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_storage.h b/engines/wintermute/base/font/base_font_storage.h
index 60874167e7..f4ac490324 100644
--- a/engines/wintermute/base/font/base_font_storage.h
+++ b/engines/wintermute/base/font/base_font_storage.h
@@ -50,6 +50,6 @@ public:
bool initLoop();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index 2fcdebc117..e073f27970 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -272,7 +272,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
// 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
- surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat());
} else { // We are using a fallback, they can't do 32bpp
surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
@@ -285,7 +285,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
}
BaseSurface *retSurface = _gameRef->_renderer->createSurface();
- Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ Graphics::Surface *convertedSurface = surface->convertTo(_gameRef->_renderer->getPixelFormat());
retSurface->putSurface(*convertedSurface, true);
convertedSurface->free();
surface->free();
@@ -644,4 +644,4 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight
}*/
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_truetype.h b/engines/wintermute/base/font/base_font_truetype.h
index f93505921f..fdbae30684 100644
--- a/engines/wintermute/base/font/base_font_truetype.h
+++ b/engines/wintermute/base/font/base_font_truetype.h
@@ -148,6 +148,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/base_image.cpp b/engines/wintermute/base/gfx/base_image.cpp
index 75de95128f..d0dbae352e 100644
--- a/engines/wintermute/base/gfx/base_image.cpp
+++ b/engines/wintermute/base/gfx/base_image.cpp
@@ -228,4 +228,4 @@ bool BaseImage::copyFrom(BaseImage *origImage, int newWidth, int newHeight) {
return true;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/base_image.h b/engines/wintermute/base/gfx/base_image.h
index 017305e5d0..4b04fd1252 100644
--- a/engines/wintermute/base/gfx/base_image.h
+++ b/engines/wintermute/base/gfx/base_image.h
@@ -67,6 +67,6 @@ private:
BaseFileManager *_fileManager;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/base_renderer.cpp b/engines/wintermute/base/gfx/base_renderer.cpp
index c20881e425..1f171209d7 100644
--- a/engines/wintermute/base/gfx/base_renderer.cpp
+++ b/engines/wintermute/base/gfx/base_renderer.cpp
@@ -113,15 +113,21 @@ void BaseRenderer::setIndicatorVal(int value) {
}
void BaseRenderer::setLoadingScreen(const char *filename, int x, int y) {
- // TODO: Handle NULL
- _loadImageName = filename;
+ if (filename == nullptr) {
+ _saveImageName = "";
+ } else {
+ _loadImageName = filename;
+ }
_loadImageX = x;
_loadImageY = y;
}
void BaseRenderer::setSaveImage(const char *filename, int x, int y) {
- // TODO: Handle NULL
- _saveImageName = filename;
+ if (filename == nullptr) {
+ _saveImageName = "";
+ } else {
+ _saveImageName = filename;
+ }
_saveImageX = x;
_saveImageY = y;
}
@@ -395,4 +401,4 @@ bool BaseRenderer::displayIndicator() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/base_renderer.h b/engines/wintermute/base/gfx/base_renderer.h
index bfef29a5ed..31dc2a022d 100644
--- a/engines/wintermute/base/gfx/base_renderer.h
+++ b/engines/wintermute/base/gfx/base_renderer.h
@@ -228,6 +228,6 @@ private:
BaseRenderer *makeOSystemRenderer(BaseGame *inGame); // Implemented in BRenderSDL.cpp
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/base_surface.cpp b/engines/wintermute/base/gfx/base_surface.cpp
index 2002463ea4..19639c0c33 100644
--- a/engines/wintermute/base/gfx/base_surface.cpp
+++ b/engines/wintermute/base/gfx/base_surface.cpp
@@ -75,8 +75,8 @@ bool BaseSurface::displayHalfTrans(int x, int y, Rect32 rect) {
}
//////////////////////////////////////////////////////////////////////////
-bool BaseSurface::displayTransform(int x, int y, int hotX, int hotY, Rect32 rect, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return displayTransZoom(x, y, rect, zoomX, zoomY, alpha, blendMode, mirrorX, mirrorY);
+bool BaseSurface::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) {
+ return displayTransform(x, y, rect, newRect, transform);
}
//////////////////////////////////////////////////////////////////////////
@@ -146,4 +146,4 @@ void BaseSurface::setSize(int width, int height) {
_height = height;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/base_surface.h b/engines/wintermute/base/gfx/base_surface.h
index b83efa0bb8..8a0603734e 100644
--- a/engines/wintermute/base/gfx/base_surface.h
+++ b/engines/wintermute/base/gfx/base_surface.h
@@ -32,6 +32,7 @@
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/math/rect32.h"
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transform_struct.h"
namespace Wintermute {
@@ -49,12 +50,12 @@ public:
virtual bool displayHalfTrans(int x, int y, Rect32 rect);
virtual bool isTransparentAt(int x, int y);
- virtual bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+ virtual bool displayTransZoom(int x, int y, Rect32 rect, int32 zoomX, int32 zoomY, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) = 0;
virtual bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 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 displayTransform(int x, int y, int hotX, int hotY, Rect32 rect, float zoomX, float zoomY, uint32 alpha, float rotate, 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, int32 zoomX, int32 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 restore();
virtual bool create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime = -1, bool keepLoaded = false) = 0;
@@ -95,6 +96,6 @@ protected:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index e1424cea87..e6d769c653 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -60,8 +60,7 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
- setAlphaMod(255);
- setColorMod(255, 255, 255);
+ _colorMod = kDefaultRgbaMod;
_dirtyRect = nullptr;
_disableDirtyRects = false;
_tempDisableDirtyRects = 0;
@@ -85,7 +84,6 @@ BaseRenderOSystem::~BaseRenderOSystem() {
delete _renderSurface;
_blankSurface->free();
delete _blankSurface;
- TransparentSurface::destroyLookup();
}
//////////////////////////////////////////////////////////////////////////
@@ -128,7 +126,7 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
_windowed = !ConfMan.getBool("fullscreen");
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
g_system->beginGFXTransaction();
g_system->initSize(_width, _height, &format);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
@@ -150,18 +148,6 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
return STATUS_OK;
}
-void BaseRenderOSystem::setAlphaMod(byte alpha) {
- byte r = RGBCOLGetR(_colorMod);
- byte g = RGBCOLGetB(_colorMod);
- byte b = RGBCOLGetB(_colorMod);
- _colorMod = BS_ARGB(alpha, r, g, b);
-}
-
-void BaseRenderOSystem::setColorMod(byte r, byte g, byte b) {
- byte alpha = RGBCOLGetA(_colorMod);
- _colorMod = BS_ARGB(alpha, r, g, b);
-}
-
bool BaseRenderOSystem::indicatorFlip() {
g_system->copyRectToScreen((byte *)_renderSurface->getBasePtr(_indicatorX, _indicatorY), _renderSurface->pitch, _indicatorX, _indicatorY, _indicatorWidthDrawn, _indicatorHeight);
g_system->updateScreen();
@@ -200,9 +186,9 @@ bool BaseRenderOSystem::flip() {
}
if (_needsFlip || _disableDirtyRects || _tempDisableDirtyRects) {
if (_disableDirtyRects || _tempDisableDirtyRects) {
- g_system->copyRectToScreen((byte *)_renderSurface->pixels, _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+ g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
}
- // g_system->copyRectToScreen((byte *)_renderSurface->pixels, _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
+ // g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
delete _dirtyRect;
_dirtyRect = nullptr;
g_system->updateScreen();
@@ -256,7 +242,6 @@ void BaseRenderOSystem::fade(uint16 alpha) {
return fadeToColor(0, 0, 0, dwAlpha);
}
-
//////////////////////////////////////////////////////////////////////////
void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect) {
Common::Rect fillRect;
@@ -279,14 +264,14 @@ void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a, Common::Rect
//TODO: This is only here until I'm sure about the final pixelformat
uint32 col = _renderSurface->format.ARGBToColor(a, r, g, b);
- setAlphaMod(255);
- setColorMod(255, 255, 255);
Graphics::Surface surf;
surf.create((uint16)fillRect.width(), (uint16)fillRect.height(), _renderSurface->format);
Common::Rect sizeRect(fillRect);
sizeRect.translate(-fillRect.top, -fillRect.left);
surf.fillRect(fillRect, col);
- drawSurface(nullptr, &surf, &sizeRect, &fillRect, false, false);
+ TransformStruct temp = TransformStruct();
+ temp._alphaDisable = false;
+ drawSurface(nullptr, &surf, &sizeRect, &fillRect, temp);
surf.free();
//SDL_SetRenderDrawColor(_renderer, r, g, b, a);
@@ -298,16 +283,18 @@ Graphics::PixelFormat BaseRenderOSystem::getPixelFormat() const {
return _renderSurface->format;
}
-void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha) {
+void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) {
+
if (_tempDisableDirtyRects || _disableDirtyRects) {
- RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
- ticket->_colorMod = _colorMod;
+ 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) {
@@ -320,12 +307,11 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
}
if (owner) { // Fade-tickets are owner-less
- RenderTicket compare(owner, nullptr, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
+ RenderTicket compare(owner, nullptr, srcRect, dstRect, transform);
compare._batchNum = _batchNum;
if (_spriteBatch) {
_batchNum++;
}
- compare._colorMod = _colorMod;
RenderQueueIterator it;
// Avoid calling end() and operator* every time, when potentially going through
// LOTS of tickets.
@@ -334,7 +320,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
for (it = _lastAddedTicket; it != endIterator; ++it) {
compareTicket = *it;
if (*(compareTicket) == compare && compareTicket->_isValid) {
- compareTicket->_colorMod = _colorMod;
+ compareTicket->_transform._rgbaMod = transform._rgbaMod;
if (_disableDirtyRects) {
drawFromSurface(compareTicket);
} else {
@@ -349,8 +335,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
}
}
}
- RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
- ticket->_colorMod = _colorMod;
+ RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
if (!_disableDirtyRects) {
drawFromTicket(ticket);
_previousTicket = ticket;
@@ -385,12 +370,14 @@ void BaseRenderOSystem::repeatLastDraw(int offsetX, int offsetY, int numTimesX,
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, false, false);
+ drawSurface(origTicket->_owner, origTicket->getSurface(), &srcRect, &dstRect, temp);
dstRect.translate(offsetX, 0);
}
dstRect.left = initLeft;
@@ -535,7 +522,7 @@ void BaseRenderOSystem::drawTickets() {
// convert from screen-coords to surface-coords.
dstClip.translate(-offsetX, -offsetY);
- _colorMod = ticket->_colorMod;
+ _colorMod = ticket->_transform._rgbaMod;
drawFromSurface(ticket, &pos, &dstClip);
_needsFlip = true;
}
@@ -546,7 +533,7 @@ void BaseRenderOSystem::drawTickets() {
// Revert the colorMod-state.
_colorMod = oldColorMod;
-
+
it = _renderQueue.begin();
// Clean out the old tickets
decrement = 0;
@@ -625,8 +612,8 @@ bool BaseRenderOSystem::setViewport(int left, int top, int right, int bottom) {
// TODO: Hopefully this is the same logic that ScummVM uses.
rect.left = (int16)(left + _borderLeft);
rect.top = (int16)(top + _borderTop);
- rect.right = (int16)((right - left) * _ratioX);
- rect.bottom = (int16)((bottom - top) * _ratioY);
+ rect.setWidth((int16)((right - left) * _ratioX));
+ rect.setHeight((int16)((bottom - top) * _ratioY));
_renderRect = rect;
return STATUS_OK;
@@ -643,15 +630,13 @@ Rect32 BaseRenderOSystem::getViewPort() {
//////////////////////////////////////////////////////////////////////////
void BaseRenderOSystem::modTargetRect(Common::Rect *rect) {
- // FIXME: This is wrong in quite a few ways right now, and ends up
- // breaking the notebook in Dirty Split, so we disable the correction
- // for now, this will need fixing when a game with odd aspect-ratios
- // show up.
return;
- rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft - _renderRect.left);
- rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop - _renderRect.top);
- rect->setWidth((int16)MathUtil::roundUp(rect->width() * _ratioX));
- rect->setHeight((int16)MathUtil::roundUp(rect->height() * _ratioY));
+ int newWidth = (int16)MathUtil::roundUp(rect->width() * _ratioX);
+ int newHeight = (int16)MathUtil::roundUp(rect->height() * _ratioY);
+ rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft);
+ rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop);
+ rect->setWidth(newWidth);
+ rect->setHeight(newHeight);
}
//////////////////////////////////////////////////////////////////////////
@@ -694,7 +679,7 @@ void BaseRenderOSystem::endSaveLoad() {
_drawNum = 1;
_renderSurface->fillRect(Common::Rect(0, 0, _renderSurface->h, _renderSurface->w), _renderSurface->format.ARGBToColor(255, 0, 0, 0));
- g_system->copyRectToScreen((byte *)_renderSurface->pixels, _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+ g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
g_system->updateScreen();
}
@@ -710,4 +695,4 @@ bool BaseRenderOSystem::endSpriteBatch() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index 3cb0fa82a3..928a52d4fc 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -33,10 +33,30 @@
#include "common/rect.h"
#include "graphics/surface.h"
#include "common/list.h"
+#include "engines/wintermute/graphics/transform_struct.h"
namespace Wintermute {
class BaseSurfaceOSystem;
class RenderTicket;
+/**
+ * A 2D-renderer implementation for WME.
+ * This renderer makes use of a "ticket"-system, where all draw-calls
+ * are stored as tickets until flip() is called, and compared against the tickets
+ * from last frame, to determine which calls were the same as last round
+ * (i.e. in the exact same order, with the exact same arguments), and thus
+ * figure out which parts of the screen need to be redrawn.
+ *
+ * Important concepts to handle here, is the ordered number of any ticket
+ * which is called the "drawNum", every frame this starts from scratch, and
+ * then the incoming tickets created from the draw-calls are checked to see whether
+ * they came before, on, or after the drawNum they had last frame. Everything else
+ * being equal, this information is then used to check whether the draw order changed,
+ * which will then create a need for redrawing, as we draw with an alpha-channel here.
+ *
+ * There is also a draw path that draws without tickets, for debugging purposes,
+ * as well as to accomodate situations with large enough amounts of draw calls,
+ * that there will be too much overhead involved with comparing the generated tickets.
+ */
class BaseRenderOSystem : public BaseRenderer {
public:
BaseRenderOSystem(BaseGame *inGame);
@@ -56,10 +76,13 @@ public:
BaseImage *takeScreenshot() override;
- void setAlphaMod(byte alpha);
- void setColorMod(byte r, byte g, byte b);
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.
+ */
void drawFromTicket(RenderTicket *renderTicket);
bool setViewport(int left, int top, int right, int bottom) override;
@@ -80,11 +103,18 @@ public:
virtual bool startSpriteBatch() override;
virtual bool endSpriteBatch() override;
void endSaveLoad();
- void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha = false) ;
+ 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:
- void addDirtyRect(const Common::Rect &rect) ;
+ /**
+ * Mark a specified rect of the screen as dirty.
+ * @param rect the region to be marked as dirty
+ */
+ void addDirtyRect(const Common::Rect &rect);
+ /**
+ * Traverse the tickets that are dirty, and draw them
+ */
void drawTickets();
// Non-dirty-rects:
void drawFromSurface(RenderTicket *ticket);
@@ -97,7 +127,7 @@ private:
RenderTicket *_previousTicket;
bool _needsFlip;
- uint32 _drawNum;
+ uint32 _drawNum; ///< The global number of the current draw-operation.
Common::Rect _renderRect;
Graphics::Surface *_renderSurface;
Graphics::Surface *_blankSurface;
@@ -119,6 +149,6 @@ private:
bool _skipThisFrame;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index 0572ef2f6e..14767aa067 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -48,10 +48,11 @@ namespace Wintermute {
BaseSurfaceOSystem::BaseSurfaceOSystem(BaseGame *inGame) : BaseSurface(inGame) {
_surface = new Graphics::Surface();
_alphaMask = nullptr;
- _hasAlpha = true;
+ _alphaType = TransparentSurface::ALPHA_FULL;
_lockPixels = nullptr;
_lockPitch = 0;
_loaded = false;
+ _rotation = 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -70,22 +71,37 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
renderer->invalidateTicketsFromSurface(this);
}
-bool hasTransparency(Graphics::Surface *surf) {
+TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
if (surf->format.bytesPerPixel != 4) {
- warning("hasTransparency:: non 32 bpp surface passed as argument");
- return false;
+ warning("hasTransparencyType:: non 32 bpp surface passed as argument");
+ return TransparentSurface::ALPHA_OPAQUE;
}
uint8 r, g, b, a;
+ bool seenAlpha = false;
+ bool seenFullAlpha = false;
for (int i = 0; i < surf->h; i++) {
+ if (seenFullAlpha) {
+ break;
+ }
for (int j = 0; j < surf->w; j++) {
- uint32 pix = *(uint32 *)surf->getBasePtr(j, i);
+ uint32 pix = *(const uint32 *)surf->getBasePtr(j, i);
surf->format.colorToARGB(pix, a, r, g, b);
if (a != 255) {
- return true;
+ seenAlpha = true;
+ if (a != 0) {
+ seenFullAlpha = true;
+ break;
+ }
}
}
}
- return false;
+ if (seenFullAlpha) {
+ return TransparentSurface::ALPHA_FULL;
+ } else if (seenAlpha) {
+ return TransparentSurface::ALPHA_BINARY;
+ } else {
+ return TransparentSurface::ALPHA_OPAQUE;
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -127,49 +143,46 @@ bool BaseSurfaceOSystem::finishLoad() {
_width = image->getSurface()->w;
_height = image->getSurface()->h;
- bool isSaveGameGrayscale = scumm_strnicmp(_filename.c_str(), "savegame:", 9) == 0 && (_filename.c_str()[_filename.size() - 1] == 'g' || _filename.c_str()[_filename.size() - 1] == 'G');
+ bool isSaveGameGrayscale = _filename.matchString("savegame:*g", true);
if (isSaveGameGrayscale) {
warning("grayscaleConversion not yet implemented");
// FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img); TODO
}
- // no alpha, set color key
- /* if (surface->format.bytesPerPixel != 4)
- SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue));*/
-
- // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?)
- // Well, actually, we don't convert via 24-bit as the color-key application overwrites the Alpha-channel anyhow.
_surface->free();
delete _surface;
bool needsColorKey = false;
bool replaceAlpha = true;
- if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
- needsColorKey = true;
- replaceAlpha = false;
- } else if (image->getSurface()->format.bytesPerPixel == 1 && image->getPalette()) {
+ if (image->getSurface()->format.bytesPerPixel == 1) {
+ if (!image->getPalette()) {
+ error("Missing palette while loading 8bit image %s", _filename.c_str());
+ }
_surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
needsColorKey = true;
- } else if (image->getSurface()->format.bytesPerPixel >= 3 && image->getSurface()->format != g_system->getScreenFormat()) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
- if (image->getSurface()->format.bytesPerPixel == 3) {
- needsColorKey = true;
- }
} else {
- _surface = new Graphics::Surface();
- _surface->copyFrom(*image->getSurface());
- if (_surface->format.aBits() == 0) {
+ if (image->getSurface()->format != g_system->getScreenFormat()) {
+ _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
+ } else {
+ _surface = new Graphics::Surface();
+ _surface->copyFrom(*image->getSurface());
+ }
+
+ if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
+ // 32 bpp BMPs have nothing useful in their alpha-channel -> color-key
+ needsColorKey = true;
+ replaceAlpha = false;
+ } else if (image->getSurface()->format.aBits() == 0) {
needsColorKey = true;
}
}
-
+
if (needsColorKey) {
TransparentSurface trans(*_surface);
trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
}
- _hasAlpha = hasTransparency(_surface);
+ _alphaType = hasTransparencyType(_surface);
_valid = true;
_gameRef->addMem(_width * _height * 4);
@@ -233,7 +246,7 @@ uint32 BaseSurfaceOSystem::getPixelAt(Graphics::Surface *surface, int x, int y)
warning("BaseSurfaceOSystem::GetPixel - Not ported yet");
int bpp = surface->format.bytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
- uint8 *p = (uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+ uint8 *p = (uint8 *)surface->getBasePtr(x, y);
switch (bpp) {
case 1:
@@ -319,39 +332,56 @@ bool BaseSurfaceOSystem::endPixelOp() {
//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return drawSprite(x, y, &rect, 100, 100, 0xFFFFFFFF, true, blendMode, mirrorX, mirrorY);
+ _rotation = 0;
+ return drawSprite(x, y, &rect, nullptr, TransformStruct(kDefaultZoomX, kDefaultZoomY, mirrorX, mirrorY));
}
//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::displayTrans(int x, int y, Rect32 rect, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return drawSprite(x, y, &rect, 100, 100, alpha, false, blendMode, mirrorX, mirrorY);
+ _rotation = 0;
+ return drawSprite(x, y, &rect, nullptr, TransformStruct(kDefaultZoomX, kDefaultZoomY, blendMode, alpha, mirrorX, mirrorY));
}
//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::displayTransOffset(int x, int y, Rect32 rect, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
- return drawSprite(x, y, &rect, 100, 100, alpha, false, blendMode, mirrorX, mirrorY, offsetX, offsetY);
+ _rotation = 0;
+ return drawSprite(x, y, &rect, nullptr, TransformStruct(kDefaultZoomX, kDefaultZoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, blendMode, alpha, mirrorX, mirrorY, offsetX, offsetY));
}
//////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return drawSprite(x, y, &rect, zoomX, zoomY, alpha, false, blendMode, mirrorX, mirrorY);
+bool BaseSurfaceOSystem::displayTransZoom(int x, int y, Rect32 rect, int32 zoomX, int32 zoomY, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+ _rotation = 0;
+ return drawSprite(x, y, &rect, nullptr, TransformStruct(zoomX, zoomY, blendMode, alpha, mirrorX, mirrorY));
}
//////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, bool transparent, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return drawSprite(x, y, &rect, zoomX, zoomY, alpha, !transparent, blendMode, mirrorX, mirrorY);
+bool BaseSurfaceOSystem::displayZoom(int x, int y, Rect32 rect, int32 zoomX, int32 zoomY, uint32 alpha, bool transparent, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+ _rotation = 0;
+ TransformStruct transform;
+ if (transparent) {
+ transform = TransformStruct(zoomX, zoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, blendMode, alpha, mirrorX, mirrorY);
+ } else {
+ transform = TransformStruct(zoomX, zoomY, mirrorX, mirrorY);
+ }
+ return drawSprite(x, y, &rect, nullptr, transform);
}
//////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTransform(int x, int y, int hotX, int hotY, Rect32 rect, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
- return drawSprite(x, y, &rect, zoomX, zoomY, alpha, false, blendMode, mirrorX, mirrorY);
+bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) {
+ _rotation = (uint32)transform._angle;
+ if (transform._angle < 0.0f) {
+ warning("Negative rotation: %d %d", transform._angle, _rotation);
+ _rotation = (uint32)(360.0f + transform._angle);
+ warning("Negative post rotation: %d %d", transform._angle, _rotation);
+ }
+ return drawSprite(x, y, &rect, &newRect, transform);
}
//////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, float zoomY, uint32 alpha, bool alphaDisable, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
+bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transform) {
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
if (!_loaded) {
@@ -359,17 +389,9 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, flo
}
if (renderer->_forceAlphaColor != 0) {
- alpha = renderer->_forceAlphaColor;
+ transform._rgbaMod = renderer->_forceAlphaColor;
}
- byte r = RGBCOLGetR(alpha);
- byte g = RGBCOLGetG(alpha);
- byte b = RGBCOLGetB(alpha);
- byte a = RGBCOLGetA(alpha);
-
- renderer->setAlphaMod(a);
- renderer->setColorMod(r, g, b);
-
#if 0 // These are kept for reference if BlendMode is reimplemented at some point.
if (alphaDisable) {
SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_NONE);
@@ -386,8 +408,8 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, flo
srcRect.setHeight(rect->bottom - rect->top);
Common::Rect position;
- position.left = x + offsetX;
- position.top = y + offsetY;
+ position.left = x + transform._offset.x;
+ position.top = y + transform._offset.y;
// Crop off-by-ones:
if (position.left == -1) {
@@ -396,31 +418,26 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, flo
if (position.top == -1) {
position.top = 0; // TODO: Something is wrong
}
-
- position.setWidth((int16)((float)srcRect.width() * zoomX / 100.f));
- position.setHeight((int16)((float)srcRect.height() * zoomX / 100.f));
-
+ 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));
+ }
renderer->modTargetRect(&position);
- /* position.left += offsetX;
- position.top += offsetY;*/
-
// TODO: This actually requires us to have the SAME source-offsets every time,
// But no checking is in place for that yet.
- // TODO: Optimize by not doing alpha-blits if we lack or disable alpha
- bool hasAlpha;
- if (_hasAlpha && !alphaDisable) {
- hasAlpha = true;
- } else {
- hasAlpha = false;
- }
- if (alphaDisable) {
- warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
+ // Optimize by not doing alpha-blits if we lack alpha
+ if (_alphaType == TransparentSurface::ALPHA_OPAQUE && !transform._alphaDisable) {
+ transform._alphaDisable = true;
}
- renderer->drawSurface(this, _surface, &srcRect, &position, mirrorX, mirrorY, !hasAlpha);
-
+ renderer->drawSurface(this, _surface, &srcRect, &position, transform);
return STATUS_OK;
}
@@ -434,11 +451,15 @@ bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAl
_loaded = true;
_surface->free();
_surface->copyFrom(surface);
- _hasAlpha = hasAlpha;
+ if (hasAlpha) {
+ _alphaType = TransparentSurface::ALPHA_FULL;
+ } else {
+ _alphaType = TransparentSurface::ALPHA_OPAQUE;
+ }
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
renderer->invalidateTicketsFromSurface(this);
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 9091ec65b1..6cf19d00fb 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -30,6 +30,7 @@
#define WINTERMUTE_BASE_SURFACESDL_H
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transparent_surface.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "common/list.h"
@@ -51,12 +52,12 @@ public:
bool endPixelOp() override;
- bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
- bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
- bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) override;
+ bool displayTransZoom(int x, int y, Rect32 rect, int32 zoomX, int32 zoomY, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+ bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+ bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) override;
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 = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
- bool displayTransform(int x, int y, int hotX, int hotY, Rect32 Rect, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+ bool displayZoom(int x, int y, Rect32 rect, int32 zoomX, int32 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 putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
@@ -81,20 +82,22 @@ public:
return _height;
}
+ TransparentSurface::AlphaType getAlphaType() const { return _alphaType; }
private:
Graphics::Surface *_surface;
bool _loaded;
bool finishLoad();
- bool drawSprite(int x, int y, Rect32 *rect, float zoomX, float zoomY, uint32 alpha, bool alphaDisable, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX = 0, int offsetY = 0);
+ bool drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transformStruct);
void genAlphaMask(Graphics::Surface *surface);
uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
- bool _hasAlpha;
+ uint32 _rotation;
+ TransparentSurface::AlphaType _alphaType;
void *_lockPixels;
int _lockPitch;
byte *_alphaMask;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 36c5d7b740..b1720c1b0b 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -26,22 +26,23 @@
* Copyright (c) 2011 Jan Nedoma
*/
-#include "engines/wintermute/graphics/transparent_surface.h"
+
#include "engines/wintermute/base/gfx/osystem/render_ticket.h"
+#include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h"
+#include "engines/wintermute/graphics/transform_tools.h"
+#include "common/textconsole.h"
namespace Wintermute {
-RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha) : _owner(owner),
-_srcRect(*srcRect), _dstRect(*dstRect), _drawNum(0), _isValid(true), _wantsDraw(true), _hasAlpha(!disableAlpha) {
- _colorMod = 0;
+RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct transform) :
+ _owner(owner),
+ _srcRect(*srcRect),
+ _dstRect(*dstRect),
+ _drawNum(0),
+ _isValid(true),
+ _wantsDraw(true),
+ _transform(transform) {
_batchNum = 0;
- _mirror = TransparentSurface::FLIP_NONE;
- if (mirrorX) {
- _mirror |= TransparentSurface::FLIP_V;
- }
- if (mirrorY) {
- _mirror |= TransparentSurface::FLIP_H;
- }
if (surf) {
_surface = new Graphics::Surface();
_surface->create((uint16)srcRect->width(), (uint16)srcRect->height(), surf->format);
@@ -51,7 +52,13 @@ _srcRect(*srcRect), _dstRect(*dstRect), _drawNum(0), _isValid(true), _wantsDraw(
memcpy(_surface->getBasePtr(0, i), surf->getBasePtr(srcRect->left, srcRect->top + i), srcRect->width() * _surface->format.bytesPerPixel);
}
// Then scale it if necessary
- if (dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) {
+ 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()) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
_surface->free();
@@ -60,6 +67,14 @@ _srcRect(*srcRect), _dstRect(*dstRect), _drawNum(0), _isValid(true), _wantsDraw(
}
} 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);
+ }
}
}
@@ -70,32 +85,37 @@ RenderTicket::~RenderTicket() {
}
}
-bool RenderTicket::operator==(RenderTicket &t) {
+bool RenderTicket::operator==(const RenderTicket &t) const {
if ((t._owner != _owner) ||
(t._batchNum != _batchNum) ||
- (t._hasAlpha != _hasAlpha) ||
- (t._mirror != _mirror) ||
- (t._colorMod != _colorMod) ||
+ (t._transform != _transform) ||
(t._dstRect != _dstRect) ||
- (t._srcRect != _srcRect)) {
+ (t._srcRect != _srcRect)
+ ) {
return false;
}
return true;
}
// Replacement for SDL2's SDL_RenderCopy
-void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) {
+void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
TransparentSurface src(*getSurface(), false);
Common::Rect clipRect;
clipRect.setWidth(getSurface()->w);
clipRect.setHeight(getSurface()->h);
- src._enableAlphaBlit = _hasAlpha;
- src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _mirror, &clipRect, _colorMod, clipRect.width(), clipRect.height());
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
+ 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) {
+void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
TransparentSurface src(*getSurface(), false);
bool doDelete = false;
if (!clipRect) {
@@ -105,11 +125,17 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
clipRect->setHeight(getSurface()->h);
}
- src._enableAlphaBlit = _hasAlpha;
- src.blit(*_targetSurface, dstRect->left, dstRect->top, _mirror, clipRect, _colorMod, clipRect->width(), clipRect->height());
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
+ src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
if (doDelete) {
delete clipRect;
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h
index 968b42b5e1..875102d01c 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.h
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.h
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -29,22 +29,36 @@
#ifndef WINTERMUTE_RENDER_TICKET_H
#define WINTERMUTE_RENDER_TICKET_H
+#include "engines/wintermute/graphics/transparent_surface.h"
#include "graphics/surface.h"
#include "common/rect.h"
namespace Wintermute {
class BaseSurfaceOSystem;
+/**
+ * A single RenderTicket.
+ * A render ticket is a collection of the data and draw specifications made
+ * for a single draw-call in the OSystem-backend for WME. The ticket additionally
+ * holds the order in which this call was made, so that it can be detected if
+ * the same call is done in the following frame. Thus allowing us to potentially
+ * skip drawing the same region again, unless anything has changed. Since a surface
+ * can have a potentially large amount of draw-calls made to it, at varying rotation,
+ * zoom, and crop-levels we also need to hold a copy of the necessary data.
+ * (Video-surfaces may even change their data). The promise that is made when a ticket
+ * is created is that what the state was of the surface at THAT point, is what will end
+ * up on screen at flip() time.
+ */
class RenderTicket {
public:
- RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, bool mirrorX = false, bool mirrorY = false, bool disableAlpha = false);
- RenderTicket() : _isValid(true), _wantsDraw(false), _drawNum(0) {}
+ 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();
- const Graphics::Surface *getSurface() { return _surface; }
+ const Graphics::Surface *getSurface() const { return _surface; }
// Non-dirty-rects:
- void drawToSurface(Graphics::Surface *_targetSurface);
+ void drawToSurface(Graphics::Surface *_targetSurface) const;
// Dirty-rects:
- void drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect);
+ void drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const;
Common::Rect _dstRect;
uint32 _batchNum;
@@ -52,18 +66,17 @@ public:
bool _isValid;
bool _wantsDraw;
uint32 _drawNum;
- uint32 _colorMod;
+ TransformStruct _transform;
+
BaseSurfaceOSystem *_owner;
- bool operator==(RenderTicket &a);
- const Common::Rect *getSrcRect() { return &_srcRect; }
+ bool operator==(const RenderTicket &a) const;
+ const Common::Rect *getSrcRect() const { return &_srcRect; }
private:
Graphics::Surface *_surface;
Common::Rect _srcRect;
- bool _hasAlpha;
- uint32 _mirror;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/particles/part_emitter.cpp b/engines/wintermute/base/particles/part_emitter.cpp
index c86e1ce369..aaffa0965a 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -1163,12 +1163,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_angle1));
persistMgr->transfer(TMEMBER(_angle2));
- persistMgr->transfer(TMEMBER(_velocity1));
- persistMgr->transfer(TMEMBER(_velocity2));
+ persistMgr->transferFloat(TMEMBER(_velocity1));
+ persistMgr->transferFloat(TMEMBER(_velocity2));
persistMgr->transfer(TMEMBER(_velocityZBased));
- persistMgr->transfer(TMEMBER(_scale1));
- persistMgr->transfer(TMEMBER(_scale2));
+ persistMgr->transferFloat(TMEMBER(_scale1));
+ persistMgr->transferFloat(TMEMBER(_scale2));
persistMgr->transfer(TMEMBER(_scaleZBased));
persistMgr->transfer(TMEMBER(_maxParticles));
@@ -1196,14 +1196,14 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha2));
persistMgr->transfer(TMEMBER(_alphaTimeBased));
- persistMgr->transfer(TMEMBER(_angVelocity1));
- persistMgr->transfer(TMEMBER(_angVelocity2));
+ persistMgr->transferFloat(TMEMBER(_angVelocity1));
+ persistMgr->transferFloat(TMEMBER(_angVelocity2));
- persistMgr->transfer(TMEMBER(_rotation1));
- persistMgr->transfer(TMEMBER(_rotation2));
+ persistMgr->transferFloat(TMEMBER(_rotation1));
+ persistMgr->transferFloat(TMEMBER(_rotation2));
- persistMgr->transfer(TMEMBER(_growthRate1));
- persistMgr->transfer(TMEMBER(_growthRate2));
+ persistMgr->transferFloat(TMEMBER(_growthRate1));
+ persistMgr->transferFloat(TMEMBER(_growthRate2));
persistMgr->transfer(TMEMBER(_exponentialGrowth));
persistMgr->transfer(TMEMBER(_useRegion));
@@ -1252,4 +1252,4 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/particles/part_emitter.h b/engines/wintermute/base/particles/part_emitter.h
index a0d701f338..94b4dc8126 100644
--- a/engines/wintermute/base/particles/part_emitter.h
+++ b/engines/wintermute/base/particles/part_emitter.h
@@ -135,6 +135,6 @@ private:
BaseArray<char *> _sprites;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/particles/part_force.cpp b/engines/wintermute/base/particles/part_force.cpp
index df84162504..122cdf1afe 100644
--- a/engines/wintermute/base/particles/part_force.cpp
+++ b/engines/wintermute/base/particles/part_force.cpp
@@ -62,4 +62,4 @@ bool PartForce::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/particles/part_force.h b/engines/wintermute/base/particles/part_force.h
index 27f4cb7d90..cdb1ce40f9 100644
--- a/engines/wintermute/base/particles/part_force.h
+++ b/engines/wintermute/base/particles/part_force.h
@@ -52,6 +52,6 @@ public:
bool persist(BasePersistenceManager *PersistMgr);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/particles/part_particle.cpp b/engines/wintermute/base/particles/part_particle.cpp
index f1aba114de..86cacacb5c 100644
--- a/engines/wintermute/base/particles/part_particle.cpp
+++ b/engines/wintermute/base/particles/part_particle.cpp
@@ -234,9 +234,9 @@ bool PartParticle::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha2));
persistMgr->transfer(TMEMBER(_border));
persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_posZ));
+ persistMgr->transferFloat(TMEMBER(_posZ));
persistMgr->transfer(TMEMBER(_velocity));
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transfer(TMEMBER(_creationTime));
persistMgr->transfer(TMEMBER(_lifeTime));
persistMgr->transfer(TMEMBER(_isDead));
@@ -244,9 +244,9 @@ bool PartParticle::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_fadeStart));
persistMgr->transfer(TMEMBER(_fadeTime));
persistMgr->transfer(TMEMBER(_currentAlpha));
- persistMgr->transfer(TMEMBER(_angVelocity));
- persistMgr->transfer(TMEMBER(_rotation));
- persistMgr->transfer(TMEMBER(_growthRate));
+ persistMgr->transferFloat(TMEMBER(_angVelocity));
+ persistMgr->transferFloat(TMEMBER(_rotation));
+ persistMgr->transferFloat(TMEMBER(_growthRate));
persistMgr->transfer(TMEMBER(_exponentialGrowth));
persistMgr->transfer(TMEMBER(_fadeStartAlpha));
@@ -266,4 +266,4 @@ bool PartParticle::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/particles/part_particle.h b/engines/wintermute/base/particles/part_particle.h
index 8cca6b4057..281d87cf72 100644
--- a/engines/wintermute/base/particles/part_particle.h
+++ b/engines/wintermute/base/particles/part_particle.h
@@ -85,6 +85,6 @@ private:
int32 _fadeStartAlpha;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/save_thumb_helper.cpp b/engines/wintermute/base/save_thumb_helper.cpp
index bab29c5cf8..77514849a6 100644
--- a/engines/wintermute/base/save_thumb_helper.cpp
+++ b/engines/wintermute/base/save_thumb_helper.cpp
@@ -56,23 +56,23 @@ BaseImage *SaveThumbHelper::storeThumb(bool doFlip, int width, int height) {
// works normally for direct3d
_gameRef->displayContent(false);
_gameRef->_renderer->flip();
-
+
_gameRef->displayContent(false);
_gameRef->_renderer->flip();
}
-
+
BaseImage *screenshot = _gameRef->_renderer->takeScreenshot();
if (!screenshot) {
return nullptr;
}
-
+
// normal thumbnail
if (_gameRef->getSaveThumbWidth() > 0 && _gameRef->getSaveThumbHeight() > 0) {
thumbnail = new BaseImage();
thumbnail->copyFrom(screenshot, width, height);
}
-
-
+
+
delete screenshot;
screenshot = nullptr;
}
@@ -99,7 +99,7 @@ bool SaveThumbHelper::storeThumbnail(bool doFlip) {
bool SaveThumbHelper::storeScummVMThumbNail(bool doFlip) {
delete _scummVMThumb;
_scummVMThumb = nullptr;
-
+
_scummVMThumb = storeThumb(doFlip, kThumbnailWidth, kThumbnailHeight2);
if (!_scummVMThumb) {
return STATUS_FAILED;
@@ -107,4 +107,4 @@ bool SaveThumbHelper::storeScummVMThumbNail(bool doFlip) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/save_thumb_helper.h b/engines/wintermute/base/save_thumb_helper.h
index d3bc5f5523..44792e3d75 100644
--- a/engines/wintermute/base/save_thumb_helper.h
+++ b/engines/wintermute/base/save_thumb_helper.h
@@ -47,6 +47,6 @@ private:
BaseGame *_gameRef;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/saveload.cpp b/engines/wintermute/base/saveload.cpp
index 1b7dfd42ed..8d37909bb4 100644
--- a/engines/wintermute/base/saveload.cpp
+++ b/engines/wintermute/base/saveload.cpp
@@ -201,4 +201,4 @@ bool SaveLoad::emptySaveSlot(int slot) {
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/saveload.h b/engines/wintermute/base/saveload.h
index 722f7a89b6..15d4d86b26 100644
--- a/engines/wintermute/base/saveload.h
+++ b/engines/wintermute/base/saveload.h
@@ -52,6 +52,6 @@ private:
static void afterLoadScript(void *script, void *data);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/dcscript.h b/engines/wintermute/base/scriptables/dcscript.h
index 4aae897dc2..d6bb3cd176 100644
--- a/engines/wintermute/base/scriptables/dcscript.h
+++ b/engines/wintermute/base/scriptables/dcscript.h
@@ -136,6 +136,6 @@ typedef enum {
ELEMENT_STRING = 0
} TElementType;
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp
index 1b945c2e1c..5aeff78c50 100644
--- a/engines/wintermute/base/scriptables/script.cpp
+++ b/engines/wintermute/base/scriptables/script.cpp
@@ -461,6 +461,7 @@ void ScScript::cleanup() {
_parentScript = nullptr; // ref only
delete _scriptStream;
+ _scriptStream = nullptr;
}
@@ -1464,4 +1465,4 @@ void ScScript::afterLoad() {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h
index ee9f45e204..488ff63606 100644
--- a/engines/wintermute/base/scriptables/script.h
+++ b/engines/wintermute/base/scriptables/script.h
@@ -169,6 +169,6 @@ public:
virtual const char *dbgGetFilename();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_engine.cpp b/engines/wintermute/base/scriptables/script_engine.cpp
index f83fb36843..bb819b23e4 100644
--- a/engines/wintermute/base/scriptables/script_engine.cpp
+++ b/engines/wintermute/base/scriptables/script_engine.cpp
@@ -362,6 +362,8 @@ bool ScEngine::tick() {
//////////////////////////////////////////////////////////////////////////
bool ScEngine::tickUnbreakable() {
+ ScScript *oldScript = _currentScript;
+
// execute unbreakable scripts
for (uint32 i = 0; i < _scripts.size(); i++) {
if (!_scripts[i]->_unbreakable) {
@@ -373,9 +375,12 @@ bool ScEngine::tickUnbreakable() {
_scripts[i]->executeInstruction();
}
_scripts[i]->finish();
- _currentScript = nullptr;
+ _currentScript = oldScript;
}
- removeFinishedScripts();
+
+ // NB: Don't remove finished scripts here since we could be recursively
+ // executing scripts. Doing so could invalidate the outer iteration in
+ // ::tick() over _scripts.
return STATUS_OK;
}
@@ -605,4 +610,4 @@ void ScEngine::dumpStats() {
}*/
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_engine.h b/engines/wintermute/base/scriptables/script_engine.h
index 639875ffb6..622b3c4b94 100644
--- a/engines/wintermute/base/scriptables/script_engine.h
+++ b/engines/wintermute/base/scriptables/script_engine.h
@@ -130,6 +130,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_array.cpp b/engines/wintermute/base/scriptables/script_ext_array.cpp
index a466d361ec..7f1c769ec5 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -249,4 +249,4 @@ bool SXArray::push(ScValue *val) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_array.h b/engines/wintermute/base/scriptables/script_ext_array.h
index 68f808641e..e6381a011e 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.h
+++ b/engines/wintermute/base/scriptables/script_ext_array.h
@@ -51,6 +51,6 @@ private:
Common::String _strRep;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_date.cpp b/engines/wintermute/base/scriptables/script_ext_date.cpp
index afca0c4bbf..d88bfc5851 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_date.cpp
@@ -307,4 +307,4 @@ int SXDate::scCompare(BaseScriptable *Value) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_date.h b/engines/wintermute/base/scriptables/script_ext_date.h
index 062b7c55c7..0ccf093a7b 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.h
+++ b/engines/wintermute/base/scriptables/script_ext_date.h
@@ -49,6 +49,6 @@ private:
Common::String _strRep;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_file.cpp b/engines/wintermute/base/scriptables/script_ext_file.cpp
index 29e032a759..18f7b8213a 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_file.cpp
@@ -825,4 +825,4 @@ Common::WriteStream *SXFile::openForAppend(const Common::String &filename, bool
error("SXFile::openForAppend - WriteFiles not supported");
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_file.h b/engines/wintermute/base/scriptables/script_ext_file.h
index fa2384109f..a1298929f2 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.h
+++ b/engines/wintermute/base/scriptables/script_ext_file.h
@@ -61,6 +61,6 @@ private:
Common::WriteStream *openForAppend(const Common::String &filename, bool binary);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_math.cpp b/engines/wintermute/base/scriptables/script_ext_math.cpp
index f4c6be2d6c..ec53b983e7 100644
--- a/engines/wintermute/base/scriptables/script_ext_math.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_math.cpp
@@ -291,4 +291,4 @@ bool SXMath::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_math.h b/engines/wintermute/base/scriptables/script_ext_math.h
index 48c43ea7e8..1aa274a96f 100644
--- a/engines/wintermute/base/scriptables/script_ext_math.h
+++ b/engines/wintermute/base/scriptables/script_ext_math.h
@@ -48,6 +48,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
index 9de9905fea..6a47c09136 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
@@ -526,4 +526,4 @@ int SXMemBuffer::scCompare(BaseScriptable *val) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.h b/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
index 6700a03f50..4aad8b6484 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.h
@@ -55,6 +55,6 @@ private:
bool checkBounds(ScScript *script, int start, int length);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_object.cpp b/engines/wintermute/base/scriptables/script_ext_object.cpp
index b87aac81f9..a72b244f0a 100644
--- a/engines/wintermute/base/scriptables/script_ext_object.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_object.cpp
@@ -64,4 +64,4 @@ bool SXObject::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_object.h b/engines/wintermute/base/scriptables/script_ext_object.h
index c85d16d44e..566111292a 100644
--- a/engines/wintermute/base/scriptables/script_ext_object.h
+++ b/engines/wintermute/base/scriptables/script_ext_object.h
@@ -41,6 +41,6 @@ public:
virtual ~SXObject();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_ext_string.cpp b/engines/wintermute/base/scriptables/script_ext_string.cpp
index 7cb3b9360b..2f2422cdf9 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -430,4 +430,4 @@ int SXString::scCompare(BaseScriptable *val) {
return strcmp(_string, ((SXString *)val)->_string);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_ext_string.h b/engines/wintermute/base/scriptables/script_ext_string.h
index 50b61deba4..7a95c59b4c 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.h
+++ b/engines/wintermute/base/scriptables/script_ext_string.h
@@ -53,6 +53,6 @@ private:
int32 _capacity;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_stack.cpp b/engines/wintermute/base/scriptables/script_stack.cpp
index b53457c81b..801ac6ab52 100644
--- a/engines/wintermute/base/scriptables/script_stack.cpp
+++ b/engines/wintermute/base/scriptables/script_stack.cpp
@@ -192,4 +192,4 @@ bool ScStack::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_stack.h b/engines/wintermute/base/scriptables/script_stack.h
index 82c3debefa..ee04485a51 100644
--- a/engines/wintermute/base/scriptables/script_stack.h
+++ b/engines/wintermute/base/scriptables/script_stack.h
@@ -61,6 +61,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 5e2923e029..31ec457df1 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -827,6 +827,17 @@ bool ScValue::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_valRef));
persistMgr->transfer(TMEMBER(_valString));
+ if (!persistMgr->getIsSaving() && !persistMgr->checkVersion(1,2,2)) {
+ // Savegames prior to 1.2.2 stored empty strings as NULL.
+ // We disambiguate those by turning NULL strings into empty
+ // strings if _type is VAL_STRING instead of VAL_NULL.
+
+ if (_type == VAL_STRING && !_valString) {
+ _valString = new char[1];
+ _valString[0] = '\0';
+ }
+ }
+
/* // TODO: Convert to Debug-statements.
FILE* f = fopen("c:\\val.log", "a+");
switch(_type)
@@ -992,4 +1003,4 @@ bool ScValue::setProperty(const char *propName) {
return ret;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/script_value.h b/engines/wintermute/base/scriptables/script_value.h
index a8e815023e..90ad9f182a 100644
--- a/engines/wintermute/base/scriptables/script_value.h
+++ b/engines/wintermute/base/scriptables/script_value.h
@@ -108,6 +108,6 @@ public:
bool setProperty(const char *propName);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/sound/base_sound.cpp b/engines/wintermute/base/sound/base_sound.cpp
index d027c03c8b..c1923b3ca8 100644
--- a/engines/wintermute/base/sound/base_sound.cpp
+++ b/engines/wintermute/base/sound/base_sound.cpp
@@ -289,4 +289,4 @@ bool BaseSound::applyFX(TSFXType type, float param1, float param2, float param3,
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/sound/base_sound.h b/engines/wintermute/base/sound/base_sound.h
index 3412e6c3a3..0a984d240a 100644
--- a/engines/wintermute/base/sound/base_sound.h
+++ b/engines/wintermute/base/sound/base_sound.h
@@ -82,6 +82,6 @@ private:
BaseSoundBuffer *_sound;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/sound/base_sound_buffer.cpp b/engines/wintermute/base/sound/base_sound_buffer.cpp
index 9c919abac6..7666a441a3 100644
--- a/engines/wintermute/base/sound/base_sound_buffer.cpp
+++ b/engines/wintermute/base/sound/base_sound_buffer.cpp
@@ -292,4 +292,4 @@ bool BaseSoundBuffer::applyFX(TSFXType type, float param1, float param2, float p
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/sound/base_sound_buffer.h b/engines/wintermute/base/sound/base_sound_buffer.h
index e78d062cd4..53b86f64c6 100644
--- a/engines/wintermute/base/sound/base_sound_buffer.h
+++ b/engines/wintermute/base/sound/base_sound_buffer.h
@@ -95,6 +95,6 @@ private:
int32 _volume;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/sound/base_sound_manager.cpp b/engines/wintermute/base/sound/base_sound_manager.cpp
index f3e7bfb408..68e62f25b0 100644
--- a/engines/wintermute/base/sound/base_sound_manager.cpp
+++ b/engines/wintermute/base/sound/base_sound_manager.cpp
@@ -287,4 +287,4 @@ float BaseSoundMgr::posToPan(int x, int y) {
return minPan + relPos * (maxPan - minPan);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/sound/base_sound_manager.h b/engines/wintermute/base/sound/base_sound_manager.h
index 602571765f..5993a05001 100644
--- a/engines/wintermute/base/sound/base_sound_manager.h
+++ b/engines/wintermute/base/sound/base_sound_manager.h
@@ -64,6 +64,6 @@ private:
bool setMasterVolume(byte percent);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/base/timer.cpp b/engines/wintermute/base/timer.cpp
index 5dfc117f48..96097c10d5 100644
--- a/engines/wintermute/base/timer.cpp
+++ b/engines/wintermute/base/timer.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/engines/wintermute/base/timer.h b/engines/wintermute/base/timer.h
index ec5477ba2e..4099c6c825 100644
--- a/engines/wintermute/base/timer.h
+++ b/engines/wintermute/base/timer.h
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -51,7 +51,7 @@ public:
void persist(BasePersistenceManager *persistMgr);
};
-
+
} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/coll_templ.h b/engines/wintermute/coll_templ.h
index 4a8e92c121..a3df92d6c8 100644
--- a/engines/wintermute/coll_templ.h
+++ b/engines/wintermute/coll_templ.h
@@ -138,6 +138,6 @@ public:
}
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/dcgf.h b/engines/wintermute/dcgf.h
index fe92194443..3db443965e 100644
--- a/engines/wintermute/dcgf.h
+++ b/engines/wintermute/dcgf.h
@@ -33,7 +33,7 @@
//////////////////////////////////////////////////////////////////////////
#define DCGF_VER_MAJOR 1
#define DCGF_VER_MINOR 2
-#define DCGF_VER_BUILD 1
+#define DCGF_VER_BUILD 2
#define DCGF_VER_SUFFIX "ScummVM"
#define DCGF_VER_BETA true
diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h
index bd4966eb6b..b40322147f 100644
--- a/engines/wintermute/dctypes.h
+++ b/engines/wintermute/dctypes.h
@@ -220,6 +220,6 @@ enum TShadowType {
SHADOW_STENCIL = 3
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp
index 92b8e6251f..8c8b8255ab 100644
--- a/engines/wintermute/debugger.cpp
+++ b/engines/wintermute/debugger.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -81,4 +81,4 @@ bool Console::Cmd_DumpFile(int argc, const char **argv) {
return true;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger.h b/engines/wintermute/debugger.h
index 588b81af97..6fbbb084f0 100644
--- a/engines/wintermute/debugger.h
+++ b/engines/wintermute/debugger.h
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -32,7 +32,7 @@ class Console : public GUI::Debugger {
public:
Console(WintermuteEngine *vm);
virtual ~Console();
-
+
bool Cmd_ShowFps(int argc, const char **argv);
bool Cmd_DumpFile(int argc, const char **argv);
private:
diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp
index 1bf2c76a50..ac21d78ef5 100644
--- a/engines/wintermute/detection.cpp
+++ b/engines/wintermute/detection.cpp
@@ -181,7 +181,7 @@ public:
}
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#if PLUGIN_ENABLED_DYNAMIC(WINTERMUTE)
REGISTER_PLUGIN_DYNAMIC(WINTERMUTE, PLUGIN_TYPE_ENGINE, Wintermute::WintermuteMetaEngine);
diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h
index 09426c9307..63f5078c12 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -40,17 +40,23 @@ static const PlainGameDescriptor wintermuteGames[] = {
{"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"},
{"dirtysplit", "Dirty Split"},
{"dreamscape", "Dreamscape"},
+ {"escapemansion", "Escape from the Mansion"},
{"ghostsheet", "Ghost in the Sheet"},
{"hamlet", "Hamlet or the last game without MMORPS features, shaders and product placement"},
- {"jamesperis", "James Peris: No License Nor Control"},
+ {"jamesperis", "James Peris: No License Nor Control"},
+ {"looky", "Looky"},
{"julia", "J.U.L.I.A."},
{"mirage", "Mirage"},
{"pigeons", "Pigeons in the Park"},
{"reversion1", "Reversion: The Escape"},
{"reversion2", "Reversion: The Meeting"},
{"rosemary", "Rosemary"},
+ {"shaban", "Shaban"},
+ {"shinestar", "The Shine of a Star"},
+ {"spacemadness", "Space Madness"},
{"thebox", "The Box"},
- {"tradestory", "The Trader of Stories"},
+ {"tib", "Fairy Tales About Toshechka and Boshechka"},
+ {"tradestory", "The Trader of Stories"},
{"twc", "the white chamber"},
{"wintermute", "Wintermute engine game"},
{0, 0}
@@ -139,6 +145,17 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Carol Reed 7 - Blue Madonna (Demo)
+ {
+ "carolreed7",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "0372ad0c775266f6355e9e8ae397a2f1", 103719442),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// Carol Reed 7 - Blue Madonna
{
"carolreed7",
@@ -271,6 +288,26 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 1",
+ AD_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 2",
+ AD_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Ghosts in the Sheet
{
"ghostsheet",
@@ -292,12 +329,43 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
- // James Peris: No License Nor Control
+ // James Peris: No License Nor Control (English)
+ {
+ "jamesperis",
+ "",
+ AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // James Peris: No License Nor Control (Spanish)
+ {
+ "jamesperis",
+ "",
+ AD_ENTRY1s("data.dcp", "a420961e170cb7d168a0d2bae2fe5218", 225294032),
+ Common::ES_ESP,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // James Peris: No License Nor Control (Demo) (English)
+ {
+ "jamesperis",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // James Peris: No License Nor Control (Demo) (Spanish)
{
"jamesperis",
"Demo",
AD_ENTRY1s("data.dcp", "edb9f9c7a08993c1e28f4e477b5f9830", 116113507),
- Common::UNK_LANG, // No solution in place to select language
+ Common::ES_ESP,
Common::kPlatformWindows,
ADGF_UNSTABLE |
ADGF_DEMO,
@@ -335,6 +403,48 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO0()
},
+ // Looky Demo (English)
+ {
+ "looky",
+ "Demo",
+ {
+ {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky Demo (German)
+ {
+ "looky",
+ "Demo",
+ {
+ {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky (German)
+ {
+ "looky",
+ "",
+ {
+ {"german.dcp", 0, "bf4c2b8c26342342441a6d64934ab832", 107027865},
+ {"data.dcp", 0, "50de0beaa5ad621aa9f020df901d1e74", 1342214},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Mirage
{
"mirage",
@@ -581,6 +691,36 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Shaban
+ {
+ "shaban",
+ "",
+ AD_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // The Shine of a Star
+ {
+ "shinestar",
+ "",
+ AD_ENTRY1s("data.dcp", "f05abe9e2427a5e4f73648fa09c4ba8e", 94113060),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Space Madness
+ {
+ "spacemadness",
+ "1.0.2",
+ AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Box
{
"thebox",
@@ -591,6 +731,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Fairy Tales About Toshechka and Boshechka
+ {
+ "tib",
+ "",
+ AD_ENTRY1s("data.dcp", "87d296ef3f46570ed18f000d3885db77", 340264526),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Trader of Stories
{
"tradestory",
diff --git a/engines/wintermute/graphics/transform_struct.cpp b/engines/wintermute/graphics/transform_struct.cpp
new file mode 100644
index 0000000000..8edbf765b5
--- /dev/null
+++ b/engines/wintermute/graphics/transform_struct.cpp
@@ -0,0 +1,93 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/wintermute/graphics/transform_struct.h"
+#include "engines/wintermute/graphics/transparent_surface.h"
+
+namespace Wintermute {
+void TransformStruct::init(Point32 zoom, uint32 angle, Point32 hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, Point32 offset) {
+ _zoom = zoom;
+ _angle = angle;
+ _hotspot = hotspot;
+ _blendMode = blendMode;
+ _rgbaMod = rgbaMod;
+ _alphaDisable = alphaDisable;
+ _flip = 0;
+ _flip += TransparentSurface::FLIP_H * mirrorX;
+ _flip += TransparentSurface::FLIP_V * mirrorY;
+ _offset = offset;
+}
+
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
+ init(Point32(zoomX, zoomY),
+ angle,
+ Point32(hotspotX, hotspotY),
+ false,
+ blendMode,
+ rgbaMod,
+ mirrorX, mirrorY,
+ Point32(offsetX, offsetY));
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY) {
+ init(Point32(zoomX, zoomY),
+ kDefaultAngle,
+ Point32(kDefaultHotspotX, kDefaultHotspotY),
+ false,
+ blendMode,
+ rgbaMod,
+ mirrorX,
+ mirrorY,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY) {
+ init(Point32(zoomX, zoomY),
+ angle,
+ Point32(hotspotX, hotspotY),
+ true,
+ BLEND_NORMAL,
+ kDefaultRgbaMod,
+ false, false,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+TransformStruct::TransformStruct() {
+ init(Point32(kDefaultZoomX, kDefaultZoomY),
+ kDefaultAngle,
+ Point32(kDefaultHotspotX, kDefaultHotspotY),
+ true,
+ BLEND_NORMAL,
+ kDefaultRgbaMod,
+ false, false,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+bool TransformStruct::getMirrorX() const {
+ return (bool)(_flip & TransparentSurface::FLIP_H);
+}
+
+bool TransformStruct::getMirrorY() const {
+ return (bool)(_flip & TransparentSurface::FLIP_V);
+}
+} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
new file mode 100644
index 0000000000..a54c4cc5d0
--- /dev/null
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WINTERMUTE_TRANSFORM_STRUCT_H
+#define WINTERMUTE_TRANSFORM_STRUCT_H
+
+#include "engines/wintermute/math/rect32.h"
+#include "engines/wintermute/dctypes.h"
+
+namespace Wintermute {
+/**
+ * Contains all the required information that define a transform.
+ * Same source sprite + same TransformStruct = Same resulting sprite.
+ * Has a number of overloaded constructors to accomodate various argument lists.
+ */
+
+const uint32 kDefaultZoomX = 100;
+const uint32 kDefaultZoomY = 100;
+const uint32 kDefaultRgbaMod = 0xFFFFFFFF;
+const int32 kDefaultHotspotX = 0;
+const int32 kDefaultHotspotY = 0;
+const int32 kDefaultOffsetX = 0;
+const int32 kDefaultOffsetY = 0;
+const int32 kDefaultAngle = 0;
+
+struct TransformStruct {
+private:
+ void init(Point32 zoom, uint32 angle, Point32 hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX, bool mirrorY, Point32 offset);
+
+public:
+ TransformStruct(int32 zoomX, int32 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();
+
+ Point32 _zoom; ///< Zoom; 100 = no zoom
+ Point32 _hotspot; ///< Position of the hotspot
+ uint32 _angle; ///< Rotation angle, in degrees
+ byte _flip; ///< Bitflag: see TransparentSurface::FLIP_XXX
+ bool _alphaDisable;
+ TSpriteBlendMode _blendMode;
+ uint32 _rgbaMod; ///< RGBa
+ Point32 _offset;
+
+ bool getMirrorX() const;
+ bool getMirrorY() const;
+
+ bool operator==(const TransformStruct &compare) const {
+ return (compare._angle == _angle &&
+ compare._flip == _flip &&
+ compare._zoom == _zoom &&
+ compare._offset == _offset &&
+ compare._alphaDisable == _alphaDisable &&
+ compare._rgbaMod == _rgbaMod &&
+ compare._blendMode == _blendMode
+ );
+ }
+
+ bool operator!=(const TransformStruct &compare) const {
+ return !(compare == *this);
+ }
+};
+} // End of namespace Wintermute
+#endif
diff --git a/engines/wintermute/graphics/transform_tools.cpp b/engines/wintermute/graphics/transform_tools.cpp
new file mode 100644
index 0000000000..ebf9092aaa
--- /dev/null
+++ b/engines/wintermute/graphics/transform_tools.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 "engines/wintermute/graphics/transform_tools.h"
+#include <math.h>
+
+namespace Wintermute {
+
+FloatPoint TransformTools::transformPoint(const FloatPoint &point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) {
+ float rotateRad = rotate * M_PI / 180.0f;
+ 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;
+ if (mirrorX) {
+ newPoint.x *= -1;
+ }
+ if (mirrorY) {
+ newPoint.y *= -1;
+ }
+ return newPoint;
+}
+
+Rect32 TransformTools::newRect(const Rect32 &oldRect, const TransformStruct &transform, Point32 *newHotspot) {
+ Point32 nw(oldRect.left, oldRect.top);
+ Point32 ne(oldRect.right, oldRect.top);
+ Point32 sw(oldRect.left, oldRect.bottom);
+ Point32 se(oldRect.right, oldRect.bottom);
+
+ FloatPoint nw1, ne1, sw1, se1;
+
+ nw1 = transformPoint(nw - transform._hotspot, transform._angle, transform._zoom);
+ ne1 = transformPoint(ne - transform._hotspot, transform._angle, transform._zoom);
+ sw1 = transformPoint(sw - transform._hotspot, transform._angle, transform._zoom);
+ se1 = transformPoint(se - transform._hotspot, transform._angle, transform._zoom);
+
+ float top = MIN(nw1.y, MIN(ne1.y, MIN(sw1.y, se1.y)));
+ float bottom = MAX(nw1.y, MAX(ne1.y, MAX(sw1.y, se1.y)));
+ 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));
+
+ res.top = (int32)(floor(top)) + transform._hotspot.y;
+ res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y;
+ res.left = (int32)(floor(left)) + transform._hotspot.x;
+ res.right = (int32)(ceil(right)) + transform._hotspot.x;
+
+ return res;
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transform_tools.h b/engines/wintermute/graphics/transform_tools.h
new file mode 100644
index 0000000000..c92b81fd11
--- /dev/null
+++ b/engines/wintermute/graphics/transform_tools.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WINTERMUTE_TRANSFORM_TOOLS_H
+#define WINTERMUTE_TRANSFORM_TOOLS_H
+
+#include "engines/wintermute/math/rect32.h"
+#include "engines/wintermute/math/floatpoint.h"
+#include "engines/wintermute/graphics/transform_struct.h"
+
+namespace Wintermute {
+
+class TransformTools {
+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);
+
+ /**
+ * @param &point the point on which the transform is to be applied
+ * @param rotate the angle in degrees
+ * @param &zoom zoom x,y in percent
+ * @param mirrorX flip along the vertical axis?
+ * @param mirrorY flip along the horizontal axis?
+ * @return the smallest rect that can contain the transformed sprite
+ * and, as a side-effect, "newHotspot" will tell you where the hotspot will
+ * have ended up in the new rect, for centering.
+ */
+ static Rect32 newRect(const Rect32 &oldRect, const TransformStruct &transform, Point32 *newHotspot);
+};
+
+} // End of namespace Wintermute
+#endif
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index dcdcbf247e..cd200354f7 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -23,22 +23,126 @@
#include "common/endian.h"
#include "common/util.h"
#include "common/rect.h"
+#include "common/math.h"
#include "common/textconsole.h"
#include "graphics/primitives.h"
#include "engines/wintermute/graphics/transparent_surface.h"
+#include "engines/wintermute/graphics/transform_tools.h"
namespace Wintermute {
-byte *TransparentSurface::_lookup = nullptr;
-void TransparentSurface::destroyLookup() {
- delete[] _lookup;
- _lookup = nullptr;
+#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) {
+ 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) {
+ 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(), _enableAlphaBlit(true) {}
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _enableAlphaBlit(true) {
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
if (copyData) {
copyFrom(surf);
} else {
@@ -46,17 +150,20 @@ TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Sur
h = surf.h;
pitch = surf.pitch;
format = surf.format;
- pixels = surf.pixels;
+ // We need to cast the const qualifier away here because 'pixels'
+ // always needs to be writable. 'surf' however is a constant Surface,
+ // thus getPixels will always return const pixel data.
+ pixels = const_cast<void *>(surf.getPixels());
}
}
-void doBlitOpaque(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
-#else
const int aIndex = 0;
+#else
+ const int aIndex = 3;
#endif
for (uint32 i = 0; i < height; i++) {
@@ -72,42 +179,60 @@ void doBlitOpaque(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pit
}
}
-void TransparentSurface::generateLookup() {
- _lookup = new byte[256 * 256];
- for (int i = 0; i < 256; i++) {
- for (int j = 0; j < 256; j++) {
- _lookup[(i << 8) + j] = (i * j) >> 8;
+void doBlitBinary(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+ byte *in, *out;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ const int aIndex = 0;
+#else
+ const int aIndex = 3;
+#endif
+ const int aShift = 0;//img->format.aShift;
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+ uint32 pix = *(uint32 *)in;
+ int a = (pix >> aShift) & 0xff;
+ in += inStep;
+
+ if (a == 0) { // Full transparency
+ out += 4;
+ } else { // Full opacity (Any value not exactly 0 is Opaque here)
+ *(uint32 *)out = pix;
+ out[aIndex] = 0xFF;
+ out += 4;
+ }
}
+ outo += pitch;
+ ino += inoStep;
}
}
-void TransparentSurface::doBlitAlpha(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in, *out;
- if (!_lookup) {
- generateLookup();
- }
-
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
for (uint32 i = 0; i < height; i++) {
out = outo;
@@ -141,13 +266,9 @@ void TransparentSurface::doBlitAlpha(byte *ino, byte* outo, uint32 width, uint32
default: // alpha blending
outa = 255;
-
- outb = _lookup[(((oPix >> bShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outg = _lookup[(((oPix >> gShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outr = _lookup[(((oPix >> rShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outb += _lookup[b + (a << 8)];
- outg += _lookup[g + (a << 8)];
- outr += _lookup[r + (a << 8)];
+ outb = ((b * a) + ((oPix >> bShiftTarget) & 0xff) * (255-a)) >> 8;
+ outg = ((g * a) + ((oPix >> gShiftTarget) & 0xff) * (255-a)) >> 8;
+ outr = ((r * a) + ((oPix >> rShiftTarget) & 0xff) * (255-a)) >> 8;
out[aIndex] = outa;
out[bIndex] = outb;
@@ -178,14 +299,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
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
TransparentSurface srcImage(*this, false);
// TODO: Is the data really in the screen format?
@@ -195,16 +308,28 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
}
if (pPartRect) {
- srcImage.pixels = &((char *)pixels)[pPartRect->top * srcImage.pitch + pPartRect->left * 4];
+
+ int xOffset = pPartRect->left;
+ int yOffset = pPartRect->top;
+
+ if (flipping & FLIP_V) {
+ yOffset = srcImage.h - pPartRect->bottom;
+ }
+
+ if (flipping & FLIP_H) {
+ xOffset = srcImage.w - pPartRect->right;
+ }
+
+ srcImage.pixels = getBasePtr(xOffset, yOffset);
srcImage.w = pPartRect->width();
srcImage.h = pPartRect->height();
debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
- pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
+ pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
} else {
debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
- srcImage.w, srcImage.h, color, width, height);
+ srcImage.w, srcImage.h, color, width, height);
}
if (width == -1)
@@ -224,7 +349,7 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
if ((width != srcImage.w) || (height != srcImage.h)) {
// Scale the image
img = imgScaled = srcImage.scale(width, height);
- savedPixels = (byte *)img->pixels;
+ savedPixels = (byte *)img->getPixels();
} else {
img = &srcImage;
}
@@ -232,13 +357,13 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
// Handle off-screen clipping
if (posY < 0) {
img->h = MAX(0, (int)img->h - -posY);
- img->pixels = (byte *)img->pixels + img->pitch * -posY;
+ img->setPixels((byte *)img->getBasePtr(0, -posY));
posY = 0;
}
if (posX < 0) {
img->w = MAX(0, (int)img->w - -posX);
- img->pixels = (byte *)img->pixels + (-posX * 4);
+ img->setPixels((byte *)img->getBasePtr(-posX, 0));
posX = 0;
}
@@ -250,12 +375,12 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
int inStep = 4;
int inoStep = img->pitch;
- if (flipping & TransparentSurface::FLIP_V) {
+ if (flipping & TransparentSurface::FLIP_H) {
inStep = -inStep;
xp = img->w - 1;
}
- if (flipping & TransparentSurface::FLIP_H) {
+ if (flipping & TransparentSurface::FLIP_V) {
inoStep = -inoStep;
yp = img->h - 1;
}
@@ -265,29 +390,32 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
+
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
- if (_enableAlphaBlit) {
+ if (_alphaMode == ALPHA_FULL) {
doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else {
+ } else if (_alphaMode == ALPHA_BINARY) {
+ doBlitBinary(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (_alphaMode == ALPHA_OPAQUE) {
doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
}
} else {
@@ -307,7 +435,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
if (ca != 255) {
a = a * ca >> 8;
}
-
switch (a) {
case 0: // Full transparency
out += 4;
@@ -337,27 +464,27 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
default: // alpha blending
outa = 255;
- outb = (o_pix >> bShiftTarget) & 0xff;
- outg = (o_pix >> gShiftTarget) & 0xff;
- outr = (o_pix >> rShiftTarget) & 0xff;
+ outb = ((o_pix >> bShiftTarget) & 0xff) * (255 - a);
+ outg = ((o_pix >> gShiftTarget) & 0xff) * (255 - a);
+ outr = ((o_pix >> rShiftTarget) & 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;
out[aIndex] = outa;
out[bIndex] = outb;
out[gIndex] = outg;
@@ -375,7 +502,7 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
retSize.setHeight(img->h);
if (imgScaled) {
- imgScaled->pixels = savedPixels;
+ imgScaled->setPixels(savedPixels);
imgScaled->free();
delete imgScaled;
}
@@ -383,16 +510,54 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
return retSize;
}
+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.
+
+ Point32 newHotspot;
+ Common::Rect srcRect(0, 0, (int16)w, (int16)h);
+ Rect32 rect = TransformTools::newRect(Rect32(srcRect), transform, &newHotspot);
+ Common::Rect dstRect(0, 0, (int16)(rect.right - rect.left), (int16)(rect.bottom - rect.top));
+
+ TransparentSurface *target = new TransparentSurface();
+ assert(format.bytesPerPixel == 4);
+
+ int dstW = dstRect.width();
+ int dstH = dstRect.height();
+
+ target->create((uint16)dstW, (uint16)dstH, this->format);
+
+ 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;
+
+ targX = ((x1 * invCos - y1 * invSin)) * kDefaultZoomX / transform._zoom.x + srcRect.left;
+ targY = ((x1 * invSin + y1 * invCos)) * kDefaultZoomY / transform._zoom.y + srcRect.top;
+
+ targX += transform._hotspot.x;
+ targY += transform._hotspot.y;
+
+#if ENABLE_BILINEAR
+ copyPixelBilinear(targX, targY, x, y, srcRect, dstRect, this, target);
+#else
+ copyPixelNearestNeighbor(targX, targY, x, y, srcRect, dstRect, this, target);
+#endif
+ }
+ }
+ return target;
+}
+
TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) const {
Common::Rect srcRect(0, 0, (int16)w, (int16)h);
Common::Rect dstRect(0, 0, (int16)newWidth, (int16)newHeight);
- return scale(srcRect, dstRect);
-}
-// Copied from clone2727's https://github.com/clone2727/scummvm/blob/pegasus/engines/pegasus/surface.cpp#L247
-TransparentSurface *TransparentSurface::scale(const Common::Rect &srcRect, const Common::Rect &dstRect) const {
- // I'm doing simple linear scaling here
- // dstRect(x, y) = srcRect(x * srcW / dstW, y * srcH / dstH);
TransparentSurface *target = new TransparentSurface();
assert(format.bytesPerPixel == 4);
@@ -404,11 +569,18 @@ TransparentSurface *TransparentSurface::scale(const Common::Rect &srcRect, const
target->create((uint16)dstW, (uint16)dstH, this->format);
+
+ float projX;
+ float projY;
for (int y = 0; y < dstH; y++) {
for (int x = 0; x < dstW; x++) {
- uint32 color = READ_UINT32((const byte *)getBasePtr(x * srcW / dstW + srcRect.left,
- y * srcH / dstH + srcRect.top));
- WRITE_UINT32((byte *)target->getBasePtr(x + dstRect.left, y + dstRect.top), color);
+ 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
}
}
return target;
@@ -440,4 +612,4 @@ void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool
}
}
-} // End of namespace Graphics
+} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index dc079a1fbc..598aaa55d7 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -23,6 +23,10 @@
#define GRAPHICS_TRANSPARENTSURFACE_H
#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
@@ -49,24 +53,35 @@ struct TransparentSurface : public Graphics::Surface {
void setColorKey(char r, char g, char b);
void disableColorKey();
+#if ENABLE_BILINEAR
+ 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
+ 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.
*/
enum FLIP_FLAGS {
- /// The image will not be flipped.
- FLIP_NONE = 0,
- /// The image will be flipped at the horizontal axis.
- FLIP_H = 1,
- /// The image will be flipped at the vertical axis.
- FLIP_V = 2,
- /// The image will be flipped at the horizontal and vertical axis.
- FLIP_HV = FLIP_H | FLIP_V,
- /// The image will be flipped at the horizontal and vertical axis.
- FLIP_VH = FLIP_H | FLIP_V
+ /// The image will not be flipped.
+ FLIP_NONE = 0,
+ /// The image will be flipped at the horizontal axis.
+ FLIP_H = 1,
+ /// The image will be flipped at the vertical axis.
+ FLIP_V = 2,
+ /// The image will be flipped at the horizontal and vertical axis.
+ FLIP_HV = FLIP_H | FLIP_V,
+ /// The image will be flipped at the horizontal and vertical axis.
+ FLIP_VH = FLIP_H | FLIP_V
};
- bool _enableAlphaBlit;
+ enum AlphaType {
+ ALPHA_OPAQUE = 0,
+ ALPHA_BINARY = 1,
+ ALPHA_FULL = 2
+ };
+
+ AlphaType _alphaMode;
/**
@brief renders the surface to another surface
@@ -102,14 +117,9 @@ struct TransparentSurface : public Graphics::Surface {
uint color = BS_ARGB(255, 255, 255, 255),
int width = -1, int height = -1);
void applyColorKey(uint8 r, uint8 g, uint8 b, bool overwriteAlpha = false);
- // The following scale-code supports arbitrary scaling (i.e. no repeats of column 0 at the end of lines)
+
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
- TransparentSurface *scale(const Common::Rect &srcRect, const Common::Rect &dstRect) const;
- static byte *_lookup;
- static void destroyLookup();
-private:
- static void doBlitAlpha(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
- static void generateLookup();
+ TransparentSurface *rotoscale(const TransformStruct &transform) const;
};
/**
@@ -125,7 +135,7 @@ private:
};*/
-} // End of namespace Graphics
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/math/floatpoint.h b/engines/wintermute/math/floatpoint.h
new file mode 100644
index 0000000000..0c47ef09d7
--- /dev/null
+++ b/engines/wintermute/math/floatpoint.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WINTERMUTE_FLOATPOINT_H
+#define WINTERMUTE_FLOATPOINT_H
+
+namespace Wintermute {
+
+struct FloatPoint {
+ float x;
+ float y;
+ FloatPoint() : x(0), y(0) {}
+ FloatPoint(float x1, float y1) : x(x1), y(y1) {}
+ bool operator==(const FloatPoint &p) const { return x == p.x && y == p.y; }
+ bool operator!=(const FloatPoint &p) const { return x != p.x || y != p.y; }
+ FloatPoint operator+(const FloatPoint &delta) const { return FloatPoint (x + delta.x, y + delta.y); }
+ FloatPoint operator-(const FloatPoint &delta) const { return FloatPoint (x - delta.x, y - delta.y); }
+
+ FloatPoint& operator+=(const FloatPoint &delta) {
+ x += delta.x;
+ y += delta.y;
+ return *this;
+ }
+ FloatPoint& operator-=(const FloatPoint &delta) {
+ x -= delta.x;
+ y -= delta.y;
+ return *this;
+ }
+};
+
+} // End of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/math/math_util.cpp b/engines/wintermute/math/math_util.cpp
index 0aa0f841ac..903cea6d39 100644
--- a/engines/wintermute/math/math_util.cpp
+++ b/engines/wintermute/math/math_util.cpp
@@ -49,4 +49,4 @@ float MathUtil::roundUp(float val) {
return result;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/math/math_util.h b/engines/wintermute/math/math_util.h
index 38b6d9abf9..41a7a43e2e 100644
--- a/engines/wintermute/math/math_util.h
+++ b/engines/wintermute/math/math_util.h
@@ -37,6 +37,6 @@ public:
static float roundUp(float val);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/math/matrix4.cpp b/engines/wintermute/math/matrix4.cpp
index a50514457e..011766f510 100644
--- a/engines/wintermute/math/matrix4.cpp
+++ b/engines/wintermute/math/matrix4.cpp
@@ -83,4 +83,4 @@ void Matrix4::transformVector2(Vector2 &vec) {
vec.y = y;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/math/matrix4.h b/engines/wintermute/math/matrix4.h
index 273633f723..4198b50484 100644
--- a/engines/wintermute/math/matrix4.h
+++ b/engines/wintermute/math/matrix4.h
@@ -45,6 +45,6 @@ public:
float m[4][4];
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/math/rect32.h b/engines/wintermute/math/rect32.h
index 190c1135cf..f522ab3a35 100644
--- a/engines/wintermute/math/rect32.h
+++ b/engines/wintermute/math/rect32.h
@@ -24,12 +24,38 @@
#define WINTERMUTE_RECT32_H
#include "common/system.h"
+#include "engines/wintermute/math/floatpoint.h"
+#include "common/rect.h"
namespace Wintermute {
struct Point32 {
int32 x;
int32 y;
+ Point32() : x(0), y(0) {}
+ Point32(int32 x1, int32 y1) : x(x1), y(y1) {}
+ bool operator==(const Point32 &p) const { return x == p.x && y == p.y; }
+ bool operator!=(const Point32 &p) const { return x != p.x || y != p.y; }
+ Point32 operator+(const Point32 &delta) const { return Point32(x + delta.x, y + delta.y); }
+ Point32 operator-(const Point32 &delta) const { return Point32(x - delta.x, y - delta.y); }
+
+ Point32 &operator+=(const Point32 &delta) {
+ x += delta.x;
+ y += delta.y;
+ return *this;
+ }
+
+ Point32 &operator-=(const Point32 &delta) {
+ x -= delta.x;
+ y -= delta.y;
+ return *this;
+ }
+
+ operator FloatPoint() {
+ return FloatPoint(x,y);
+ }
+
+
};
struct Rect32 {
@@ -38,6 +64,7 @@ struct Rect32 {
Rect32() : top(0), left(0), bottom(0), right(0) {}
Rect32(int32 w, int32 h) : top(0), left(0), bottom(h), right(w) {}
+ Rect32(const Common::Rect &rect) : top(rect.top), left(rect.left), bottom(rect.bottom), right(rect.right) {}
Rect32(int32 x1, int32 y1, int32 x2, int32 y2) : top(y1), left(x1), bottom(y2), right(x2) {
assert(isValidRect());
}
@@ -89,6 +116,6 @@ struct Rect32 {
}
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/math/vector2.cpp b/engines/wintermute/math/vector2.cpp
index 98dca70b44..618ee9bda9 100644
--- a/engines/wintermute/math/vector2.cpp
+++ b/engines/wintermute/math/vector2.cpp
@@ -52,4 +52,4 @@ float Vector2::length() const {
return (float)sqrt(x * x + y * y);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/math/vector2.h b/engines/wintermute/math/vector2.h
index 31f31daaa0..e4ba97c517 100644
--- a/engines/wintermute/math/vector2.h
+++ b/engines/wintermute/math/vector2.h
@@ -70,6 +70,6 @@ public:
float y;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 32931bf05f..95f9ba2ffb 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -89,6 +89,8 @@ MODULE_OBJS := \
base/save_thumb_helper.o \
base/timer.o \
detection.o \
+ graphics/transform_struct.o \
+ graphics/transform_tools.o \
graphics/transparent_surface.o \
math/math_util.o \
math/matrix4.o \
diff --git a/engines/wintermute/persistent.h b/engines/wintermute/persistent.h
index 1464ae0fd6..ddc0791054 100644
--- a/engines/wintermute/persistent.h
+++ b/engines/wintermute/persistent.h
@@ -37,7 +37,7 @@ class BasePersistenceManager;
typedef void *(*PERSISTBUILD)(void);
typedef bool(*PERSISTLOAD)(void *, BasePersistenceManager *);
typedef void(*SYS_INSTANCE_CALLBACK)(void *instance, void *data);
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#include "engines/wintermute/system/sys_class_registry.h"
namespace Wintermute {
@@ -85,6 +85,6 @@ namespace Wintermute {
#define TMEMBER_PTR(memberName) #memberName, &memberName
#define TMEMBER_INT(memberName) #memberName, (int32*)&memberName
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/platform_osystem.cpp b/engines/wintermute/platform_osystem.cpp
index 362c0da624..87a127d001 100644
--- a/engines/wintermute/platform_osystem.cpp
+++ b/engines/wintermute/platform_osystem.cpp
@@ -125,9 +125,12 @@ void BasePlatform::handleEvent(Common::Event *event) {
// _gameRef->AutoSaveOnExit();
// _gameRef->_quitting = true;
// }
- if (_gameRef) {
- _gameRef->onWindowClose();
- }
+
+// The engine CAN query for closing, but we disable it for now, as the EVENT_QUIT-event
+// can't be stopped.
+// if (_gameRef) {
+// _gameRef->onWindowClose();
+// }
break;
default:
// TODO: Do we care about any other events?
@@ -272,4 +275,4 @@ char *BasePlatform::strlwr(char *string) {
return string;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/platform_osystem.h b/engines/wintermute/platform_osystem.h
index 8c39b29ea9..46c86df909 100644
--- a/engines/wintermute/platform_osystem.h
+++ b/engines/wintermute/platform_osystem.h
@@ -70,6 +70,6 @@ private:
static WintermuteEngine *_engineRef;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/system/sys_class.cpp b/engines/wintermute/system/sys_class.cpp
index cda58bbb48..0577f29e2c 100644
--- a/engines/wintermute/system/sys_class.cpp
+++ b/engines/wintermute/system/sys_class.cpp
@@ -217,4 +217,4 @@ void SystemClass::instanceCallback(SYS_INSTANCE_CALLBACK lpCallback, void *lpDat
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/system/sys_class.h b/engines/wintermute/system/sys_class.h
index 3f91723ed8..9fb3f70696 100644
--- a/engines/wintermute/system/sys_class.h
+++ b/engines/wintermute/system/sys_class.h
@@ -125,6 +125,6 @@ private:
InstanceMap _instanceMap;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/system/sys_class_registry.cpp b/engines/wintermute/system/sys_class_registry.cpp
index 8a6aae754f..20e4661efb 100644
--- a/engines/wintermute/system/sys_class_registry.cpp
+++ b/engines/wintermute/system/sys_class_registry.cpp
@@ -333,4 +333,4 @@ void SystemClassRegistry::dumpClasses(Common::WriteStream *stream) {
}
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/system/sys_class_registry.h b/engines/wintermute/system/sys_class_registry.h
index ef7218c7c1..48a6738ffb 100644
--- a/engines/wintermute/system/sys_class_registry.h
+++ b/engines/wintermute/system/sys_class_registry.h
@@ -101,6 +101,6 @@ public:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/system/sys_instance.cpp b/engines/wintermute/system/sys_instance.cpp
index d106119dba..b8e5c9b50a 100644
--- a/engines/wintermute/system/sys_instance.cpp
+++ b/engines/wintermute/system/sys_instance.cpp
@@ -46,4 +46,4 @@ SystemInstance::SystemInstance(void *instance, int id, SystemClass *sysClass) {
SystemInstance::~SystemInstance() {
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/system/sys_instance.h b/engines/wintermute/system/sys_instance.h
index 215a6d1437..115de28094 100644
--- a/engines/wintermute/system/sys_instance.h
+++ b/engines/wintermute/system/sys_instance.h
@@ -63,6 +63,6 @@ private:
SystemClass *_class;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_button.cpp b/engines/wintermute/ui/ui_button.cpp
index 9db1f4f4b4..b2e6c3953b 100644
--- a/engines/wintermute/ui/ui_button.cpp
+++ b/engines/wintermute/ui/ui_button.cpp
@@ -1206,4 +1206,4 @@ bool UIButton::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_button.h b/engines/wintermute/ui/ui_button.h
index 5db9356ef9..b5002f3166 100644
--- a/engines/wintermute/ui/ui_button.h
+++ b/engines/wintermute/ui/ui_button.h
@@ -75,6 +75,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_edit.cpp b/engines/wintermute/ui/ui_edit.cpp
index 91ca7326cb..caed157e0b 100644
--- a/engines/wintermute/ui/ui_edit.cpp
+++ b/engines/wintermute/ui/ui_edit.cpp
@@ -949,4 +949,4 @@ bool UIEdit::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_edit.h b/engines/wintermute/ui/ui_edit.h
index ac626f0f06..a057be9ead 100644
--- a/engines/wintermute/ui/ui_edit.h
+++ b/engines/wintermute/ui/ui_edit.h
@@ -67,6 +67,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_entity.cpp b/engines/wintermute/ui/ui_entity.cpp
index 1872400cdd..6d4cfdb7eb 100644
--- a/engines/wintermute/ui/ui_entity.cpp
+++ b/engines/wintermute/ui/ui_entity.cpp
@@ -363,4 +363,4 @@ bool UIEntity::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_entity.h b/engines/wintermute/ui/ui_entity.h
index 3bd3ec9888..1b6e8a10d6 100644
--- a/engines/wintermute/ui/ui_entity.h
+++ b/engines/wintermute/ui/ui_entity.h
@@ -54,6 +54,6 @@ public:
virtual const char *scToString();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_object.cpp b/engines/wintermute/ui/ui_object.cpp
index 07efc5e4cb..c32ae75c20 100644
--- a/engines/wintermute/ui/ui_object.cpp
+++ b/engines/wintermute/ui/ui_object.cpp
@@ -648,4 +648,4 @@ bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
return STATUS_FAILED;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_object.h b/engines/wintermute/ui/ui_object.h
index 935c27613c..5d9508c2cf 100644
--- a/engines/wintermute/ui/ui_object.h
+++ b/engines/wintermute/ui/ui_object.h
@@ -80,6 +80,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_text.cpp b/engines/wintermute/ui/ui_text.cpp
index 98d70b770e..5dc25f5852 100644
--- a/engines/wintermute/ui/ui_text.cpp
+++ b/engines/wintermute/ui/ui_text.cpp
@@ -519,4 +519,4 @@ bool UIText::sizeToFit() {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_text.h b/engines/wintermute/ui/ui_text.h
index be074755ba..29ed62a5ef 100644
--- a/engines/wintermute/ui/ui_text.h
+++ b/engines/wintermute/ui/ui_text.h
@@ -55,6 +55,6 @@ public:
virtual const char *scToString() override;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_tiled_image.cpp b/engines/wintermute/ui/ui_tiled_image.cpp
index abccdd6c39..de4b86a6dd 100644
--- a/engines/wintermute/ui/ui_tiled_image.cpp
+++ b/engines/wintermute/ui/ui_tiled_image.cpp
@@ -388,4 +388,4 @@ bool UITiledImage::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_tiled_image.h b/engines/wintermute/ui/ui_tiled_image.h
index a6cd22d53d..39bc6495a9 100644
--- a/engines/wintermute/ui/ui_tiled_image.h
+++ b/engines/wintermute/ui/ui_tiled_image.h
@@ -59,6 +59,6 @@ private:
Rect32 _downRight;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_window.cpp b/engines/wintermute/ui/ui_window.cpp
index 2ce9f68605..9066ee9f5b 100644
--- a/engines/wintermute/ui/ui_window.cpp
+++ b/engines/wintermute/ui/ui_window.cpp
@@ -1442,4 +1442,4 @@ bool UIWindow::getWindowObjects(BaseArray<UIObject *> &objects, bool interactive
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_window.h b/engines/wintermute/ui/ui_window.h
index 70799cea25..8a726fdff8 100644
--- a/engines/wintermute/ui/ui_window.h
+++ b/engines/wintermute/ui/ui_window.h
@@ -89,6 +89,6 @@ public:
virtual const char *scToString();
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/utils/crc.cpp b/engines/wintermute/utils/crc.cpp
index e7ec45511b..a9781500fa 100644
--- a/engines/wintermute/utils/crc.cpp
+++ b/engines/wintermute/utils/crc.cpp
@@ -234,4 +234,4 @@ crc crc_finalize(crc remainder) {
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/path_util.cpp b/engines/wintermute/utils/path_util.cpp
index 298f0c268f..ee8b298562 100644
--- a/engines/wintermute/utils/path_util.cpp
+++ b/engines/wintermute/utils/path_util.cpp
@@ -98,4 +98,4 @@ AnsiString PathUtil::getExtension(const AnsiString &path) {
return Common::lastPathComponent(path, '.');
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/path_util.h b/engines/wintermute/utils/path_util.h
index 7358c2aba0..2c7dfa99d1 100644
--- a/engines/wintermute/utils/path_util.h
+++ b/engines/wintermute/utils/path_util.h
@@ -44,6 +44,6 @@ public:
static AnsiString getExtension(const AnsiString &path);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/utils/string_util.cpp b/engines/wintermute/utils/string_util.cpp
index 9fffad85cd..e8e078aba8 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -146,26 +146,21 @@ Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
return "";
}
-// Currently this only does Ansi->ISO 8859, and only for carets.
-char simpleAnsiToWide(const AnsiString &str, uint32 &offset) {
- byte c = str[offset];
-
- if (c == 146) {
- offset++;
- return 39; // Replace right-quote with apostrophe
- } else {
- offset++;
- return c;
- }
-}
-
//////////////////////////////////////////////////////////////////////////
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()) {
- converted += simpleAnsiToWide(str, index);
+ 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 ...
+ } else {
+ converted += c;
+ }
+ index++;
}
// using default os locale!
@@ -231,4 +226,4 @@ AnsiString StringUtil::toString(int val) {
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/string_util.h b/engines/wintermute/utils/string_util.h
index e419e2bca8..3ae5e47493 100644
--- a/engines/wintermute/utils/string_util.h
+++ b/engines/wintermute/utils/string_util.h
@@ -51,6 +51,6 @@ public:
static AnsiString toString(int val);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/utils/utils.cpp b/engines/wintermute/utils/utils.cpp
index 6e0d69edbe..8fa6313ba6 100644
--- a/engines/wintermute/utils/utils.cpp
+++ b/engines/wintermute/utils/utils.cpp
@@ -258,4 +258,4 @@ float BaseUtils::Hue2RGB(float v1, float v2, float vH) {
return (v1);
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/utils.h b/engines/wintermute/utils/utils.h
index d6a603ec72..6c804ff01e 100644
--- a/engines/wintermute/utils/utils.h
+++ b/engines/wintermute/utils/utils.h
@@ -59,6 +59,6 @@ private:
static float Hue2RGB(float v1, float v2, float vH);
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/video/video_player.cpp b/engines/wintermute/video/video_player.cpp
index 42857b5c1b..f18311c3e1 100644
--- a/engines/wintermute/video/video_player.cpp
+++ b/engines/wintermute/video/video_player.cpp
@@ -106,4 +106,4 @@ bool VideoPlayer::loadSubtitles(const char *filename, const char *subtitleFile)
return STATUS_OK;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/video/video_player.h b/engines/wintermute/video/video_player.h
index 033ab50dfa..51c6bf41d3 100644
--- a/engines/wintermute/video/video_player.h
+++ b/engines/wintermute/video/video_player.h
@@ -85,6 +85,6 @@ public:
BaseArray<CVidSubtitle *, CVidSubtitle *> _subtitles;*/
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index 8f9db8392f..f3317684b5 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -163,14 +163,14 @@ bool VideoTheoraPlayer::resetStream() {
if (!_file) {
return STATUS_FAILED;
}
-
+
#if defined (USE_THEORADEC)
_theoraDecoder = new Video::TheoraDecoder();
#else
return STATUS_FAILED;
#endif
_theoraDecoder->loadStream(_file);
-
+
if (!_theoraDecoder->isVideoLoaded()) {
return STATUS_FAILED;
}
@@ -369,14 +369,14 @@ void VideoTheoraPlayer::writeAlpha() {
if (_alphaImage && _surface.w == _alphaImage->getSurface()->w && _surface.h == _alphaImage->getSurface()->h) {
assert(_alphaImage->getSurface()->format.bytesPerPixel == 4);
assert(_surface.format.bytesPerPixel == 4);
- const byte *alphaData = (const byte *)_alphaImage->getSurface()->getBasePtr(0, 0);
+ const byte *alphaData = (const byte *)_alphaImage->getSurface()->getPixels();
#ifdef SCUMM_LITTLE_ENDIAN
int alphaPlace = (_alphaImage->getSurface()->format.aShift / 8);
#else
int alphaPlace = 3 - (_alphaImage->getSurface()->format.aShift / 8);
#endif
alphaData += alphaPlace;
- byte *imgData = (byte *)_surface.getBasePtr(0, 0);
+ byte *imgData = (byte *)_surface.getPixels();
#ifdef SCUMM_LITTLE_ENDIAN
imgData += (_surface.format.aShift / 8);
#else
@@ -417,7 +417,7 @@ bool VideoTheoraPlayer::display(uint32 alpha) {
bool VideoTheoraPlayer::setAlphaImage(const Common::String &filename) {
delete _alphaImage;
_alphaImage = new BaseImage();
- if (!_alphaImage || DID_FAIL(_alphaImage->loadFile(filename))) {
+ if (filename == "" || !_alphaImage || DID_FAIL(_alphaImage->loadFile(filename))) {
delete _alphaImage;
_alphaImage = nullptr;
_alphaFilename = "";
@@ -498,7 +498,7 @@ bool VideoTheoraPlayer::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alphaFilename));
persistMgr->transfer(TMEMBER(_posX));
persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_playZoom));
+ persistMgr->transferFloat(TMEMBER(_playZoom));
persistMgr->transfer(TMEMBER_INT(_playbackType));
persistMgr->transfer(TMEMBER(_looping));
persistMgr->transfer(TMEMBER(_volume));
@@ -529,4 +529,4 @@ BaseSurface *VideoTheoraPlayer::getTexture() const {
return _texture;
}
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h
index 364509a080..ddeba48bbc 100644
--- a/engines/wintermute/video/video_theora_player.h
+++ b/engines/wintermute/video/video_theora_player.h
@@ -101,7 +101,7 @@ public:
// video properties
int32 _posX;
int32 _posY;
-
+
bool _dontDropFrames;
private:
int32 _state;
@@ -142,6 +142,6 @@ private:
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index 19848b002e..0a6be4caf8 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -105,7 +105,7 @@ bool WintermuteEngine::hasFeature(EngineFeature f) const {
Common::Error WintermuteEngine::run() {
// Initialize graphics using following:
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
initGraphics(800, 600, true, &format);
if (g_system->getScreenFormat() != format) {
error("Wintermute currently REQUIRES 32bpp");
@@ -133,7 +133,7 @@ Common::Error WintermuteEngine::run() {
}
int WintermuteEngine::init() {
- BaseEngine::createInstance(_targetName, _gameDescription->language);
+ BaseEngine::createInstance(_targetName, _gameDescription->gameid, _gameDescription->language);
_game = new AdGame(_targetName);
if (!_game) {
return 1;
@@ -147,7 +147,7 @@ int WintermuteEngine::init() {
_game->initialize1();
// set gameId, for savegame-naming:
- _game->setGameId(_targetName);
+ _game->setGameTargetName(_targetName);
if (DID_FAIL(_game->loadSettings("startup.settings"))) {
_game->LOG(0, "Error loading game settings.");
@@ -250,6 +250,9 @@ int WintermuteEngine::messageLoop() {
}
prevTime = time;
}
+ if (shouldQuit()) {
+ break;
+ }
if (_game && _game->_quitting) {
break;
}
diff --git a/engines/wintermute/wintypes.h b/engines/wintermute/wintypes.h
index c7723808ea..1288ac1a65 100644
--- a/engines/wintermute/wintypes.h
+++ b/engines/wintermute/wintypes.h
@@ -48,6 +48,6 @@ namespace Wintermute {
#define MAX_PATH_LENGTH 512
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 0467cac946..8e1c5e91e1 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -73,6 +73,8 @@ struct DrawStep {
uint8 shadow, stroke, factor, radius, bevel; /**< Misc options... */
uint8 fillMode; /**< active fill mode */
+ uint8 shadowFillMode; /**< fill mode of the shadow used */
+
uint32 extraData; /**< Generic parameter for extra options (orientation/bevel) */
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
@@ -103,7 +105,7 @@ VectorRenderer *createRenderer(int mode);
*/
class VectorRenderer {
public:
- VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0),
+ VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0), _shadowFillMode(kShadowExponential),
_disableShadows(false), _strokeWidth(1), _gradientFactor(1) {
}
@@ -126,6 +128,11 @@ public:
kTriangleRight
};
+ enum ShadowFillMode {
+ kShadowLinear = 0,
+ kShadowExponential = 1
+ };
+
/**
* Draws a line by considering the special cases for optimization.
*
@@ -278,7 +285,7 @@ public:
* Clears the active surface.
*/
virtual void clearSurface() {
- byte *src = (byte *)_activeSurface->pixels;
+ byte *src = (byte *)_activeSurface->getPixels();
memset(src, 0, _activeSurface->pitch * _activeSurface->h);
}
@@ -292,6 +299,10 @@ public:
_fillMode = mode;
}
+ virtual void setShadowFillMode(ShadowFillMode mode) {
+ _shadowFillMode = mode;
+ }
+
/**
* Sets the stroke width. All shapes drawn with a stroke will
* have that width. Pass 0 to disable shape stroking.
@@ -466,7 +477,7 @@ public:
*/
virtual void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
- GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis) = 0;
+ GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis, const Common::Rect &textDrawableArea) = 0;
/**
* Allows to temporarily enable/disable all shadows drawing.
@@ -485,6 +496,7 @@ protected:
Surface *_activeSurface; /**< Pointer to the surface currently being drawn */
FillMode _fillMode; /**< Defines in which way (if any) are filled the drawn shapes */
+ ShadowFillMode _shadowFillMode;
int _shadowOffset; /**< offset for drawn shadows */
int _bevel; /**< amount of fake bevel */
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index 6a3ee306a5..491a9d7f42 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -119,6 +119,38 @@ inline frac_t fp_sqroot(uint32 x) {
*(ptr4 + (y) + (px)) = color2; \
} while (0)
+#define BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) - (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) - (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) - (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) - (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) + (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) + (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) + (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) + (px), color, a); \
+} while (0)
+
#define BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py) do { \
*(ptr1 + (y) - (px)) = color1; \
*(ptr1 + (x) - (py)) = color2; \
@@ -222,6 +254,37 @@ inline frac_t fp_sqroot(uint32 x) {
this->blendPixelPtr(ptr4 + (y) + (px), color2, a); \
} while (0)
+#define WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) - (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) - (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) - (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) - (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) + (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) + (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) + (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) + (px), color, a); \
+} while (0)
// optimized Wu's algorithm
#define WU_ALGORITHM() do { \
@@ -277,16 +340,24 @@ void colorFill(PixelType *first, PixelType *last, PixelType color) {
VectorRenderer *createRenderer(int mode) {
#ifdef DISABLE_FANCY_THEMES
- assert(mode == GUI::ThemeEngine::kGfxStandard16bit);
+ assert(mode == GUI::ThemeEngine::kGfxStandard);
#endif
PixelFormat format = g_system->getOverlayFormat();
switch (mode) {
- case GUI::ThemeEngine::kGfxStandard16bit:
- return new VectorRendererSpec<OverlayColor>(format);
+ case GUI::ThemeEngine::kGfxStandard:
+ if (g_system->getOverlayFormat().bytesPerPixel == 4)
+ return new VectorRendererSpec<uint32>(format);
+ else if (g_system->getOverlayFormat().bytesPerPixel == 2)
+ return new VectorRendererSpec<uint16>(format);
+ break;
#ifndef DISABLE_FANCY_THEMES
- case GUI::ThemeEngine::kGfxAntialias16bit:
- return new VectorRendererAA<OverlayColor>(format);
+ case GUI::ThemeEngine::kGfxAntialias:
+ if (g_system->getOverlayFormat().bytesPerPixel == 4)
+ return new VectorRendererAA<uint32>(format);
+ else if (g_system->getOverlayFormat().bytesPerPixel == 2)
+ return new VectorRendererAA<uint16>(format);
+ break;
#endif
default:
break;
@@ -317,9 +388,15 @@ setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) {
_gradientEnd = _format.RGBToColor(r2, g2, b2);
_gradientStart = _format.RGBToColor(r1, g1, b1);
- _gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask);
- _gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask);
- _gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask);
+ if (sizeof(PixelType) == 4) {
+ _gradientBytes[0] = ((_gradientEnd & _redMask) >> _format.rShift) - ((_gradientStart & _redMask) >> _format.rShift);
+ _gradientBytes[1] = ((_gradientEnd & _greenMask) >> _format.gShift) - ((_gradientStart & _greenMask) >> _format.gShift);
+ _gradientBytes[2] = ((_gradientEnd & _blueMask) >> _format.bShift) - ((_gradientStart & _blueMask) >> _format.bShift);
+ } else {
+ _gradientBytes[0] = (_gradientEnd & _redMask) - (_gradientStart & _redMask);
+ _gradientBytes[1] = (_gradientEnd & _greenMask) - (_gradientStart & _greenMask);
+ _gradientBytes[2] = (_gradientEnd & _blueMask) - (_gradientStart & _blueMask);
+ }
}
template<typename PixelType>
@@ -328,9 +405,15 @@ calcGradient(uint32 pos, uint32 max) {
PixelType output = 0;
pos = (MIN(pos * Base::_gradientFactor, max) << 12) / max;
- output |= ((_gradientStart & _redMask) + ((_gradientBytes[0] * pos) >> 12)) & _redMask;
- output |= ((_gradientStart & _greenMask) + ((_gradientBytes[1] * pos) >> 12)) & _greenMask;
- output |= ((_gradientStart & _blueMask) + ((_gradientBytes[2] * pos) >> 12)) & _blueMask;
+ if (sizeof(PixelType) == 4) {
+ output |= ((_gradientStart & _redMask) + (((_gradientBytes[0] * pos) >> 12) << _format.rShift)) & _redMask;
+ output |= ((_gradientStart & _greenMask) + (((_gradientBytes[1] * pos) >> 12) << _format.gShift)) & _greenMask;
+ output |= ((_gradientStart & _blueMask) + (((_gradientBytes[2] * pos) >> 12) << _format.bShift)) & _blueMask;
+ } else {
+ output |= ((_gradientStart & _redMask) + ((_gradientBytes[0] * pos) >> 12)) & _redMask;
+ output |= ((_gradientStart & _greenMask) + ((_gradientBytes[1] * pos) >> 12)) & _greenMask;
+ output |= ((_gradientStart & _blueMask) + ((_gradientBytes[2] * pos) >> 12)) & _blueMask;
+ }
output |= _alphaMask;
return output;
@@ -397,7 +480,7 @@ gradientFill(PixelType *ptr, int width, int x, int y) {
template<typename PixelType>
void VectorRendererSpec<PixelType>::
fillSurface() {
- byte *ptr = (byte *)_activeSurface->getBasePtr(0, 0);
+ byte *ptr = (byte *)_activeSurface->getPixels();
int h = _activeSurface->h;
int pitch = _activeSurface->pitch;
@@ -453,7 +536,7 @@ template<typename PixelType>
void VectorRendererSpec<PixelType>::
blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) {
byte *dst_ptr = (byte *)_activeSurface->getBasePtr(r.left, r.top);
- const byte *src_ptr = (const byte *)source->getBasePtr(0, 0);
+ const byte *src_ptr = (const byte *)source->getPixels();
const int dst_pitch = _activeSurface->pitch;
const int src_pitch = source->pitch;
@@ -481,7 +564,7 @@ blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) {
y = y + (r.height() >> 1) - (source->h >> 1);
PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
- const PixelType *src_ptr = (const PixelType *)source->getBasePtr(0, 0);
+ const PixelType *src_ptr = (const PixelType *)source->getPixels();
int dst_pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
int src_pitch = source->pitch / source->format.bytesPerPixel;
@@ -508,7 +591,7 @@ template<typename PixelType>
void VectorRendererSpec<PixelType>::
applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
int pixels = _activeSurface->w * _activeSurface->h;
- PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, 0);
+ PixelType *ptr = (PixelType *)_activeSurface->getPixels();
uint8 r, g, b;
uint lum;
@@ -537,20 +620,41 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
template<typename PixelType>
inline void VectorRendererSpec<PixelType>::
blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
- int idst = *ptr;
- int isrc = color;
-
- *ptr = (PixelType)(
- (_redMask & ((idst & _redMask) +
- ((int)(((int)(isrc & _redMask) -
- (int)(idst & _redMask)) * alpha) >> 8))) |
- (_greenMask & ((idst & _greenMask) +
- ((int)(((int)(isrc & _greenMask) -
- (int)(idst & _greenMask)) * alpha) >> 8))) |
- (_blueMask & ((idst & _blueMask) +
- ((int)(((int)(isrc & _blueMask) -
- (int)(idst & _blueMask)) * alpha) >> 8))) |
- (idst & _alphaMask));
+ 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;
+
+ byte dR = (*ptr & _redMask) >> _format.rShift;
+ byte dG = (*ptr & _greenMask) >> _format.gShift;
+ byte dB = (*ptr & _blueMask) >> _format.bShift;
+
+ dR += ((sR - dR) * alpha) >> 8;
+ dG += ((sG - dG) * alpha) >> 8;
+ dB += ((sB - dB) * alpha) >> 8;
+
+ *ptr = ((dR << _format.rShift) & _redMask)
+ | ((dG << _format.gShift) & _greenMask)
+ | ((dB << _format.bShift) & _blueMask)
+ | (*ptr & _alphaMask);
+ } else if (sizeof(PixelType) == 2) {
+ int idst = *ptr;
+ int isrc = color;
+
+ *ptr = (PixelType)(
+ (_redMask & ((idst & _redMask) +
+ ((int)(((int)(isrc & _redMask) -
+ (int)(idst & _redMask)) * alpha) >> 8))) |
+ (_greenMask & ((idst & _greenMask) +
+ ((int)(((int)(isrc & _greenMask) -
+ (int)(idst & _greenMask)) * alpha) >> 8))) |
+ (_blueMask & ((idst & _blueMask) +
+ ((int)(((int)(isrc & _blueMask) -
+ (int)(idst & _blueMask)) * alpha) >> 8))) |
+ (idst & _alphaMask));
+ } else {
+ error("Unsupported BPP format: %u", (uint)sizeof(PixelType));
+ }
}
template<typename PixelType>
@@ -607,24 +711,45 @@ darkenFill(PixelType *ptr, PixelType *end) {
template<typename PixelType>
void VectorRendererSpec<PixelType>::
drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area,
- Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis) {
+ Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis, const Common::Rect &textDrawableArea) {
int offset = area.top;
if (font->getFontHeight() < area.height()) {
switch (alignV) {
- case GUI::ThemeEngine::kTextAlignVCenter:
- offset = area.top + ((area.height() - font->getFontHeight()) >> 1);
- break;
- case GUI::ThemeEngine::kTextAlignVBottom:
- offset = area.bottom - font->getFontHeight();
- break;
- default:
- break;
+ case GUI::ThemeEngine::kTextAlignVCenter:
+ offset = area.top + ((area.height() - font->getFontHeight()) >> 1);
+ break;
+ case GUI::ThemeEngine::kTextAlignVBottom:
+ offset = area.bottom - font->getFontHeight();
+ break;
+ default:
+ break;
}
}
- font->drawString(_activeSurface, text, area.left, offset, area.width() - deltax, _fgColor, alignH, deltax, ellipsis);
+ Common::Rect drawArea;
+ if (textDrawableArea.isEmpty()) {
+ // In case no special area to draw to is given we only draw in the
+ // area specified by the user.
+ drawArea = area;
+ // warning("there is no text drawable area. Please set this area for clipping");
+ } else {
+ // The area we can draw to is the intersection between the allowed
+ // drawing area (textDrawableArea) and the area where we try to draw
+ // the text (area).
+ drawArea = textDrawableArea.findIntersectingRect(area);
+ }
+
+ // Better safe than sorry. We intersect with the actual surface boundaries
+ // to avoid any ugly clipping in _activeSurface->getSubArea which messes
+ // up the calculation of the x and y coordinates where to draw the string.
+ drawArea = drawArea.findIntersectingRect(Common::Rect(0, 0, _activeSurface->w, _activeSurface->h));
+
+ if (!drawArea.isEmpty()) {
+ Surface textAreaSurface = _activeSurface->getSubArea(drawArea);
+ font->drawString(&textAreaSurface, text, area.left - drawArea.left, offset - drawArea.top, area.width() - deltax, _fgColor, alignH, deltax, ellipsis);
+ }
}
/** LINES **/
@@ -778,7 +903,8 @@ drawRoundedSquare(int x, int y, int r, int w, int h) {
if (Base::_fillMode != kFillDisabled && Base::_shadowOffset
&& x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w
- && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h) {
+ && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h
+ && h > (Base::_shadowOffset + 1) * 2) {
drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset);
}
@@ -809,13 +935,14 @@ drawTab(int x, int y, int r, int w, int h) {
// FIXME: This is broken for the AA renderer.
// See the rounded rect alg for how to fix it. (The border should
// be drawn before the interior, both inside drawTabAlg.)
- drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
+ drawTabShadow(x, y, w - 2, h, r);
+ drawTabAlg(x, y, w - 2, h, r, _bgColor, Base::_fillMode);
if (Base::_strokeWidth)
drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF));
break;
case kFillForeground:
- drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
+ drawTabAlg(x, y, w, h, r, _fgColor, Base::_fillMode);
break;
}
}
@@ -996,6 +1123,67 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
}
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawTabShadow(int x1, int y1, int w, int h, int r) {
+ int offset = 3;
+ int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
+
+ // "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
+ uint8 expFactor = 3;
+ uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
+
+ int xstart = x1;
+ int ystart = y1;
+ int width = w;
+ int height = h + offset + 1;
+
+ for (int i = offset; i >= 0; i--) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(xstart, ystart);
+
+ int short_h = height - (2 * r) + 2;
+ PixelType color = _format.RGBToColor(0, 0, 0);
+
+ BE_RESET();
+
+ // HACK: As we are drawing circles exploting 8-axis symmetry,
+ // there are 4 pixels on each circle which are drawn twice.
+ // this is ok on filled circles, but when blending on surfaces,
+ // we cannot let it blend twice. awful.
+ uint32 hb = 0;
+
+ while (x++ < y) {
+ BE_ALGORITHM();
+
+ if (((1 << x) & hb) == 0) {
+ blendFill(ptr_tl - y - px, ptr_tr + y - px, color, (uint8)alpha);
+ hb |= (1 << x);
+ }
+
+ if (((1 << y) & hb) == 0) {
+ blendFill(ptr_tl - x - py, ptr_tr + x - py, color, (uint8)alpha);
+ hb |= (1 << y);
+ }
+ }
+
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
+ ptr_fill += pitch;
+ }
+
+ // Move shadow one pixel upward each iteration
+ xstart += 1;
+ // Multiply with expfactor
+ alpha = (alpha * (expFactor << 8)) >> 9;
+ }
+}
+
/** BEVELED TABS FOR CLASSIC THEME **/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
@@ -1429,118 +1617,160 @@ drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, Vecto
/** ROUNDED SQUARE ALGORITHM **/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l) {
int f, ddF_x, ddF_y;
int x, y, px, py;
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
+ int sw = 0, sp = 0, hp = h * pitch;
- // TODO: Split this up into border, bevel and interior functions
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (fill_m != kFillDisabled) {
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int real_radius = r;
- int short_h = h - (2 * r) + 2;
- int long_h = h;
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
- BE_RESET();
+ PixelType color1 = color;
+ PixelType color2 = color;
- PixelType color1 = color;
- if (fill_m == kFillBackground)
- color1 = _bgColor;
+ while (sw++ < Base::_strokeWidth) {
+ blendFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1, alpha_t); // top
+ blendFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2, alpha_b); // bottom
+ sp += pitch;
- if (fill_m == kFillGradient) {
- PixelType color2, color3, color4;
- precalcGradient(long_h);
+ BE_RESET();
+ r--;
+
+ int alphaStep_tr = ((alpha_t - alpha_r)/(y+1));
+ int alphaStep_br = ((alpha_r - alpha_b)/(y+1));
+ int alphaStep_bl = ((alpha_b - alpha_l)/(y+1));
+ int alphaStep_tl = ((alpha_l - alpha_t)/(y+1));
+
+ // Avoid blending the last pixels twice, since we have an alpha
+ while (x++ < (y - 2)) {
+ BE_ALGORITHM();
- while (x++ < y) {
- BE_ALGORITHM();
+ BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)(alpha_r + (alphaStep_tr * x)));
+ BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)(alpha_b + (alphaStep_br * x)));
+ BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)(alpha_l + (alphaStep_bl * x)));
+ BE_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)(alpha_t + (alphaStep_tl * x)));
+
+ BE_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)(alpha_t - (alphaStep_tr * x)));
+ BE_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)(alpha_r - (alphaStep_br * x)));
+ BE_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)(alpha_b - (alphaStep_bl * x)));
+ BE_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)(alpha_l - (alphaStep_tl * x)));
+
+ if (Base::_strokeWidth > 1) {
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
+ }
+ }
+ }
- color1 = calcGradient(real_radius - x, long_h);
- color2 = calcGradient(real_radius - y, long_h);
- color3 = calcGradient(long_h - r + x, long_h);
- color4 = calcGradient(long_h - r + y, long_h);
+ ptr_fill += pitch * real_radius;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + Base::_strokeWidth, color1, alpha_l); // left
+ blendFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2, alpha_r); // right
+ ptr_fill += pitch;
+ }
+}
- gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
- gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+ int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y);
- gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x);
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
- }
- } else {
- while (x++ < y) {
- BE_ALGORITHM();
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
+ int long_h = h;
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color1);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
+ BE_RESET();
- colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color1);
- colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color1);
+ PixelType color1 = color;
- // do not remove - messes up the drawing at lower resolutions
- BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
- }
- }
+ if (fill_m == kFillGradient) {
+ PixelType color2, color3, color4;
+ precalcGradient(long_h);
- ptr_fill += pitch * r;
- while (short_h--) {
- if (fill_m == kFillGradient) {
- gradientFill(ptr_fill, w + 1, x1, real_radius++);
- } else {
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color1);
- }
- ptr_fill += pitch;
- }
- }
+ while (x++ < y) {
+ BE_ALGORITHM();
+ color1 = calcGradient(real_radius - x, long_h);
+ color2 = calcGradient(real_radius - y, long_h);
+ color3 = calcGradient(long_h - r + x, long_h);
+ color4 = calcGradient(long_h - r + y, long_h);
- if (Base::_strokeWidth) {
- int sw = 0, sp = 0, hp = h * pitch;
+ gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
+ gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y);
+ gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x);
- int real_radius = r;
- int short_h = h - (2 * r) + 2;
+ BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ }
+ } else {
+ while (x++ < y) {
+ BE_ALGORITHM();
- // TODO: A gradient effect on the bevel
- PixelType color1, color2;
- color1 = Base::_bevel ? _bevelColor : color;
- color2 = color;
+ colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color1);
+ colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
- while (sw++ < Base::_strokeWidth) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
- colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
- sp += pitch;
+ colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color1);
+ colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color1);
- BE_RESET();
- r--;
-
- while (x++ < y) {
- BE_ALGORITHM();
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ // do not remove - messes up the drawing at lower resolutions
+ BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ }
+ }
- if (Base::_strokeWidth > 1) {
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
- }
- }
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ if (fill_m == kFillGradient) {
+ gradientFill(ptr_fill, w + 1, x1, real_radius++);
+ } else {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color1);
}
+ ptr_fill += pitch;
+ }
+}
- ptr_fill += pitch * real_radius;
- while (short_h--) {
- colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
- colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
- ptr_fill += pitch;
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ const uint8 borderAlpha_t = 0;
+ const uint8 borderAlpha_r = 127;
+ const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_l = 63;
+
+ const uint8 bevelAlpha_t = 255;
+ const uint8 bevelAlpha_r = 31;
+ const uint8 bevelAlpha_b = 0;
+ const uint8 bevelAlpha_l = 127;
+
+ // If only border is visible
+ if ((!(w <= 0 || h <= 0)) && (fill_m != Base::kFillDisabled)) {
+ if (fill_m == Base::kFillBackground)
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, _bgColor, fill_m);
+ else
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, color, fill_m);
+ }
+
+ if (Base::_strokeWidth) {
+ if (r != 0 && _bevel > 0) {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, borderAlpha_t, borderAlpha_r, borderAlpha_b, borderAlpha_l);
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, _bevelColor, fill_m, bevelAlpha_t, bevelAlpha_r, bevelAlpha_b, bevelAlpha_l);
+ } else {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, 255, 255, 255, 255);
}
}
}
@@ -1599,85 +1829,112 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
********************************************************************/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawSquareShadow(int x, int y, int w, int h, int blur) {
- PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + blur);
+drawSquareShadow(int x, int y, int w, int h, int offset) {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + offset);
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
int i, j;
- i = h - blur;
+ i = h - offset;
while (i--) {
- j = blur;
+ j = offset;
while (j--)
- blendPixelPtr(ptr + j, 0, ((blur - j) << 8) / blur);
+ blendPixelPtr(ptr + j, 0, ((offset - j) << 8) / offset);
ptr += pitch;
}
- ptr = (PixelType *)_activeSurface->getBasePtr(x + blur, y + h - 1);
+ ptr = (PixelType *)_activeSurface->getBasePtr(x + offset, y + h - 1);
- while (i++ < blur) {
- j = w - blur;
+ while (i++ < offset) {
+ j = w - offset;
while (j--)
- blendPixelPtr(ptr + j, 0, ((blur - i) << 8) / blur);
+ blendPixelPtr(ptr + j, 0, ((offset - i) << 8) / offset);
ptr += pitch;
}
ptr = (PixelType *)_activeSurface->getBasePtr(x + w, y + h);
i = 0;
- while (i++ < blur) {
- j = blur - 1;
+ while (i++ < offset) {
+ j = offset - 1;
while (j--)
- blendPixelPtr(ptr + j, 0, (((blur - j) * (blur - i)) << 8) / (blur * blur));
+ blendPixelPtr(ptr + j, 0, (((offset - j) * (offset - i)) << 8) / (offset * offset));
ptr += pitch;
}
}
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
- int f, ddF_x, ddF_y;
- int x, y, px, py;
+drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- int alpha = 102;
- x1 += blur;
- y1 += blur;
+ // "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
+ uint8 expFactor = 3;
+ uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
+
+ // These constants ensure a border of 2px on the left and of each rounded square
+ int xstart = (x1 > 2) ? x1 - 2 : x1;
+ int ystart = y1;
+ int width = w + offset + 2;
+ int height = h + offset + 1;
+
+ for (int i = offset; i >= 0; i--) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + height - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + height - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(xstart, ystart);
+
+ int short_h = height - (2 * r) + 2;
+ PixelType color = _format.RGBToColor(0, 0, 0);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - blur, y1 + r);
-
- int short_h = h - (2 * r) + 1;
+ BE_RESET();
- BE_RESET();
+ // HACK: As we are drawing circles exploting 8-axis symmetry,
+ // there are 4 pixels on each circle which are drawn twice.
+ // this is ok on filled circles, but when blending on surfaces,
+ // we cannot let it blend twice. awful.
+ uint32 hb = 0;
+
+ while (x++ < y) {
+ BE_ALGORITHM();
- // HACK: As we are drawing circles exploting 8-axis symmetry,
- // there are 4 pixels on each circle which are drawn twice.
- // this is ok on filled circles, but when blending on surfaces,
- // we cannot let it blend twice. awful.
- uint32 hb = 0;
- while (x++ < y) {
- BE_ALGORITHM();
+ if (((1 << x) & hb) == 0) {
+ blendFill(ptr_tl - y - px, ptr_tr + y - px, color, (uint8)alpha);
+
+ // Will create a dark line of pixles if left out
+ if (hb > 0) {
+ blendFill(ptr_bl - y + px, ptr_br + y + px, color, (uint8)alpha);
+ }
+ hb |= (1 << x);
+ }
- if (((1 << x) & hb) == 0) {
- blendFill(ptr_tr - px - r, ptr_tr + y - px, 0, alpha);
- blendFill(ptr_bl - y + px, ptr_br + y + px, 0, alpha);
- hb |= (1 << x);
+ if (((1 << y) & hb) == 0) {
+ blendFill(ptr_tl - x - py, ptr_tr + x - py, color, (uint8)alpha);
+ blendFill(ptr_bl - x + py, ptr_br + x + py, color, (uint8)alpha);
+ hb |= (1 << y);
+ }
}
-
- if (((1 << y) & hb) == 0) {
- blendFill(ptr_tr - r - py, ptr_tr + x - py, 0, alpha);
- blendFill(ptr_bl - x + py, ptr_br + x + py, 0, alpha);
- hb |= (1 << y);
+
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
+ ptr_fill += pitch;
}
- }
- while (short_h--) {
- blendFill(ptr_fill - r, ptr_fill + blur, 0, alpha);
- ptr_fill += pitch;
+ // Make shadow smaller each iteration, and move it one pixel inward
+ xstart += 1;
+ ystart += 1;
+ width -= 2;
+ height -= 2;
+
+ if (_shadowFillMode == kShadowExponential)
+ // Multiply with expfactor
+ alpha = (alpha * (expFactor << 8)) >> 9;
}
}
@@ -1870,7 +2127,7 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
/** ROUNDED SQUARES **/
template<typename PixelType>
void VectorRendererAA<PixelType>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l) {
int x, y;
const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
int px, py;
@@ -1879,65 +2136,89 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
frac_t T = 0, oldT;
uint8 a1, a2;
- // TODO: Split this up into border, bevel and interior functions
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (Base::_strokeWidth) {
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int sw = 0, sp = 0;
- int short_h = h - 2 * r;
- int hp = h * pitch;
-
- int strokeWidth = Base::_strokeWidth;
- // If we're going to fill the inside, draw a slightly thicker border
- // so we can blend the inside on top of it.
- if (fill_m != Base::kFillDisabled) strokeWidth++;
-
- // TODO: A gradient effect on the bevel
- PixelType color1, color2;
- color1 = Base::_bevel ? Base::_bevelColor : color;
- color2 = color;
+ int sw = 0, sp = 0;
+ int short_h = h - 2 * r;
+ int hp = h * pitch;
+ int strokeWidth = Base::_strokeWidth;
- while (sw++ < strokeWidth) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
- colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
- sp += pitch;
+ while (sw++ < strokeWidth) {
+ this->blendFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color, alpha_b); // bottom
+ this->blendFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color, alpha_t); // top
- x = r - (sw - 1);
- y = 0;
- T = 0;
- px = pitch * x;
- py = 0;
+ sp += pitch;
- while (x > y++) {
- WU_ALGORITHM();
+ x = r - (sw - 1);
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
- // sw == 1: outside, sw = _strokeWidth: inside
- // We always draw the outer edge AAed, but the inner edge
- // only when the inside isn't filled
- if (sw != strokeWidth || fill_m != Base::kFillDisabled)
- a2 = 255;
+ int alphaStep_tr = ((alpha_t - alpha_r)/(x+1));
+ int alphaStep_br = ((alpha_r - alpha_b)/(x+1));
+ int alphaStep_bl = ((alpha_b - alpha_l)/(x+1));
+ int alphaStep_tl = ((alpha_l - alpha_t)/(x+1));
- // inner arc
- WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2);
+ while (x > y++) {
+ WU_ALGORITHM();
- if (sw == 1) // outer arc
- WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ // sw == 1: outside, sw = _strokeWidth: inside
+ // We always draw the outer edge AAed, but the inner edge
+ // only when the inside isn't filled
+ if (sw != strokeWidth || fill_m != Base::kFillDisabled)
+ a2 = 255;
+
+ // inner arc
+ WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a2) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a2) >> 16));
+
+ // outer arc
+ if (sw == 1) {
+ WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a1) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a1) >> 16));
+ }
}
- }
ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
- colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
+
+ while (short_h-- >= -2) {
+ this->blendFill(ptr_fill, ptr_fill + Base::_strokeWidth, color, alpha_l); // left
+ this->blendFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color, alpha_r); // right
ptr_fill += pitch;
}
}
+}
+
+template<typename PixelType>
+void VectorRendererAA<PixelType>::
+drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ int x, y;
+ const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
+ int px, py;
+
+ uint32 rsq = r*r;
+ frac_t T = 0, oldT;
+ uint8 a1, a2;
r -= Base::_strokeWidth;
x1 += Base::_strokeWidth;
@@ -1946,93 +2227,116 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
h -= 2*Base::_strokeWidth;
rsq = r*r;
- if (w <= 0 || h <= 0)
- return; // Only border is visible
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (fill_m != Base::kFillDisabled) {
- if (fill_m == Base::kFillBackground)
- color = Base::_bgColor;
+ int short_h = h - 2 * r;
+ x = r;
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ if (fill_m == Base::kFillGradient) {
- int short_h = h - 2 * r;
- x = r;
- y = 0;
- T = 0;
- px = pitch * x;
- py = 0;
+ Base::precalcGradient(h);
- if (fill_m == Base::kFillGradient) {
+ PixelType color1, color2, color3, color4;
+ while (x > y++) {
+ WU_ALGORITHM();
- Base::precalcGradient(h);
+ color1 = Base::calcGradient(r - x, h);
+ color2 = Base::calcGradient(r - y, h);
+ color3 = Base::calcGradient(h - r + x, h);
+ color4 = Base::calcGradient(h - r + y, h);
- PixelType color1, color2, color3, color4;
- while (x > y++) {
- WU_ALGORITHM();
+ Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, r - y);
- color1 = Base::calcGradient(r - x, h);
- color2 = Base::calcGradient(r - y, h);
- color3 = Base::calcGradient(h - r + x, h);
- color4 = Base::calcGradient(h - r + y, h);
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, r - x);
- Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, r - y);
+ Base::gradientFill(ptr_bl - x + py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, h - r + y);
- // Only fill each horizontal line once (or we destroy
- // the gradient effect at the edges)
- if (T < oldT || y == 1)
- Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, r - x);
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_bl - y + px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, h - r + x);
- Base::gradientFill(ptr_bl - x + py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, h - r + y);
+ // This shape is used for dialog backgrounds.
+ // If we're drawing on top of an empty overlay background,
+ // and the overlay supports alpha, we have to do AA by
+ // setting the dest alpha channel, instead of blending with
+ // dest color channels.
+ if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha))
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelPtr);
+ else
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelDestAlphaPtr);
+ }
- // Only fill each horizontal line once (or we destroy
- // the gradient effect at the edges)
- if (T < oldT || y == 1)
- Base::gradientFill(ptr_bl - y + px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, h - r + x);
-
- // This shape is used for dialog backgrounds.
- // If we're drawing on top of an empty overlay background,
- // and the overlay supports alpha, we have to do AA by
- // setting the dest alpha channel, instead of blending with
- // dest color channels.
- if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha))
- WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelPtr);
- else
- WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelDestAlphaPtr);
- }
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ Base::gradientFill(ptr_fill, w + 1, x1, r++);
+ ptr_fill += pitch;
+ }
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- Base::gradientFill(ptr_fill, w + 1, x1, r++);
- ptr_fill += pitch;
- }
+ } else {
- } else {
+ while (x > 1 + y++) {
+ WU_ALGORITHM();
- while (x > 1 + y++) {
- WU_ALGORITHM();
+ colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
- colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
- if (T < oldT || y == 1)
- colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
+ colorFill<PixelType>(ptr_bl - x + py + 1, ptr_br + x + py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_bl - y + px + 1, ptr_br + y + px, color);
- colorFill<PixelType>(ptr_bl - x + py + 1, ptr_br + x + py, color);
- if (T < oldT || y == 1)
- colorFill<PixelType>(ptr_bl - y + px + 1, ptr_br + y + px, color);
+ WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ }
- WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
- }
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ ptr_fill += pitch;
+ }
+ }
+}
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
- ptr_fill += pitch;
- }
+template<typename PixelType>
+void VectorRendererAA<PixelType>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ const uint8 borderAlpha_t = 0;
+ const uint8 borderAlpha_r = 127;
+ const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_l = 63;
+
+ const uint8 bevelAlpha_t = 255;
+ const uint8 bevelAlpha_r = 31;
+ const uint8 bevelAlpha_b = 0;
+ const uint8 bevelAlpha_l = 127;
+
+ if (Base::_strokeWidth) {
+ if (r != 0 && Base::_bevel > 0) {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, borderAlpha_t, borderAlpha_r, borderAlpha_b, borderAlpha_l);
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, Base::_bevelColor, fill_m, bevelAlpha_t, bevelAlpha_r, bevelAlpha_b, bevelAlpha_l);
+ } else {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, 255, 255, 255, 255);
}
}
+
+ // If only border is visible
+ if ((!(w <= 0 || h <= 0)) && (fill_m != Base::kFillDisabled)) {
+ if (fill_m == Base::kFillBackground)
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, Base::_bgColor, fill_m);
+ else
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, color, fill_m);
+ }
}
/** CIRCLES **/
diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h
index 4ed80cb55f..c035ca0e19 100644
--- a/graphics/VectorRendererSpec.h
+++ b/graphics/VectorRendererSpec.h
@@ -61,7 +61,7 @@ public:
}
void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
- GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis);
+ GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis, const Common::Rect &textDrawableArea = Common::Rect(0, 0, 0, 0));
void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = _format.RGBToColor(r, g, b); }
void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); }
@@ -158,6 +158,12 @@ protected:
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h,
PixelType color, FillMode fill_m);
+ virtual void drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h,
+ PixelType color, FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l);
+
+ virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h,
+ PixelType color, FillMode fill_m);
+
virtual void drawSquareAlg(int x, int y, int w, int h,
PixelType color, FillMode fill_m);
@@ -174,6 +180,8 @@ protected:
PixelType color, VectorRenderer::FillMode fill_m,
int baseLeft = 0, int baseRight = 0);
+ virtual void drawTabShadow(int x, int y, int w, int h, int r);
+
virtual void drawBevelTabAlg(int x, int y, int w, int h,
int bevel, PixelType topColor, PixelType bottomColor,
int baseLeft = 0, int baseRight = 0);
@@ -186,10 +194,10 @@ protected:
* There functions may be overloaded in inheriting classes to improve performance
* in the slowest platforms where pixel alpha blending just doesn't cut it.
*
- * @param blur Intensity/size of the shadow.
+ * @param offset Intensity/size of the shadow.
*/
- virtual void drawSquareShadow(int x, int y, int w, int h, int blur);
- virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur);
+ virtual void drawSquareShadow(int x, int y, int w, int h, int offset);
+ virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset);
/**
* Calculates the color gradient on a given point.
@@ -292,10 +300,12 @@ protected:
*/
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
- virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur) {
- Base::drawRoundedSquareShadow(x, y, r, w, h, blur);
-// VectorRenderer::applyConvolutionMatrix(VectorRenderer::kConvolutionHardBlur,
-// Common::Rect(x, y, x + w + blur * 2, y + h + blur * 2));
+ virtual void drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_l, uint8 alpha_r, uint8 alpha_b);
+
+ virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
+
+ virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset) {
+ Base::drawRoundedSquareShadow(x, y, r, w, h, offset);
}
virtual void drawTabAlg(int x, int y, int w, int h, int r,
diff --git a/graphics/decoders/bmp.cpp b/graphics/decoders/bmp.cpp
index bcfd0abbda..2eabbb7631 100644
--- a/graphics/decoders/bmp.cpp
+++ b/graphics/decoders/bmp.cpp
@@ -130,14 +130,14 @@ bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) {
const int extraDataLength = (srcPitch % 4) ? 4 - (srcPitch % 4) : 0;
if (bitsPerPixel == 8) {
- byte *dst = (byte *)_surface->pixels;
+ byte *dst = (byte *)_surface->getPixels();
for (int32 i = 0; i < height; i++) {
stream.read(dst + (height - i - 1) * width, width);
stream.skip(extraDataLength);
}
} else if (bitsPerPixel == 24) {
- byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch;
+ byte *dst = (byte *)_surface->getBasePtr(0, height - 1);
for (int32 i = 0; i < height; i++) {
for (uint32 j = 0; j < width; j++) {
@@ -154,7 +154,7 @@ bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) {
dst -= _surface->pitch * 2;
}
} else { // 32 bpp
- byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch;
+ byte *dst = (byte *)_surface->getBasePtr(0, height - 1);
for (int32 i = 0; i < height; i++) {
for (uint32 j = 0; j < width; j++) {
diff --git a/graphics/decoders/iff.cpp b/graphics/decoders/iff.cpp
index 50c7b4f7de..7b37969fc1 100644
--- a/graphics/decoders/iff.cpp
+++ b/graphics/decoders/iff.cpp
@@ -170,7 +170,7 @@ void IFFDecoder::loadBitmap(Common::SeekableReadStream &stream) {
if (_type == TYPE_ILBM) {
uint32 scanlinePitch = ((_header.width + 15) >> 4) << 1;
byte *scanlines = new byte[scanlinePitch * _header.numPlanes];
- byte *data = (byte *)_surface->pixels;
+ byte *data = (byte *)_surface->getPixels();
for (uint16 i = 0; i < _header.height; ++i) {
byte *scanline = scanlines;
@@ -194,7 +194,7 @@ void IFFDecoder::loadBitmap(Common::SeekableReadStream &stream) {
delete[] scanlines;
} else if (_type == TYPE_PBM) {
- byte *data = (byte *)_surface->pixels;
+ byte *data = (byte *)_surface->getPixels();
uint32 outSize = _header.width * _header.height;
if (_header.compression) {
diff --git a/graphics/decoders/jpeg.cpp b/graphics/decoders/jpeg.cpp
index 75fdcd6e5a..ff018c799a 100644
--- a/graphics/decoders/jpeg.cpp
+++ b/graphics/decoders/jpeg.cpp
@@ -81,7 +81,7 @@ const Surface *JPEGDecoder::getSurface() const {
const Graphics::Surface *uComponent = getComponent(2);
const Graphics::Surface *vComponent = getComponent(3);
- YUVToRGBMan.convert444(_rgbSurface, Graphics::YUVToRGBManager::kScaleFull, (byte *)yComponent->pixels, (byte *)uComponent->pixels, (byte *)vComponent->pixels, yComponent->w, yComponent->h, yComponent->pitch, uComponent->pitch);
+ YUVToRGBMan.convert444(_rgbSurface, Graphics::YUVToRGBManager::kScaleFull, (const byte *)yComponent->getPixels(), (const byte *)uComponent->getPixels(), (const byte *)vComponent->getPixels(), yComponent->w, yComponent->h, yComponent->pitch, uComponent->pitch);
return _rgbSurface;
}
diff --git a/graphics/decoders/pcx.cpp b/graphics/decoders/pcx.cpp
index 1250398c73..eb9b4c997d 100644
--- a/graphics/decoders/pcx.cpp
+++ b/graphics/decoders/pcx.cpp
@@ -117,7 +117,7 @@ bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) {
if (nPlanes == 3 && bitsPerPixel == 8) { // 24bpp
Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
_surface->create(width, height, format);
- dst = (byte *)_surface->pixels;
+ dst = (byte *)_surface->getPixels();
_paletteColorCount = 0;
for (y = 0; y < height; y++) {
@@ -135,7 +135,7 @@ bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) {
}
} else if (nPlanes == 1 && bitsPerPixel == 8) { // 8bpp indexed
_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- dst = (byte *)_surface->pixels;
+ dst = (byte *)_surface->getPixels();
_paletteColorCount = 16;
for (y = 0; y < height; y++, dst += _surface->pitch) {
@@ -163,7 +163,7 @@ bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) {
}
} else if ((nPlanes == 2 || nPlanes == 3 || nPlanes == 4) && bitsPerPixel == 1) { // planar, 4, 8 or 16 colors
_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- dst = (byte *)_surface->pixels;
+ dst = (byte *)_surface->getPixels();
_paletteColorCount = 16;
for (y = 0; y < height; y++, dst += _surface->pitch) {
diff --git a/graphics/decoders/pict.cpp b/graphics/decoders/pict.cpp
index b1d408ebc3..f3e17b33e2 100644
--- a/graphics/decoders/pict.cpp
+++ b/graphics/decoders/pict.cpp
@@ -364,7 +364,7 @@ void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool withPa
case 1:
// Just copy to the image
_outputSurface->create(width, height, PixelFormat::createFormatCLUT8());
- memcpy(_outputSurface->pixels, buffer, _outputSurface->w * _outputSurface->h);
+ memcpy(_outputSurface->getPixels(), buffer, _outputSurface->w * _outputSurface->h);
break;
case 2:
// We have a 16-bit surface
diff --git a/graphics/decoders/png.cpp b/graphics/decoders/png.cpp
index 11e26162eb..505475213f 100644
--- a/graphics/decoders/png.cpp
+++ b/graphics/decoders/png.cpp
@@ -164,7 +164,7 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
png_set_packing(pngPtr);
} else {
_outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
- if (!_outputSurface->pixels) {
+ if (!_outputSurface->getPixels()) {
error("Could not allocate memory for output image.");
}
if (bitDepth == 16)
diff --git a/graphics/decoders/tga.cpp b/graphics/decoders/tga.cpp
index c3b9d84055..a9f136d238 100644
--- a/graphics/decoders/tga.cpp
+++ b/graphics/decoders/tga.cpp
@@ -272,7 +272,7 @@ bool TGADecoder::readData(Common::SeekableReadStream &tga, byte imageType, byte
} else if (imageType == TYPE_BW) {
_surface.create(_surface.w, _surface.h, _format);
- byte *data = (byte *)_surface.pixels;
+ byte *data = (byte *)_surface.getPixels();
uint32 count = _surface.w * _surface.h;
while (count-- > 0) {
@@ -318,7 +318,7 @@ bool TGADecoder::readDataRLE(Common::SeekableReadStream &tga, byte imageType, by
if (imageType == TYPE_RLE_TRUECOLOR || imageType == TYPE_RLE_BW || imageType == TYPE_RLE_CMAP) {
_surface.create(_surface.w, _surface.h, _format);
uint32 count = _surface.w * _surface.h;
- byte *data = (byte *)_surface.pixels;
+ byte *data = (byte *)_surface.getPixels();
while (count > 0) {
uint32 header = tga.readByte();
diff --git a/graphics/font.cpp b/graphics/font.cpp
index 3b00cd8568..a852274b06 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -128,7 +128,7 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
w = getCharWidth(cur);
if (x+w > rightX)
break;
- if (x >= leftX)
+ if (x+w >= leftX)
drawChar(dst, str[i], x, y, color);
x += w;
}
diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index 6d4befa37c..e523a36ad5 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -102,7 +102,7 @@ void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const
// equal to 50 and the decision of the theme designer?
// asserting _data.maxAdvance <= 50: let the theme designer decide what looks best
assert(_data.maxAdvance <= 50);
- assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2);
+ assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
const int idx = mapToIndex(chr);
if (idx < 0)
@@ -165,6 +165,8 @@ void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const
drawCharIntern<byte>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
else if (dst->format.bytesPerPixel == 2)
drawCharIntern<uint16>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
+ else if (dst->format.bytesPerPixel == 4)
+ drawCharIntern<uint32>(ptr, dst->pitch, src, height, originalWidth, xStart, xEnd, color);
}
namespace {
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index 2b1dca1eae..b9e9610d77 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -322,7 +322,7 @@ void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const
int w = glyph.image.w;
int h = glyph.image.h;
- const uint8 *srcPos = (const uint8 *)glyph.image.getBasePtr(0, 0);
+ const uint8 *srcPos = (const uint8 *)glyph.image.getPixels();
// Make sure we are not drawing outside the screen bounds
if (x < 0) {
@@ -422,7 +422,7 @@ bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
srcPitch = -srcPitch;
}
- uint8 *dst = (uint8 *)glyph.image.getBasePtr(0, 0);
+ uint8 *dst = (uint8 *)glyph.image.getPixels();
memset(dst, 0, glyph.image.h * glyph.image.pitch);
switch (bitmap.pixel_mode) {
diff --git a/graphics/scaler.h b/graphics/scaler.h
index 54d022d202..1e5b796631 100644
--- a/graphics/scaler.h
+++ b/graphics/scaler.h
@@ -89,10 +89,4 @@ extern bool createThumbnailFromScreen(Graphics::Surface *surf);
*/
extern bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette);
-/**
- * Downscale screenshot to thumbnale size.
- *
- */
-extern bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in);
-
#endif
diff --git a/graphics/scaler/thumbnail_intern.cpp b/graphics/scaler/thumbnail_intern.cpp
index 8a98263eee..c30fc3b6fd 100644
--- a/graphics/scaler/thumbnail_intern.cpp
+++ b/graphics/scaler/thumbnail_intern.cpp
@@ -42,8 +42,10 @@ uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) {
template<int bitFormat>
void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
- assert(width % 2 == 0);
- assert(height % 2 == 0);
+ // Make sure the width and height is a multiple of 2.
+ width &= ~1;
+ height &= ~1;
+
for (int y = 0; y < height; y += 2) {
for (int x = 0; x < width; x += 2, dstPtr += 2) {
*((uint16 *)dstPtr) = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch);
@@ -55,8 +57,10 @@ void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32
template<int bitFormat>
void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
- assert(width % 4 == 0);
- assert(height % 4 == 0);
+ // Make sure the width and height is a multiple of 4
+ width &= ~3;
+ height &= ~3;
+
for (int y = 0; y < height; y += 4) {
for (int x = 0; x < width; x += 4, dstPtr += 2) {
uint16 upleft = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch);
@@ -71,17 +75,87 @@ void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32
}
}
-static void createThumbnail(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
- // only 1/2 and 1/4 downscale supported
- if (width != 320 && width != 640)
- return;
+static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) {
+ while (in.w / out.w >= 4 || in.h / out.h >= 4) {
+ createThumbnail_4<565>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h);
+ in.w /= 4;
+ in.h /= 4;
+ }
+
+ while (in.w / out.w >= 2 || in.h / out.h >= 2) {
+ createThumbnail_2<565>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h);
+ in.w /= 2;
+ in.h /= 2;
+ }
+
+ if ((in.w == out.w && in.h < out.h) || (in.w < out.w && in.h == out.h)) {
+ // In this case we simply center the input surface in the output
+ uint8 *dst = (uint8 *)out.getBasePtr((out.w - in.w) / 2, (out.h - in.h) / 2);
+ const uint8 *src = (const uint8 *)in.getPixels();
+
+ for (int y = 0; y < in.h; ++y) {
+ memcpy(dst, src, in.w * in.format.bytesPerPixel);
+ src += in.pitch;
+ dst += out.pitch;
+ }
+ } else {
+ // Assure the aspect of the scaled image still matches the original.
+ int targetWidth = out.w, targetHeight = out.h;
+
+ const float inputAspect = (float)in.w / in.h;
+ const float outputAspect = (float)out.w / out.h;
+
+ if (inputAspect > outputAspect) {
+ targetHeight = int(targetWidth / inputAspect);
+ } else if (inputAspect < outputAspect) {
+ targetWidth = int(targetHeight * inputAspect);
+ }
- int downScaleMode = (width == 320) ? 2 : 4;
+ // Make sure we are still in the bounds of the output
+ assert(targetWidth <= out.w);
+ assert(targetHeight <= out.h);
+
+ // Center the image on the output surface
+ byte *dst = (byte *)out.getBasePtr((out.w - targetWidth) / 2, (out.h - targetHeight) / 2);
+ const uint dstLineIncrease = out.pitch - targetWidth * out.format.bytesPerPixel;
+
+ const float scaleFactorX = (float)targetWidth / in.w;
+ const float scaleFactorY = (float)targetHeight / in.h;
+
+ for (int y = 0; y < targetHeight; ++y) {
+ const float yFrac = (y / scaleFactorY);
+ const int y1 = (int)yFrac;
+ const int y2 = (y1 + 1 < in.h) ? (y1 + 1) : (in.h - 1);
+
+ for (int x = 0; x < targetWidth; ++x) {
+ const float xFrac = (x / scaleFactorX);
+ const int x1 = (int)xFrac;
+ const int x2 = (x1 + 1 < in.w) ? (x1 + 1) : (in.w - 1);
+
+ // Look up colors at the points
+ uint8 p1R, p1G, p1B;
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x1, y1)), p1R, p1G, p1B);
+ uint8 p2R, p2G, p2B;
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x2, y1)), p2R, p2G, p2B);
+ uint8 p3R, p3G, p3B;
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x1, y2)), p3R, p3G, p3B);
+ uint8 p4R, p4G, p4B;
+ Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x2, y2)), p4R, p4G, p4B);
+
+ const float xDiff = xFrac - x1;
+ const float yDiff = yFrac - y1;
+
+ uint8 pR = (uint8)((1 - yDiff) * ((1 - xDiff) * p1R + xDiff * p2R) + yDiff * ((1 - xDiff) * p3R + xDiff * p4R));
+ uint8 pG = (uint8)((1 - yDiff) * ((1 - xDiff) * p1G + xDiff * p2G) + yDiff * ((1 - xDiff) * p3G + xDiff * p4G));
+ uint8 pB = (uint8)((1 - yDiff) * ((1 - xDiff) * p1B + xDiff * p2B) + yDiff * ((1 - xDiff) * p3B + xDiff * p4B));
+
+ WRITE_UINT16(dst, Graphics::RGBToColor<Graphics::ColorMasks<565> >(pR, pG, pB));
+ dst += 2;
+ }
- if (downScaleMode == 2) {
- createThumbnail_2<565>(src, srcPitch, dstPtr, dstPitch, width, height);
- } else if (downScaleMode == 4) {
- createThumbnail_4<565>(src, srcPitch, dstPtr, dstPitch, width, height);
+ // Move to the next line
+ dst = (byte *)dst + dstLineIncrease;
+ }
}
}
@@ -90,7 +164,7 @@ static void createThumbnail(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, ui
* Copies the current screen contents to a new surface, using RGB565 format.
* WARNING: surf->free() must be called by the user to avoid leaking.
*
- * @param surf the surface to store the data in it
+ * @param surf the surface to store the data in it
*/
static bool grabScreen565(Graphics::Surface *surf) {
Graphics::Surface *screen = g_system->lockScreen();
@@ -98,7 +172,7 @@ static bool grabScreen565(Graphics::Surface *surf) {
return false;
assert(screen->format.bytesPerPixel == 1 || screen->format.bytesPerPixel == 2);
- assert(screen->pixels != 0);
+ assert(screen->getPixels() != 0);
Graphics::PixelFormat screenFormat = g_system->getScreenFormat();
@@ -116,15 +190,16 @@ static bool grabScreen565(Graphics::Surface *surf) {
byte r = 0, g = 0, b = 0;
if (screenFormat.bytesPerPixel == 1) {
- r = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3];
- g = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3 + 1];
- b = palette[((uint8 *)screen->pixels)[y * screen->pitch + x] * 3 + 2];
+ uint8 pixel = *(uint8 *)screen->getBasePtr(x, y);
+ r = palette[pixel * 3 + 0];
+ g = palette[pixel * 3 + 1];
+ b = palette[pixel * 3 + 2];
} else if (screenFormat.bytesPerPixel == 2) {
uint16 col = READ_UINT16(screen->getBasePtr(x, y));
screenFormat.colorToRGB(col, r, g, b);
}
- ((uint16 *)surf->pixels)[y * surf->w + x] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ *((uint16 *)surf->getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
}
}
@@ -134,75 +209,17 @@ static bool grabScreen565(Graphics::Surface *surf) {
return true;
}
-bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) {
- uint16 width = in.w;
- uint16 inHeight = in.h;
-
- if (width < 320) {
- // Special case to handle MM NES (uses a screen width of 256)
- width = 320;
-
- // center MM NES screen
- Graphics::Surface newscreen;
- newscreen.create(width, in.h, in.format);
-
- uint8 *dst = (uint8 *)newscreen.getBasePtr((320 - in.w) / 2, 0);
- const uint8 *src = (const uint8 *)in.getBasePtr(0, 0);
- uint16 height = in.h;
-
- while (height--) {
- memcpy(dst, src, in.pitch);
- dst += newscreen.pitch;
- src += in.pitch;
- }
-
- in.free();
- in = newscreen;
- } else if (width == 720) {
- // Special case to handle Hercules mode
- //
- // NOTE: This code is pretty SCUMM specific.
- // For other games this code might cut off
- // not only the menu, but also other graphics.
- width = 640;
- inHeight = 400;
-
- // cut off menu and so on..
- Graphics::Surface newscreen;
- newscreen.create(width, 400, in.format);
-
- uint8 *dst = (uint8 *)newscreen.getBasePtr(0, (400 - 240) / 2);
- const uint8 *src = (const uint8 *)in.getBasePtr(41, 28);
-
- for (int y = 0; y < 240; ++y) {
- memcpy(dst, src, 640 * in.format.bytesPerPixel);
- dst += newscreen.pitch;
- src += in.pitch;
- }
-
- in.free();
- in = newscreen;
- } else if (width == 640 && inHeight == 440) {
- // Special case to handle KQ6 Windows: resize the screen to 640x480,
- // adding a black band in the bottom.
- inHeight = 480;
-
- Graphics::Surface newscreen;
- newscreen.create(width, 480, in.format);
-
- memcpy(newscreen.getBasePtr(0, 0), in.getBasePtr(0, 0), width * 440 * in.format.bytesPerPixel);
-
- in.free();
- in = newscreen;
+static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) {
+ int height;
+ if ((in.w == 320 && in.h == 200) || (in.w == 640 && in.h == 400)) {
+ height = kThumbnailHeight1;
+ } else {
+ height = kThumbnailHeight2;
}
- uint16 newHeight = !(inHeight % 240) ? kThumbnailHeight2 : kThumbnailHeight1;
-
- out.create(kThumbnailWidth, newHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
- createThumbnail((const uint8 *)in.pixels, width * sizeof(uint16), (uint8 *)out.pixels, out.pitch, width, inHeight);
-
+ out.create(kThumbnailWidth, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ scaleThumbnail(in, out);
in.free();
-
return true;
}
@@ -230,7 +247,7 @@ bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h,
g = palette[pixels[y * w + x] * 3 + 1];
b = palette[pixels[y * w + x] * 3 + 2];
- ((uint16 *)screen.pixels)[y * screen.w + x] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ *((uint16 *)screen.getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
}
}
@@ -256,7 +273,7 @@ bool createScreenShot(Graphics::Surface &surf) {
byte r = 0, g = 0, b = 0, a = 0;
uint32 col = READ_UINT32(screen->getBasePtr(x, y));
screenFormat.colorToARGB(col, a, r, g, b);
- ((uint32 *)surf.pixels)[y * surf.w + x] = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b);
+ *((uint32 *)surf.getBasePtr(x, y)) = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b);
}
}
g_system->unlockScreen();
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 41ae8dcebb..929157203e 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -82,9 +82,55 @@ void Surface::free() {
format = PixelFormat();
}
+void Surface::init(uint16 width, uint16 height, uint16 newPitch, void *newPixels, const PixelFormat &f) {
+ w = width;
+ h = height;
+ pitch = newPitch;
+ pixels = newPixels;
+ format = f;
+}
+
void Surface::copyFrom(const Surface &surf) {
create(surf.w, surf.h, surf.format);
- memcpy(pixels, surf.pixels, h * pitch);
+ if (surf.pitch == pitch) {
+ memcpy(pixels, surf.pixels, h * pitch);
+ } else {
+ const byte *src = (const byte *)surf.pixels;
+ byte *dst = (byte *)pixels;
+ for (int y = h; y > 0; --y) {
+ memcpy(dst, src, w * format.bytesPerPixel);
+ src += surf.pitch;
+ dst += pitch;
+ }
+ }
+}
+
+Surface Surface::getSubArea(const Common::Rect &area) {
+ Common::Rect effectiveArea(area);
+ effectiveArea.clip(w, h);
+
+ Surface subSurface;
+ subSurface.w = effectiveArea.width();
+ subSurface.h = effectiveArea.height();
+ subSurface.pitch = pitch;
+ subSurface.pixels = getBasePtr(area.left, area.top);
+ subSurface.format = format;
+ return subSurface;
+}
+
+const Surface Surface::getSubArea(const Common::Rect &area) const {
+ Common::Rect effectiveArea(area);
+ effectiveArea.clip(w, h);
+
+ Surface subSurface;
+ subSurface.w = effectiveArea.width();
+ subSurface.h = effectiveArea.height();
+ subSurface.pitch = pitch;
+ // We need to cast the const away here because a Surface always has a
+ // pointer to modifiable pixel data.
+ subSurface.pixels = const_cast<void *>(getBasePtr(area.left, area.top));
+ subSurface.format = format;
+ return subSurface;
}
void Surface::hLine(int x, int y, int x2, uint32 color) {
diff --git a/graphics/surface.h b/graphics/surface.h
index 6c9e464657..b08d4a5cb7 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -61,11 +61,13 @@ struct Surface {
*/
uint16 pitch;
+protected:
/**
* The surface's pixel data.
*/
void *pixels;
+public:
/**
* The pixel format of the surface.
*/
@@ -78,6 +80,33 @@ struct Surface {
}
/**
+ * Return a pointer to the pixel data.
+ *
+ * @return Pointer to the pixel data.
+ */
+ inline const void *getPixels() const {
+ return pixels;
+ }
+
+ /**
+ * Return a pointer to the pixel data.
+ *
+ * @return Pointer to the pixel data.
+ */
+ inline void *getPixels() {
+ return pixels;
+ }
+
+ /**
+ * Sets the pixel data.
+ *
+ * Note that this is a simply a setter. Be careful what you are doing!
+ *
+ * @param newPixels The new pixel data.
+ */
+ void setPixels(void *newPixels) { pixels = newPixels; }
+
+ /**
* Return a pointer to the pixel at the specified point.
*
* @param x The x coordinate of the pixel.
@@ -122,6 +151,20 @@ struct Surface {
void free();
/**
+ * Set up the Surface with user specified data.
+ *
+ * Note that this simply sets the 'internal' attributes of the Surface. It
+ * will not take care of freeing old data via free or similar!
+ *
+ * @param width Width of the pixel data.
+ * @param height Height of the pixel data.
+ * @param pitch The pitch of the pixel data.
+ * @param pixels The pixel data itself.
+ * @param format The pixel format of the pixel data.
+ */
+ void init(uint16 width, uint16 height, uint16 pitch, void *pixels, const PixelFormat &format);
+
+ /**
* Copy the data from another Surface.
*
* Note that this calls free on the current surface, to assure it being
@@ -135,10 +178,42 @@ struct Surface {
void copyFrom(const Surface &surf);
/**
+ * Creates a Surface which represents a sub-area of this Surface object.
+ *
+ * The pixel (0, 0) of the returned Surface will be the same as Pixel
+ * (area.x, area.y) of this Surface. Changes to any of the Surface objects
+ * will change the shared pixel data.
+ *
+ * Note that the Surface returned is only valid as long as this Surface
+ * object is still alive (i.e. its pixel data is not destroyed or
+ * reallocated). Do *never* try to free the returned Surface.
+ *
+ * @param area The area which should be represented. Note that the area
+ * will get clipped in case it does not fit!
+ */
+ Surface getSubArea(const Common::Rect &area);
+
+ /**
+ * Creates a Surface which represents a sub-area of this Surface object.
+ *
+ * The pixel (0, 0) of the returned Surface will be the same as Pixel
+ * (area.x, area.y) of this Surface.
+ *
+ * Note that the Surface returned is only valid as long as this Surface
+ * object is still alive (i.e. its pixel data is not destroyed or
+ * reallocated). Do *never* try to free the returned Surface.
+ *
+ * @param area The area which should be represented. Note that the area
+ * will get clipped in case it does not fit!
+ */
+ const Surface getSubArea(const Common::Rect &area) const;
+
+ /**
* Convert the data to another pixel format.
*
* This works in-place. This means it will not create an additional buffer
- * for the conversion process. The value of pixels might change though.
+ * for the conversion process. The value of 'pixels' might change though
+ * (that means it might realloc the pixel data).
*
* Note that you should only use this, when you created the Surface data via
* create! Otherwise this function has undefined behavior.
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp
index d04c218624..e3f368dffa 100644
--- a/graphics/thumbnail.cpp
+++ b/graphics/thumbnail.cpp
@@ -43,7 +43,16 @@ struct ThumbnailHeader {
#define ThumbnailHeaderSize (4+4+1+2+2+(1+4+4))
-bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) {
+enum HeaderState {
+ /// There is no header present
+ kHeaderNone,
+ /// The header present only has reliable values for version and size
+ kHeaderUnsupported,
+ /// The header is present and the version is supported
+ kHeaderPresent
+};
+
+HeaderState loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) {
header.type = in.readUint32BE();
// We also accept the bad 'BMHT' header here, for the sake of compatibility
// with some older savegames which were written incorrectly due to a bug in
@@ -51,16 +60,28 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou
if (header.type != MKTAG('T','H','M','B') && header.type != MKTAG('B','M','H','T')) {
if (outputWarnings)
warning("couldn't find thumbnail header type");
- return false;
+ return kHeaderNone;
}
header.size = in.readUint32BE();
header.version = in.readByte();
+ // Do a check whether any read errors had occured. If so we cannot use the
+ // values obtained for size and version because they might be bad.
+ if (in.err() || in.eos()) {
+ // TODO: We fake that there is no header. This is actually not quite
+ // correct since we found the start of the header and then things
+ // started to break. Right no we leave detection of this to the client.
+ // Since this case is caused by broken files, the client code should
+ // catch it anyway... If there is a nicer solution here, we should
+ // implement it.
+ return kHeaderNone;
+ }
+
if (header.version > THMB_VERSION) {
if (outputWarnings)
warning("trying to load a newer thumbnail version: %d instead of %d", header.version, THMB_VERSION);
- return false;
+ return kHeaderUnsupported;
}
header.width = in.readUint16BE();
@@ -82,7 +103,15 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou
header.format = createPixelFormat<565>();
}
- return true;
+ if (in.err() || in.eos()) {
+ // When we reached this point we know that at least the size and
+ // version field was loaded successfully, thus we tell this header
+ // is not supported and silently hope that the client code is
+ // prepared to handle read errors.
+ return kHeaderUnsupported;
+ } else {
+ return kHeaderPresent;
+ }
}
} // end of anonymous namespace
@@ -90,7 +119,12 @@ bool checkThumbnailHeader(Common::SeekableReadStream &in) {
uint32 position = in.pos();
ThumbnailHeader header;
- bool hasHeader = loadHeader(in, header, false);
+ // TODO: It is not clear whether this is the best semantics. Now
+ // checkThumbnailHeader will return true even when the thumbnail header
+ // found is actually not usable. However, most engines seem to use this
+ // to detect the presence of any header and if there is none it wont even
+ // try to skip it. Thus, this looks like the best solution for now...
+ bool hasHeader = (loadHeader(in, header, false) != kHeaderNone);
in.seek(position, SEEK_SET);
@@ -101,7 +135,9 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
uint32 position = in.pos();
ThumbnailHeader header;
- if (!loadHeader(in, header, false)) {
+ // We can skip unsupported and supported headers. So we only seek back
+ // to the old position in case there is no header at all.
+ if (loadHeader(in, header, false) == kHeaderNone) {
in.seek(position, SEEK_SET);
return false;
}
@@ -111,10 +147,23 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
}
Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
+ const uint32 position = in.pos();
ThumbnailHeader header;
-
- if (!loadHeader(in, header, true))
+ HeaderState headerState = loadHeader(in, header, true);
+
+ // Try to handle unsupported/broken headers gracefully. If there is no
+ // header at all, we seek back and return at this point. If there is an
+ // unsupported/broken header, we skip the actual data and return. The
+ // downside is that we might reset the end of stream flag with this and
+ // the client code would not be able to notice a read past the end of the
+ // stream at this point then.
+ if (headerState == kHeaderNone) {
+ in.seek(position, SEEK_SET);
+ return 0;
+ } else if (headerState == kHeaderUnsupported) {
+ in.seek(header.size - (in.pos() - position), SEEK_CUR);
return 0;
+ }
if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) {
warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel);
diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp
index 6043315a13..2a485fa664 100644
--- a/graphics/yuv_to_rgb.cpp
+++ b/graphics/yuv_to_rgb.cpp
@@ -229,7 +229,7 @@ void convertYUV444ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup
void YUVToRGBManager::convert444(Graphics::Surface *dst, YUVToRGBManager::LuminanceScale scale, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) {
// Sanity checks
- assert(dst && dst->pixels);
+ assert(dst && dst->getPixels());
assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(ySrc && uSrc && vSrc);
@@ -237,9 +237,9 @@ void YUVToRGBManager::convert444(Graphics::Surface *dst, YUVToRGBManager::Lumina
// Use a templated function to avoid an if check on every pixel
if (dst->format.bytesPerPixel == 2)
- convertYUV444ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV444ToRGB<uint16>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
else
- convertYUV444ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV444ToRGB<uint32>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
}
template<typename PixelInt>
@@ -283,7 +283,7 @@ void convertYUV420ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup
void YUVToRGBManager::convert420(Graphics::Surface *dst, YUVToRGBManager::LuminanceScale scale, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) {
// Sanity checks
- assert(dst && dst->pixels);
+ assert(dst && dst->getPixels());
assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(ySrc && uSrc && vSrc);
assert((yWidth & 1) == 0);
@@ -293,9 +293,9 @@ void YUVToRGBManager::convert420(Graphics::Surface *dst, YUVToRGBManager::Lumina
// Use a templated function to avoid an if check on every pixel
if (dst->format.bytesPerPixel == 2)
- convertYUV420ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV420ToRGB<uint16>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
else
- convertYUV420ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV420ToRGB<uint32>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
}
#define READ_QUAD(ptr, prefix) \
@@ -368,7 +368,7 @@ void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup
void YUVToRGBManager::convert410(Graphics::Surface *dst, YUVToRGBManager::LuminanceScale scale, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) {
// Sanity checks
- assert(dst && dst->pixels);
+ assert(dst && dst->getPixels());
assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(ySrc && uSrc && vSrc);
assert((yWidth & 3) == 0);
@@ -378,9 +378,9 @@ void YUVToRGBManager::convert410(Graphics::Surface *dst, YUVToRGBManager::Lumina
// Use a templated function to avoid an if check on every pixel
if (dst->format.bytesPerPixel == 2)
- convertYUV410ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV410ToRGB<uint16>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
else
- convertYUV410ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ convertYUV410ToRGB<uint32>((byte *)dst->getPixels(), dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
}
} // End of namespace Graphics
diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp
index 47358a0b3d..21152dd079 100644
--- a/gui/EventRecorder.cpp
+++ b/gui/EventRecorder.cpp
@@ -23,12 +23,12 @@
#include "gui/EventRecorder.h"
+#ifdef ENABLE_EVENTRECORDER
+
namespace Common {
DECLARE_SINGLETON(GUI::EventRecorder);
}
-#ifdef ENABLE_EVENTRECORDER
-
#include "common/debug-channels.h"
#include "backends/timer/sdl/sdl-timer.h"
#include "backends/mixer/sdl/sdl-mixer.h"
@@ -77,6 +77,19 @@ EventRecorder::EventRecorder() {
_initialized = false;
_needRedraw = false;
_fastPlayback = false;
+
+ _fakeTimer = 0;
+ _savedState = false;
+ _needcontinueGame = false;
+ _temporarySlot = 0;
+ _realSaveManager = 0;
+ _realMixerManager = 0;
+ _controlPanel = 0;
+ _lastMillis = 0;
+ _lastScreenshotTime = 0;
+ _screenshotPeriod = 0;
+ _playbackFile = 0;
+
DebugMan.addDebugChannel(kDebugLevelEventRec, "EventRec", "Event recorder debug level");
}
@@ -96,8 +109,8 @@ void EventRecorder::deinit() {
_recordMode = kPassthrough;
delete _fakeMixerManager;
_fakeMixerManager = NULL;
- controlPanel->close();
- delete controlPanel;
+ _controlPanel->close();
+ delete _controlPanel;
debugC(1, kDebugLevelEventRec, "playback:action=stopplayback");
g_system->getEventManager()->getEventDispatcher()->unregisterSource(this);
_recordMode = kPassthrough;
@@ -127,7 +140,7 @@ void EventRecorder::processMillis(uint32 &millis, bool skipRecord) {
millisDelay = millis - _lastMillis;
_lastMillis = millis;
_fakeTimer += millisDelay;
- controlPanel->setReplayedTime(_fakeTimer);
+ _controlPanel->setReplayedTime(_fakeTimer);
timerEvent.recordedtype = Common::kRecorderEventTypeTimer;
timerEvent.time = _fakeTimer;
_playbackFile->writeEvent(timerEvent);
@@ -150,7 +163,7 @@ void EventRecorder::processMillis(uint32 &millis, bool skipRecord) {
}
}
millis = _fakeTimer;
- controlPanel->setReplayedTime(_fakeTimer);
+ _controlPanel->setReplayedTime(_fakeTimer);
break;
case kRecorderPlaybackPause:
millis = _fakeTimer;
@@ -173,7 +186,7 @@ void EventRecorder::checkForKeyCode(const Common::Event &event) {
bool EventRecorder::pollEvent(Common::Event &ev) {
if ((_recordMode != kRecorderPlayback) || !_initialized)
return false;
-
+
if ((_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) || (_nextEvent.type == Common::EVENT_INVALID)) {
return false;
}
@@ -209,12 +222,12 @@ void EventRecorder::togglePause() {
case kRecorderRecord:
oldState = _recordMode;
_recordMode = kRecorderPlaybackPause;
- controlPanel->runModal();
+ _controlPanel->runModal();
_recordMode = oldState;
_initialized = true;
break;
case kRecorderPlaybackPause:
- controlPanel->close();
+ _controlPanel->close();
break;
default:
break;
@@ -277,7 +290,7 @@ void EventRecorder::init(Common::String recordFileName, RecordMode mode) {
return;
}
if (_recordMode != kPassthrough) {
- controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord);
+ _controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord);
}
if (_recordMode == kRecorderPlayback) {
applyPlaybackSettings();
@@ -318,7 +331,7 @@ bool EventRecorder::openRecordFile(const Common::String &fileName) {
}
bool EventRecorder::checkGameHash(const ADGameDescription *gameDesc) {
- if ((gameDesc == NULL) && (_playbackFile->getHeader().hashRecords.size() != 0)) {
+ if (_playbackFile->getHeader().hashRecords.size() != 0) {
warning("Engine doesn't contain description table");
return false;
}
@@ -359,8 +372,8 @@ SdlMixerManager *EventRecorder::getMixerManager() {
}
}
-void EventRecorder::getConfigFromDomain(Common::ConfigManager::Domain *domain) {
- for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) {
+void EventRecorder::getConfigFromDomain(const Common::ConfigManager::Domain *domain) {
+ for (Common::ConfigManager::Domain::const_iterator entry = domain->begin(); entry!= domain->end(); ++entry) {
_playbackFile->getHeader().settingsRecords[entry->_key] = entry->_value;
}
}
@@ -373,7 +386,7 @@ void EventRecorder::getConfig() {
void EventRecorder::applyPlaybackSettings() {
- for (Common::StringMap::iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) {
+ for (Common::StringMap::const_iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) {
Common::String currentValue = ConfMan.get(i->_key);
if (currentValue != i->_value) {
ConfMan.set(i->_key, i->_value, ConfMan.kTransientDomain);
@@ -387,7 +400,7 @@ void EventRecorder::applyPlaybackSettings() {
}
void EventRecorder::removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain) {
- for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) {
+ for (Common::ConfigManager::Domain::const_iterator entry = domain->begin(); entry!= domain->end(); ++entry) {
if (_playbackFile->getHeader().settingsRecords.find(entry->_key) == _playbackFile->getHeader().settingsRecords.end()) {
debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" checksettings:key=%s storedvalue=%s currentvalue="" result=different", entry->_key.c_str(), entry->_value.c_str());
domain->erase(entry->_key);
@@ -439,8 +452,8 @@ Common::List<Common::Event> EventRecorder::mapEvent(const Common::Event &ev, Com
return Common::DefaultEventMapper::mapEvent(ev, source);
break;
case kRecorderRecord:
- g_gui.processEvent(evt, controlPanel);
- if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) {
+ g_gui.processEvent(evt, _controlPanel);
+ if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) {
return Common::List<Common::Event>();
} else {
Common::RecorderEvent e;
@@ -453,13 +466,13 @@ Common::List<Common::Event> EventRecorder::mapEvent(const Common::Event &ev, Com
break;
case kRecorderPlaybackPause: {
Common::Event dialogEvent;
- if (controlPanel->isEditDlgVisible()) {
+ if (_controlPanel->isEditDlgVisible()) {
dialogEvent = ev;
} else {
dialogEvent = evt;
}
- g_gui.processEvent(dialogEvent, controlPanel->getActiveDlg());
- if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) {
+ g_gui.processEvent(dialogEvent, _controlPanel->getActiveDlg());
+ if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) {
return Common::List<Common::Event>();
}
return Common::DefaultEventMapper::mapEvent(dialogEvent, source);
@@ -509,7 +522,7 @@ bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5
warning("Can't save screenshot");
return false;
}
- Common::MemoryReadStream bitmapStream((const byte*)screen.pixels, screen.w * screen.h * screen.format.bytesPerPixel);
+ Common::MemoryReadStream bitmapStream((const byte*)screen.getPixels(), screen.w * screen.h * screen.format.bytesPerPixel);
computeStreamMD5(bitmapStream, md5);
return true;
}
@@ -549,7 +562,7 @@ void EventRecorder::preDrawOverlayGui() {
g_system->showOverlay();
g_gui.theme()->clearAll();
g_gui.theme()->openDialog(true, GUI::ThemeEngine::kShadingNone);
- controlPanel->drawDialog();
+ _controlPanel->drawDialog();
g_gui.theme()->finishBuffering();
g_gui.theme()->updateScreen();
_recordMode = oldMode;
diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h
index 3e32d89232..b2a549ece8 100644
--- a/gui/EventRecorder.h
+++ b/gui/EventRecorder.h
@@ -193,13 +193,13 @@ private:
DefaultTimerManager *_timerManager;
RecorderSaveFileManager _fakeSaveManager;
NullSdlMixerManager *_fakeMixerManager;
- GUI::OnScreenDialog *controlPanel;
+ GUI::OnScreenDialog *_controlPanel;
Common::RecorderEvent _nextEvent;
void setFileHeader();
void setGameMd5(const ADGameDescription *gameDesc);
void getConfig();
- void getConfigFromDomain(Common::ConfigManager::Domain *domain);
+ void getConfigFromDomain(const Common::ConfigManager::Domain *domain);
void removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain);
void applyPlaybackSettings();
@@ -233,61 +233,6 @@ private:
} // End of namespace GUI
-#else
-
-#ifdef SDL_BACKEND
-#include "backends/timer/default/default-timer.h"
-#include "backends/mixer/sdl/sdl-mixer.h"
-#endif
-
-#define g_eventRec (GUI::EventRecorder::instance())
-
-namespace GUI {
-
-class EventRecorder : private Common::EventSource, public Common::Singleton<EventRecorder>, private Common::DefaultEventMapper {
- friend class Common::Singleton<SingletonBaseType>;
-
- public:
- EventRecorder() {
-#ifdef SDL_BACKEND
- _timerManager = NULL;
- _realMixerManager = NULL;
-#endif
- }
- ~EventRecorder() {}
-
- bool pollEvent(Common::Event &ev) { return false; }
- void RegisterEventSource() {}
- void deinit() {}
- void suspendRecording() {}
- void resumeRecording() {}
- void preDrawOverlayGui() {}
- void postDrawOverlayGui() {}
- void processGameDescription(const ADGameDescription *desc) {}
- void updateSubsystems() {}
- uint32 getRandomSeed(const Common::String &name) { return g_system->getMillis(); }
- Common::SaveFileManager *getSaveManager(Common::SaveFileManager *realSaveManager) { return realSaveManager; }
-
-#ifdef SDL_BACKEND
- private:
- DefaultTimerManager *_timerManager;
- SdlMixerManager *_realMixerManager;
-
- public:
- DefaultTimerManager *getTimerManager() { return _timerManager; }
- void registerTimerManager(DefaultTimerManager *timerManager) { _timerManager = timerManager; }
-
- SdlMixerManager *getMixerManager() { return _realMixerManager; }
- void registerMixerManager(SdlMixerManager *mixerManager) { _realMixerManager = mixerManager; }
-
- void processMillis(uint32 &millis, bool skipRecord) {}
- bool processDelayMillis() { return false; }
-#endif
-
-};
-
-} // namespace GUI
-
#endif // ENABLE_EVENTRECORDER
#endif
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 3ce043cb39..688654d208 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -122,15 +122,16 @@ protected:
class ThemeItemTextData : public ThemeItem {
public:
- ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::String &text,
- Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
+ ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::Rect &textDrawableArea,
+ const Common::String &text, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
bool ellipsis, bool restoreBg, int deltaX) :
ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV),
- _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {}
+ _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX), _textDrawableArea(textDrawableArea) {}
void drawSelf(bool draw, bool restore);
protected:
+ Common::Rect _textDrawableArea;
const TextDrawData *_data;
const TextColorData *_color;
Common::String _text;
@@ -246,7 +247,7 @@ void ThemeItemTextData::drawSelf(bool draw, bool restore) {
if (draw) {
_engine->renderer()->setFgColor(_color->r, _color->g, _color->b);
- _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis);
+ _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis, _textDrawableArea);
}
_engine->addDirtyRect(_area);
@@ -343,9 +344,9 @@ ThemeEngine::~ThemeEngine() {
*********************************************************/
const ThemeEngine::Renderer ThemeEngine::_rendererModes[] = {
{ _s("Disabled GFX"), _sc("Disabled GFX", "lowres"), "none", kGfxDisabled },
- { _s("Standard Renderer (16bpp)"), _s("Standard (16bpp)"), "normal_16bpp", kGfxStandard16bit },
+ { _s("Standard Renderer"), _s("Standard"), "normal", kGfxStandard },
#ifndef DISABLE_FANCY_THEMES
- { _s("Antialiased Renderer (16bpp)"), _s("Antialiased (16bpp)"), "aa_16bpp", kGfxAntialias16bit }
+ { _s("Antialiased Renderer"), _s("Antialiased"), "antialias", kGfxAntialias }
#endif
};
@@ -353,9 +354,9 @@ const uint ThemeEngine::_rendererModesSize = ARRAYSIZE(ThemeEngine::_rendererMod
const ThemeEngine::GraphicsMode ThemeEngine::_defaultRendererMode =
#ifndef DISABLE_FANCY_THEMES
- ThemeEngine::kGfxAntialias16bit;
+ ThemeEngine::kGfxAntialias;
#else
- ThemeEngine::kGfxStandard16bit;
+ ThemeEngine::kGfxStandard;
#endif
ThemeEngine::GraphicsMode ThemeEngine::findMode(const Common::String &cfg) {
@@ -389,7 +390,7 @@ bool ThemeEngine::init() {
_overlayFormat = _system->getOverlayFormat();
setGraphicsMode(_graphicsMode);
- if (_screen.pixels && _backBuffer.pixels) {
+ if (_screen.getPixels() && _backBuffer.getPixels()) {
_initOk = true;
}
@@ -439,7 +440,7 @@ bool ThemeEngine::init() {
void ThemeEngine::clearAll() {
if (_initOk) {
_system->clearOverlay();
- _system->grabOverlay(_screen.pixels, _screen.pitch);
+ _system->grabOverlay(_screen.getPixels(), _screen.pitch);
}
}
@@ -494,13 +495,17 @@ void ThemeEngine::disable() {
void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
switch (mode) {
- case kGfxStandard16bit:
+ case kGfxStandard:
#ifndef DISABLE_FANCY_THEMES
- case kGfxAntialias16bit:
+ case kGfxAntialias:
#endif
- _bytesPerPixel = sizeof(uint16);
- break;
-
+ if (g_system->getOverlayFormat().bytesPerPixel == 4) {
+ _bytesPerPixel = sizeof(uint32);
+ break;
+ } else if (g_system->getOverlayFormat().bytesPerPixel == 2) {
+ _bytesPerPixel = sizeof(uint16);
+ break;
+ }
default:
error("Invalid graphics mode");
}
@@ -517,6 +522,12 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
delete _vectorRenderer;
_vectorRenderer = Graphics::createRenderer(mode);
_vectorRenderer->setSurface(&_screen);
+
+ // Since we reinitialized our screen surfaces we know nothing has been
+ // drawn so far. Sometimes we still end up with dirty screen bits in the
+ // list. Clearing it avoids invalid overlay writes when the backend
+ // resizes the overlay.
+ _dirtyScreen.clear();
}
void WidgetDrawData::calcBackgroundOffset() {
@@ -832,7 +843,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic,
}
void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
- bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) {
+ bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax, const Common::Rect &drawableTextArea) {
if (_texts[type] == 0)
return;
@@ -840,7 +851,7 @@ void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect
Common::Rect area = r;
area.clip(_screen.w, _screen.h);
- ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, text, alignH, alignV, ellipsis, restoreBg, deltax);
+ ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, drawableTextArea, text, alignH, alignV, ellipsis, restoreBg, deltax);
if (_buffering) {
_screenQueue.push_back(q);
@@ -1111,7 +1122,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
}
}
-void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore) {
+void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore, const Common::Rect &drawableTextArea) {
if (!ready())
return;
@@ -1181,7 +1192,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
break;
}
- queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax);
+ queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
}
void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) {
@@ -1219,7 +1230,7 @@ void ThemeEngine::updateScreen(bool render) {
}
_vectorRenderer->setSurface(&_screen);
- memcpy(_screen.getBasePtr(0, 0), _backBuffer.getBasePtr(0, 0), _screen.pitch * _screen.h);
+ memcpy(_screen.getPixels(), _backBuffer.getPixels(), _screen.pitch * _screen.h);
_bufferQueue.clear();
}
@@ -1287,7 +1298,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h));
}
- memcpy(_backBuffer.getBasePtr(0, 0), _screen.getBasePtr(0, 0), _screen.pitch * _screen.h);
+ memcpy(_backBuffer.getPixels(), _screen.getPixels(), _screen.pitch * _screen.h);
_vectorRenderer->setSurface(&_screen);
}
@@ -1320,22 +1331,31 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
memset(_cursor, 0xFF, sizeof(byte) * _cursorWidth * _cursorHeight);
// the transparent color is 0xFF00FF
- const int colTransparent = _overlayFormat.RGBToColor(0xFF, 0, 0xFF);
+ const uint32 colTransparent = _overlayFormat.RGBToColor(0xFF, 0, 0xFF);
// Now, scan the bitmap. We have to convert it from 16 bit color mode
// to 8 bit mode, and have to create a suitable palette on the fly.
uint colorsFound = 0;
Common::HashMap<int, int> colorToIndex;
- const OverlayColor *src = (const OverlayColor *)cursor->pixels;
+ const byte *src = (const byte *)cursor->getPixels();
for (uint y = 0; y < _cursorHeight; ++y) {
for (uint x = 0; x < _cursorWidth; ++x) {
+ uint32 color = colTransparent;
byte r, g, b;
+ if (cursor->format.bytesPerPixel == 2) {
+ color = READ_UINT16(src);
+ } else if (cursor->format.bytesPerPixel == 4) {
+ color = READ_UINT32(src);
+ }
+
+ src += cursor->format.bytesPerPixel;
+
// Skip transparency
- if (src[x] == colTransparent)
+ if (color == colTransparent)
continue;
- _overlayFormat.colorToRGB(src[x], r, g, b);
+ cursor->format.colorToRGB(color, r, g, b);
const int col = (r << 16) | (g << 8) | b;
// If there is no entry yet for this color in the palette: Add one
@@ -1357,7 +1377,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
const int index = colorToIndex[col];
_cursor[y * _cursorWidth + x] = index;
}
- src += _cursorWidth;
}
_useCursor = true;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 160ceb3259..4dffb13e71 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -29,6 +29,7 @@
#include "common/hashmap.h"
#include "common/list.h"
#include "common/str.h"
+#include "common/rect.h"
#include "graphics/surface.h"
#include "graphics/font.h"
@@ -39,10 +40,6 @@
class OSystem;
-namespace Common {
-struct Rect;
-}
-
namespace Graphics {
struct DrawStep;
class VectorRenderer;
@@ -250,8 +247,8 @@ public:
*/
enum GraphicsMode {
kGfxDisabled = 0, ///< No GFX
- kGfxStandard16bit, ///< 2BPP with the standard (aliased) renderer.
- kGfxAntialias16bit ///< 2BPP with the optimized AA renderer.
+ kGfxStandard, ///< Standard (aliased) renderer.
+ kGfxAntialias ///< Optimized AA renderer.
};
/** Constant value to expand dirty rectangles, to make sure they are fully copied */
@@ -376,7 +373,7 @@ public:
void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled);
- void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true);
+ void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal);
@@ -588,7 +585,7 @@ protected:
*/
void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool restore = false);
void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
- bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0);
+ bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
/**
diff --git a/gui/about.cpp b/gui/about.cpp
index 088971f273..3bb1934e28 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -46,7 +46,7 @@ enum {
// 0 - 2 -- set a custom color:
// 0 normal text
// 1 highlighted text
-// 2 disabled text
+// 2 disabled text
// TODO: Maybe add a tab/indent feature; that is, make it possible to specify
// an amount by which that line shall be indented (the indent of course would have
// to be considered while performing any word wrapping, too).
@@ -139,7 +139,7 @@ void AboutDialog::addLine(const char *str) {
} else {
Common::String format(str, 2);
str += 2;
-
+
static Common::String asciiStr;
if (format[0] == 'A') {
bool useAscii = false;
@@ -180,9 +180,10 @@ void AboutDialog::close() {
}
void AboutDialog::drawDialog() {
-// g_gui.theme()->setDrawArea(Common::Rect(_x, _y, _x+_w, _y+_h));
Dialog::drawDialog();
+ setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h));
+
// Draw text
// TODO: Add a "fade" effect for the top/bottom text lines
// TODO: Maybe prerender all of the text into another surface,
@@ -239,8 +240,8 @@ void AboutDialog::drawDialog() {
while (*str && *str == ' ')
str++;
- if (*str && y > _y && y + g_gui.theme()->getFontHeight() < _y + _h)
- g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false);
+ if (*str)
+ g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
y += _lineHeight;
}
}
diff --git a/gui/chooser.cpp b/gui/chooser.cpp
index 6ae08161df..c195e94c9b 100644
--- a/gui/chooser.cpp
+++ b/gui/chooser.cpp
@@ -67,6 +67,7 @@ void ChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
break;
case kCloseCmd:
setResult(-1);
+ // Fall through
default:
Dialog::handleCommand(sender, cmd, data);
}
diff --git a/gui/credits.h b/gui/credits.h
index 70f79ac9a5..3a4d7769f6 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -170,6 +170,15 @@ static const char *credits[] = {
"C0""Eugene Sandulenko",
"C0""David Turner",
"",
+"C1""Mortevielle",
+"A0""Arnaud Boutonne",
+"C0""Arnaud Boutonn\351",
+"C0""Paul Gilbert",
+"",
+"C1""Neverhood",
+"C0""Benjamin Haisch",
+"C0""Filippos Karapetis",
+"",
"C1""Parallaction",
"C0""peres",
"",
diff --git a/gui/editrecorddialog.cpp b/gui/editrecorddialog.cpp
index a6a7a2560e..cfcc747121 100644
--- a/gui/editrecorddialog.cpp
+++ b/gui/editrecorddialog.cpp
@@ -37,7 +37,7 @@ void EditRecordDialog::setAuthor(const Common::String &author) {
const Common::String EditRecordDialog::getNotes() {
return _notesEdit->getEditString();
-}
+}
void EditRecordDialog::setNotes(const Common::String &desc) {
_notesEdit->setEditString(desc);
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 78b40a46ce..1505c8c707 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -258,8 +258,10 @@ void GuiManager::runLoop() {
if (activeDialog == 0)
return;
+#ifdef ENABLE_EVENTRECORDER
// Suspend recording while GUI is shown
g_eventRec.suspendRecording();
+#endif
if (!_stateIsSaved) {
saveState();
@@ -361,8 +363,10 @@ void GuiManager::runLoop() {
_useStdCursor = false;
}
+#ifdef ENABLE_EVENTRECORDER
// Resume recording once GUI is shown
g_eventRec.resumeRecording();
+#endif
}
#pragma mark -
diff --git a/gui/object.cpp b/gui/object.cpp
index 73c4f74d6c..189a286ead 100644
--- a/gui/object.cpp
+++ b/gui/object.cpp
@@ -29,7 +29,7 @@
namespace GUI {
GuiObject::GuiObject(const Common::String &name)
- : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0) {
+ : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) {
reflowLayout();
}
diff --git a/gui/object.h b/gui/object.h
index bce3cd7846..dac3341b5a 100644
--- a/gui/object.h
+++ b/gui/object.h
@@ -24,6 +24,7 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/rect.h"
namespace GUI {
@@ -59,6 +60,8 @@ class Widget;
class GuiObject : public CommandReceiver {
friend class Widget;
protected:
+ Common::Rect _textDrawableArea;
+
int16 _x, _y;
uint16 _w, _h;
const Common::String _name;
@@ -66,10 +69,12 @@ protected:
Widget *_firstWidget;
public:
- GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0) { }
+ GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { }
GuiObject(const Common::String &name);
~GuiObject();
+ virtual void setTextDrawableArea(const Common::Rect &r) { _textDrawableArea = r; }
+
virtual int16 getAbsX() const { return _x; }
virtual int16 getAbsY() const { return _y; }
virtual int16 getChildX() const { return getAbsX(); }
diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp
index efe8038e68..03a6f26ec0 100644
--- a/gui/onscreendialog.cpp
+++ b/gui/onscreendialog.cpp
@@ -97,26 +97,28 @@ OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") {
} else
#endif
{
- GUI::ButtonWidget *btn;
if (g_system->getOverlayWidth() > 320)
- btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd);
+ new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd);
else
- btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd);
+ new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd);
if (isRecord) {
- btn = new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd);
+ new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd);
} else {
- btn = new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd);
+ new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd);
- btn = new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd);
+ new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd);
}
}
- text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00");
+ _text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00");
_enableDrag = false;
_mouseOver = false;
_editDlgShown = false;
+
+ _lastTime = 0;
+ _dlg = 0;
}
void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
@@ -128,20 +130,20 @@ void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
close();
break;
case kEditCmd:
- dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes());
+ _dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes());
CursorMan.lock(false);
g_eventRec.setRedraw(false);
g_system->showOverlay();
_editDlgShown = true;
- dlg->runModal();
+ _dlg->runModal();
_editDlgShown = false;
g_system->hideOverlay();
g_eventRec.setRedraw(true);
CursorMan.lock(true);
- g_eventRec.setAuthor(((EditRecordDialog *)dlg)->getAuthor());
- g_eventRec.setName(((EditRecordDialog *)dlg)->getName());
- g_eventRec.setNotes(((EditRecordDialog *)dlg)->getNotes());
- delete dlg;
+ g_eventRec.setAuthor(((EditRecordDialog *)_dlg)->getAuthor());
+ g_eventRec.setName(((EditRecordDialog *)_dlg)->getName());
+ g_eventRec.setNotes(((EditRecordDialog *)_dlg)->getNotes());
+ delete _dlg;
break;
case kSwitchModeCmd:
if (g_eventRec.switchMode()) {
@@ -155,10 +157,10 @@ void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
}
void OnScreenDialog::setReplayedTime(uint32 newTime) {
- if (newTime - lastTime > 1000) {
+ if (newTime - _lastTime > 1000) {
uint32 seconds = newTime / 1000;
- text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60));
- lastTime = newTime;
+ _text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60));
+ _lastTime = newTime;
}
}
@@ -218,7 +220,7 @@ void OnScreenDialog::close() {
Dialog *OnScreenDialog::getActiveDlg() {
if (_editDlgShown) {
- return dlg;
+ return _dlg;
} else {
return this;
}
diff --git a/gui/onscreendialog.h b/gui/onscreendialog.h
index 4f3839acb6..2fae14cbc6 100644
--- a/gui/onscreendialog.h
+++ b/gui/onscreendialog.h
@@ -30,14 +30,16 @@ namespace GUI {
class OnScreenDialog : public Dialog {
private:
- uint32 lastTime;
+ uint32 _lastTime;
bool _enableDrag;
bool _mouseOver;
bool _editDlgShown;
Common::Point _dragPoint;
- GUI::StaticTextWidget *text;
- Dialog *dlg;
+ GUI::StaticTextWidget *_text;
+ Dialog *_dlg;
+
bool isMouseOver(int x, int y);
+
public:
OnScreenDialog(bool recordingMode);
~OnScreenDialog();
@@ -56,7 +58,7 @@ public:
bool isEditDlgVisible();
Dialog *getActiveDlg();
protected:
- virtual void releaseFocus();
+ virtual void releaseFocus();
};
} // End of namespace GUI
diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp
index 55f342d4a1..1a11dbac65 100644
--- a/gui/recorderdialog.cpp
+++ b/gui/recorderdialog.cpp
@@ -52,6 +52,12 @@ enum {
};
RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentScreenshot(0) {
+ _firstScreenshotUpdate = false;
+ _screenShotsCount = 0;
+ _currentScreenshotText = 0;
+ _authorText = 0;
+ _notesText = 0;
+
_backgroundType = ThemeEngine::kDialogBackgroundSpecial;
new StaticTextWidget(this, "SaveLoadChooser.Title", _("Recorder or Playback Gameplay"));
@@ -63,7 +69,7 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentS
new GUI::ButtonWidget(this, "RecorderDialog.Cancel", _("Cancel"), 0, kCloseCmd);
new GUI::ButtonWidget(this, "RecorderDialog.Record", _("Record"), 0, kRecordCmd);
_playbackButton = new GUI::ButtonWidget(this, "RecorderDialog.Playback", _("Playback"), 0, kPlaybackCmd);
-
+
_editButton = new GUI::ButtonWidget(this, "RecorderDialog.Edit", _("Edit"), 0, kEditRecordCmd);
_editButton->setEnabled(false);
@@ -74,7 +80,7 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentS
_container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) {
new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", "<", 0, kPrevScreenshotCmd);
- new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd);
+ new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd);
_currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", "0/0");
_authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: "));
_notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: "));
@@ -185,10 +191,11 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
break;
case kCloseCmd:
setResult(kRecordDialogClose);
+ // Fall through
default:
Dialog::handleCommand(sender, cmd, data);
- }
}
+}
void RecorderDialog::updateList() {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp
index c7dd62b6c6..585117fba4 100644
--- a/gui/saveload-dialog.cpp
+++ b/gui/saveload-dialog.cpp
@@ -286,6 +286,7 @@ void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uin
break;
case kCloseCmd:
setResult(-1);
+ // Fall through
default:
SaveLoadChooserDialog::handleCommand(sender, cmd, data);
}
@@ -595,6 +596,7 @@ void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint3
case kCloseCmd:
setResult(-1);
+ // Fall through
default:
SaveLoadChooserDialog::handleCommand(sender, cmd, data);
}
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 1b6ae3ec27..352cc86852 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1,142 +1,142 @@
"<?xml version = '1.0'?>"
-"<render_info> "
-"<palette> "
+"<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> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</drawdata>"
+"<drawdata id='text_selection_focus' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='mainmenu_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='mainmenu_bg' cache='false'>"
"<drawstep func='fill' "
"fill='foreground' "
"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='special_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='special_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='tooltip_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='tooltip_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='foreground' "
"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='separator' cache='false'> "
+"/>"
+"</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'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_base' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_hover' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_handle_hover' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_idle' cache='false'> "
+"/>"
+"</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'> "
+"/>"
+"</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' "
@@ -146,13 +146,13 @@
"ypos='center' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'> "
+"/>"
+"</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' "
@@ -162,13 +162,13 @@
"ypos='center' "
"padding='0,0,2,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'> "
+"/>"
+"</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' "
@@ -178,13 +178,13 @@
"ypos='center' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'> "
+"/>"
+"</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' "
@@ -194,69 +194,69 @@
"ypos='center' "
"padding='0,0,2,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_active' cache='false'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_disabled' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_full' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_full' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_hover' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_hover' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_small' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_idle' cache='false' resolution='y>399'> "
+"/>"
+"</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' "
@@ -266,7 +266,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -276,18 +276,18 @@
"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'> "
+"/>"
+"</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' "
@@ -297,7 +297,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -307,18 +307,18 @@
"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'> "
+"/>"
+"</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' "
@@ -328,7 +328,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -338,18 +338,18 @@
"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'> "
+"/>"
+"</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' "
@@ -359,7 +359,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -369,18 +369,18 @@
"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'> "
+"/>"
+"</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' "
@@ -390,7 +390,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -400,18 +400,18 @@
"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'> "
+"/>"
+"</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' "
@@ -421,7 +421,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -431,123 +431,123 @@
"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'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_textedit' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='plain_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='plain_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='caret' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='caret' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='default_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='default_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_pressed' cache='false'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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'> "
+"/>"
+"</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' "
@@ -556,14 +556,14 @@
"bg_color='darkgrey' "
"xpos='0' "
"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_selected' cache='false'> "
+"/>"
+"</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' "
@@ -572,7 +572,7 @@
"fill='none' "
"xpos='0' "
"ypos='0' "
-"/> "
+"/>"
"<drawstep func='circle' "
"width='7' "
"height='7' "
@@ -581,14 +581,14 @@
"fill='foreground' "
"xpos='2' "
"ypos='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_disabled' cache='false'> "
+"/>"
+"</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' "
@@ -597,2510 +597,2510 @@
"fill='background' "
"xpos='0' "
"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_default' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_default' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
+"/>"
+"</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' /> "
-"<def var='Font.Height' value='16' /> "
-"<def var='About.OuterBorder' value='80'/> "
-"<def var='Layout.Spacing' value='8' /> "
-"<def var='ShowLauncherLogo' value='0'/> "
-"<def var='ShowGlobalMenuLogo' value='0'/> "
-"<def var='ShowSearchPic' value='0'/> "
-"<def var='ShowChooserPics' value='0'/> "
-"<def var='ShowChooserPageDisplay' value='1'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
-"<def var='RecorderDialog.ExtInfo.Visible' value='1'/> "
-"<def var='OnScreenDialog.ShowPics' value='0'/> "
-"<def var='KeyMapper.Spacing' value='10'/> "
-"<def var='KeyMapper.LabelWidth' value='100'/> "
-"<def var='KeyMapper.ButtonWidth' value='80'/> "
-"<def var='Tooltip.MaxWidth' value='200'/> "
+"/>"
+"</drawdata>"
+"</render_info>"
+"<layout_info resolution='y>399'>"
+"<globals>"
+"<def var='Line.Height' value='16' />"
+"<def var='Font.Height' value='16' />"
+"<def var='About.OuterBorder' value='80'/>"
+"<def var='Layout.Spacing' value='8' />"
+"<def var='ShowLauncherLogo' value='0'/>"
+"<def var='ShowGlobalMenuLogo' value='0'/>"
+"<def var='ShowSearchPic' value='0'/>"
+"<def var='ShowChooserPics' value='0'/>"
+"<def var='ShowChooserPageDisplay' value='1'/>"
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/>"
+"<def var='RecorderDialog.ExtInfo.Visible' value='1'/>"
+"<def var='OnScreenDialog.ShowPics' value='0'/>"
+"<def var='KeyMapper.Spacing' value='10'/>"
+"<def var='KeyMapper.LabelWidth' value='100'/>"
+"<def var='KeyMapper.ButtonWidth' value='80'/>"
+"<def var='Tooltip.MaxWidth' value='200'/>"
"<def var='Tooltip.XDelta' value='16'/> "
-"<def var='Tooltip.YDelta' value='16'/> "
-"<def var='Predictive.Button.Width' value='60' /> "
+"<def var='Tooltip.YDelta' value='16'/>"
+"<def var='Predictive.Button.Width' value='60' />"
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='SmallLabel' "
"size='24,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ShortOptionsLabel' "
"size='60,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Button' "
"size='108,24' "
-"/> "
+"/>"
"<widget name='Slider' "
"size='128,18' "
-"/> "
+"/>"
"<widget name='PopUp' "
"size='-1,19' "
-"/> "
+"/>"
"<widget name='Checkbox' "
"size='-1,14' "
-"/> "
+"/>"
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ListWidget' "
"padding='5,0,8,0' "
-"/> "
+"/>"
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
-"/> "
+"/>"
"<widget name='EditTextWidget' "
"padding='5,5,0,0' "
-"/> "
+"/>"
"<widget name='Console' "
"padding='7,5,5,5' "
-"/> "
+"/>"
"<widget name='Scrollbar' "
"size='15,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Tab' "
"size='75,27' "
"padding='0,0,8,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Body' "
"padding='0,0,0,0' "
-"/> "
+"/>"
"<widget name='TabWidget.NavButton' "
"size='15,18' "
"padding='0,3,4,0' "
-"/> "
+"/>"
"<widget name='EditRecordLabel' "
"size='60,25' "
-"/> "
+"/>"
"<widget name='EditRecord' "
"size='240,25' "
-"/> "
-"</globals> "
-"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='16,16,8,8'> "
+"/>"
+"</globals>"
+"<dialog name='Launcher' overlays='screen'>"
+"<layout type='vertical' center='true' padding='16,16,8,8'>"
"<widget name='Version' "
"height='Globals.Line.Height' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='10,0,0,0'>"
"<widget name='SearchDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Search' "
"width='150' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SearchClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space /> "
-"</layout> "
-"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"<space />"
+"</layout>"
+"<widget name='GameList'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='LoadGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='AddGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='EditGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='RemoveGameButton' "
"height='20' "
-"/> "
-"</layout> "
-"<space size='4'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<space size='4'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='QuitButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='AboutButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='OptionsButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='StartButton' "
"height='20' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Path' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
-"<layout type='vertical' padding='0,0,16,0'> "
+"/>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,16,0'>"
"<widget name='Hidden' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Up' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='16,16,16,16'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grModePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grRenderPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='grAspectCheckbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='grFullscreenCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auMidiPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auOPLPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auSampleRatePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='horizontal' padding='16,16,16,16' spacing='8'> "
-"<layout type='vertical' padding='0,0,0,0' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='horizontal' padding='16,16,16,16' spacing='8'>"
+"<layout type='vertical' padding='0,0,0,0' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,0,24,0' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<layout type='vertical' padding='24,0,24,0' center='true'>"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefGmPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='mcFontButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='mcFontPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='mcFontClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='mcMidiGainSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='mcMidiGainLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcFluidSynthSettings' "
"width='200' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefMt32Popup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMt32Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='mcGSCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='SaveButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ThemePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='ExtraButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='PluginsButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='PluginsPath' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='CurTheme' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RendererPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RendererPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='AutosavePeriodPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='GuiLanguagePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeysButton' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Action' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
+"/>"
+"<widget name='List'/>"
"<widget name='Mapping' "
"height='Globals.Line.Height' "
-"/> "
-"<space size='Globals.Line.Height'/> "
-"<layout type='horizontal'> "
+"/>"
+"<space size='Globals.Line.Height'/>"
+"<layout type='horizontal'>"
"<widget name='Map' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,4'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0' spacing='16'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='16,16,16,4'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Graphics' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Graphics' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Audio' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Audio' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MIDI' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MIDI' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MT32' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MT32' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Volume' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Volume' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Id' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Domain' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Name' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Desc' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LangPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LangPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='PlatformPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='PlatformPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Savepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Extrapath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Gamepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='GamepathText' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption2Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption3Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption4Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption5Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption6Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption7Checkbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='16,16,16,16' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalMenu' overlays='screen_center'>"
+"<layout type='vertical' padding='16,16,16,16' center='true'>"
"<widget name='Title' "
"width='210' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Version' "
"width='210' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Resume' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='Load' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Save' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='Options' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Help' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='About' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='RTL' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Quit' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalConfig' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
-"<layout type='vertical' padding='0,0,0,0' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalConfig' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
+"<layout type='vertical' padding='0,0,0,0' center='true'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,24,24,24' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<layout type='vertical' padding='24,24,24,24' center='true'>"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"width='80' "
-"/> "
-"</layout> "
-"</layout> "
-"<space size='8' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"</layout>"
+"<space size='8' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
"width='100' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
"width='100' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
"width='100' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<space size='60'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<space size='60'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='Keys' "
"type='Button' "
-"/> "
-"<space size='Globals.Button.Width' /> "
+"/>"
+"<space size='Globals.Button.Width' />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='16,16,16,16'>"
+"<space/>"
"<widget name='ResetSettings' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='VoiceCountText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='VoiceCountSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='VoiceCountLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='SpeedText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='SpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='SpeedLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DepthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DepthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DepthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WaveFormTypeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WaveFormType' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RoomSizeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RoomSizeSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='RoomSizeLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DampingText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DampingSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DampingLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WidthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WidthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='WidthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='InterpolationText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Interpolation' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,32' center='true'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='PageDisplay' "
"width='200' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
-"<widget name='List' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'>"
+"<widget name='List' />"
"<widget name='Thumbnail' "
"width='180' "
"height='200' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='ListSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GridSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SavenameDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SavenameDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='DescriptionText' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description' "
"height='19' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"<space size='96'/> "
+"/>"
+"<space size='96'/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,32' center='true'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
-"<widget name='List' /> "
-"<layout type='vertical' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'>"
+"<widget name='List' />"
+"<layout type='vertical' padding='0,0,0,0'>"
"<widget name='Thumbnail' "
"width='180' "
"height='170' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='NextScreenShotButton' "
"width='25' "
"height='25' "
-"/> "
+"/>"
"<widget name='currentScreenshot' "
"width='125' "
"height='25' "
"textalign='center' "
-"/> "
+"/>"
"<widget name='PreviousScreenShotButton' "
"width='25' "
"height='25' "
-"/> "
-"</layout> "
-"<widget name='Author' height='Globals.Line.Height' /> "
-"<widget name='Notes' height='Globals.Line.Height' /> "
-"</layout> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<widget name='Author' height='Globals.Line.Height' />"
+"<widget name='Notes' height='Globals.Line.Height' />"
+"</layout>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Edit' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Record' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Playback' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='OnScreenDialog' overlays='screen_center'> "
-"<layout type='horizontal' spacing='5' padding='5,3,5,3' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='OnScreenDialog' overlays='screen_center'>"
+"<layout type='horizontal' spacing='5' padding='5,3,5,3' center='true'>"
"<widget name='StopButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='EditButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='SwitchModeButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='FastReplayButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='TimeLabel' "
"width='50' "
"height='30' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='EditRecordDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='EditRecordDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='AuthorLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='AuthorEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NameLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NameEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NotesLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NotesEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='OK' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='ScummHelp' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='ScummHelp' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='HelpText' "
"height='200' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Prev' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Next' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Description1' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description2' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Standard' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Practice' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Expert' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='MassAdd' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='8,8,32,8' center='true'>"
"<widget name='DirProgressText' "
"width='480' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameProgressText' "
"width='480' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameList' "
"width='480' "
"height='250' "
-"/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
"<widget name='Ok' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeyMapper' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Popup' "
"type='PopUp' "
"width='400' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeymapArea' "
"width='600' "
"height='280' "
-"/> "
+"/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='5,5,5,5' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='Predictive' overlays='screen_center'>"
+"<layout type='vertical' padding='5,5,5,5' center='true'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
"width='210' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' padding='5,5,5,5'> "
+"/>"
+"<layout type='horizontal' padding='5,5,5,5'>"
"<widget name='Word' "
"width='190' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Delete' "
"width='20' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<space size='5' /> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<space size='5' />"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<space size='5' /> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<space size='5' />"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='22'/> "
+"/>"
+"<space size='22'/>"
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"</layout_info> "
-"<layout_info resolution='y<400'> "
-"<globals> "
-"<def var='Line.Height' value='12' /> "
-"<def var='Font.Height' value='10' /> "
-"<def var='About.OuterBorder' value='10'/> "
-"<def var='Layout.Spacing' value='8'/> "
-"<def var='ShowLauncherLogo' value='0'/> "
-"<def var='ShowGlobalMenuLogo' value='0'/> "
-"<def var='ShowSearchPic' value='0'/> "
-"<def var='ShowChooserPics' value='0'/> "
-"<def var='ShowChooserPageDisplay' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
-"<def var='RecorderDialog.ExtInfo.Visible' value='0'/> "
-"<def var='OnScreenDialog.ShowPics' value='0'/> "
-"<def var='KeyMapper.Spacing' value='5'/> "
-"<def var='KeyMapper.LabelWidth' value='80'/> "
-"<def var='KeyMapper.ButtonWidth' value='60'/> "
-"<def var='Tooltip.MaxWidth' value='70'/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"</layout_info>"
+"<layout_info resolution='y<400'>"
+"<globals>"
+"<def var='Line.Height' value='12' />"
+"<def var='Font.Height' value='10' />"
+"<def var='About.OuterBorder' value='10'/>"
+"<def var='Layout.Spacing' value='8'/>"
+"<def var='ShowLauncherLogo' value='0'/>"
+"<def var='ShowGlobalMenuLogo' value='0'/>"
+"<def var='ShowSearchPic' value='0'/>"
+"<def var='ShowChooserPics' value='0'/>"
+"<def var='ShowChooserPageDisplay' value='0'/>"
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/>"
+"<def var='RecorderDialog.ExtInfo.Visible' value='0'/>"
+"<def var='OnScreenDialog.ShowPics' value='0'/>"
+"<def var='KeyMapper.Spacing' value='5'/>"
+"<def var='KeyMapper.LabelWidth' value='80'/>"
+"<def var='KeyMapper.ButtonWidth' value='60'/>"
+"<def var='Tooltip.MaxWidth' value='70'/>"
"<def var='Tooltip.XDelta' value='8'/> "
-"<def var='Tooltip.YDelta' value='8'/> "
-"<def var='Predictive.Button.Width' value='45' /> "
-"<def var='Predictive.Button.Height' value='15' /> "
+"<def var='Tooltip.YDelta' value='8'/>"
+"<def var='Predictive.Button.Width' value='45' />"
+"<def var='Predictive.Button.Height' value='15' />"
"<widget name='Button' "
"size='72,16' "
-"/> "
+"/>"
"<widget name='Slider' "
"size='85,12' "
-"/> "
+"/>"
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='SmallLabel' "
"size='18,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='PopUp' "
"size='-1,15' "
-"/> "
+"/>"
"<widget name='Checkbox' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ListWidget' "
"padding='5,0,0,0' "
-"/> "
+"/>"
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
-"/> "
+"/>"
"<widget name='EditTextWidget' "
"padding='5,5,0,0' "
-"/> "
+"/>"
"<widget name='Console' "
"padding='7,5,5,5' "
-"/> "
+"/>"
"<widget name='Scrollbar' "
"size='9,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Tab' "
"size='45,16' "
"padding='0,0,2,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Body' "
"padding='0,0,0,-8' "
-"/> "
+"/>"
"<widget name='TabWidget.NavButton' "
"size='32,18' "
"padding='0,0,1,0' "
-"/> "
+"/>"
"<widget name='EditRecordLabel' "
"size='60,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='EditRecord' "
"size='120,15' "
-"/> "
-"</globals> "
-"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='6,6,2,2'> "
+"/>"
+"</globals>"
+"<dialog name='Launcher' overlays='screen'>"
+"<layout type='vertical' center='true' padding='6,6,2,2'>"
"<widget name='Version' "
"height='Globals.Line.Height' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'>"
"<widget name='SearchDesc' "
"width='50' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Search' "
"width='150' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SearchClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space /> "
-"</layout> "
-"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"<space />"
+"</layout>"
+"<widget name='GameList'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='LoadGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='AddGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='EditGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='RemoveGameButton' "
"height='12' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='QuitButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='AboutButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='OptionsButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='StartButton' "
"height='12' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,0,4'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='Browser' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,0,4'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Path' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
-"<layout type='vertical' padding='0,0,8,0'> "
+"/>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,8,0'>"
"<widget name='Hidden' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Up' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grModePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grRenderPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='grAspectCheckbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='grFullscreenCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auMidiPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auOPLPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auSampleRatePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
+"<space size='110' />"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='6'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='6'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefGmPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='mcFontButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='mcFontPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='mcFontClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='mcMidiGainSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='mcMidiGainLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcFluidSynthSettings' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefMt32Popup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMt32Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='mcGSCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='SaveButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ThemePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='ExtraButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='PluginsButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='PluginsPath' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='CurTheme' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='RendererPopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='RendererPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='AutosavePeriodPopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='GuiLanguagePopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeysButton' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Action' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
+"/>"
+"<widget name='List'/>"
"<widget name='Mapping' "
"height='Globals.Line.Height' "
-"/> "
-"<space size='Globals.Line.Height'/> "
-"<layout type='horizontal'> "
+"/>"
+"<space size='Globals.Line.Height'/>"
+"<layout type='horizontal'>"
"<widget name='Map' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0' spacing='16'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Graphics' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Graphics' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Audio' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Audio' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MIDI' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MIDI' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MT32' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MT32' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Volume' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Volume' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='Id' "
"width='35' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Domain' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='Name' "
"width='35' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Desc' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<space size='8'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<space size='8'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='LangPopupDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='LangPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='PlatformPopupDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='PlatformPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='Savepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='Extrapath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='Gamepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='GamepathText' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption2Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption3Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption4Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption5Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption6Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption7Checkbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalMenu' overlays='screen_center'>"
+"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'>"
"<widget name='Title' "
"width='160' "
"height='4' "
-"/> "
+"/>"
"<widget name='Version' "
"width='160' "
"height='4' "
-"/> "
-"<space size='1'/> "
+"/>"
+"<space size='1'/>"
"<widget name='Load' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='Save' "
"width='120' "
"height='12' "
-"/> "
-"<space size='1'/> "
+"/>"
+"<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'/> "
+"/>"
+"<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> "
-"</dialog> "
-"<dialog name='GlobalConfig' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalConfig' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
+"<space size='110' />"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"width='80' "
-"/> "
-"</layout> "
-"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
+"/>"
+"</layout>"
+"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
"width='90' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
"width='90' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
"width='90' "
-"/> "
-"</layout> "
-"</layout> "
-"<space size='2' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<space size='2' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<space size='16'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
+"/>"
+"</layout>"
+"<space size='16'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='4'>"
"<widget name='Keys' "
"type='Button' "
-"/> "
-"<space size='Globals.Button.Width' /> "
+"/>"
+"<space size='Globals.Button.Width' />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<space/>"
"<widget name='ResetSettings' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='VoiceCountText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='VoiceCountSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='VoiceCountLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='SpeedText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='SpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='SpeedLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DepthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DepthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DepthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WaveFormTypeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WaveFormType' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RoomSizeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RoomSizeSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='RoomSizeLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DampingText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DampingSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DampingLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WidthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WidthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='WidthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='InterpolationText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Interpolation' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
-"<widget name='Title' height='Globals.Line.Height'/> "
-"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
+"<widget name='Title' height='Globals.Line.Height'/>"
+"<widget name='List' />"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='ListSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GridSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SavenameDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SavenameDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='DescriptionText' "
"width='180' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description' "
"height='19' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,4' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,4' center='true'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='2'> "
+"/>"
+"<widget name='List' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='2'>"
"<widget name='Edit' "
"type='Button' "
-"/> "
-"<space /> "
+"/>"
+"<space />"
"<widget name='Record' "
"type='Button' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='2'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='2'>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space /> "
+"/>"
+"<space />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Playback' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='OnScreenDialog' overlays='screen_center'> "
-"<layout type='horizontal' spacing='5' padding='3,2,3,2' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='OnScreenDialog' overlays='screen_center'>"
+"<layout type='horizontal' spacing='5' padding='3,2,3,2' center='true'>"
"<widget name='StopButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='EditButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='SwitchModeButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='FastReplayButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='TimeLabel' "
"width='50' "
"height='16' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='EditRecordDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='EditRecordDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='AuthorLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='AuthorEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NameLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NameEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NotesLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NotesEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='OK' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='ScummHelp' overlays='screen'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='ScummHelp' overlays='screen'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='Title' "
"width='180' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='HelpText' "
"height='140' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Prev' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Next' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Description1' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description2' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Standard' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Practice' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Expert' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='4,4,16,4' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='MassAdd' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='4,4,16,4' center='true'>"
"<widget name='DirProgressText' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameProgressText' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameList' "
"width='280' "
"height='100' "
-"/> "
-"<layout type='horizontal' padding='4,4,4,4'> "
+"/>"
+"<layout type='horizontal' padding='4,4,4,4'>"
"<widget name='Ok' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeyMapper' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Popup' "
"type='PopUp' "
"width='150' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeymapArea' "
"width='300' "
"height='120' "
-"/> "
+"/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='1,1,1,1' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='Predictive' overlays='screen_center'>"
+"<layout type='vertical' padding='1,1,1,1' center='true'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
"width='150' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Word' "
"width='120' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Delete' "
"width='20' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,0'>"
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<space size='3' /> "
-"<layout type='horizontal' padding='3,3,0,3'> "
+"/>"
+"</layout>"
+"<space size='3' />"
+"<layout type='horizontal' padding='3,3,0,3'>"
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"</layout_info> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"</layout_info>"
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 4154c6c33a..1085aa64a4 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 0f10003e94..e40e8b1e26 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 1b3bcea0d6..3a1ec5a5f0 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -38,6 +38,14 @@
rgb = '203, 126, 107'
/>
+ <color name = 'brightredborder'
+ rgb = '238, 213, 207'
+ />
+
+ <color name = 'darkredborder'
+ rgb = '30, 7, 1'
+ />
+
<!-- Disabled button/slider -->
<color name = 'darkeneddarkred'
rgb = '120, 28, 0'
@@ -73,7 +81,7 @@
rgb = '255, 255, 255'
/>
<color name = 'shadowcolor'
- rgb = '63, 60, 17'
+ rgb = '105, 101, 86'
/>
<color name = 'darkgray'
rgb = '176, 168, 144'
@@ -170,6 +178,10 @@
color = '128, 128, 128'
/>
+ <text_color id = 'color_button_hover'
+ color = 'white'
+ />
+
<text_color id = 'color_alternative_inverted'
color = 'white'
/>
@@ -186,10 +198,6 @@
color = 'white'
/>
- <text_color id = 'color_button_hover'
- color = '255, 214, 84'
- />
-
<text_color id = 'color_button_disabled'
color = '192, 192, 192'
/>
@@ -232,7 +240,7 @@
stroke = '0'
gradient_start = 'darkorange'
gradient_end = 'brightorange'
- shadow = '3'
+ shadow = '7'
gradient_factor = '3'
/>
</drawdata>
@@ -466,7 +474,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -505,7 +513,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -663,7 +671,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -716,7 +724,7 @@
gradient_start = 'blandyellow'
gradient_end = 'xtrabrightred'
fill = 'gradient'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
@@ -737,7 +745,7 @@
gradient_start = 'blandyellow'
gradient_end = 'xtrabrightred'
gradient_factor = '4'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
@@ -783,18 +791,18 @@
stroke = '1'
fill = 'gradient'
shadow = '0'
- fg_color = 'shadowcolor'
+ fg_color = 'darkredborder'
gradient_start = 'brightred'
gradient_end = 'darkred'
bevel = '1'
- bevel_color = '237, 169, 72'
+ bevel_color = 'brightredborder'
/>
</drawdata>
<!-- Hovered button -->
<drawdata id = 'button_hover' cache = 'false'>
<text font = 'text_button'
- text_color = 'color_button_hover'
+ text_color = 'color_button'
vertical_align = 'center'
horizontal_align = 'center'
/>
@@ -803,11 +811,11 @@
stroke = '1'
fill = 'gradient'
shadow = '0'
- fg_color = 'shadowcolor'
+ fg_color = 'darkredborder'
gradient_start = 'brightpink'
gradient_end = 'darkpink'
bevel = '1'
- bevel_color = 'xtrabrightred'
+ bevel_color = 'brightredborder'
/>
</drawdata>
@@ -915,7 +923,7 @@
gradient_factor = '6'
fill = 'gradient'
bg_color = 'xtrabrightred'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py
index 4c55fd79de..524e91468e 100755
--- a/gui/themes/scummtheme.py
+++ b/gui/themes/scummtheme.py
@@ -37,9 +37,13 @@ def parseSTX(theme_file, def_file):
comm = re.compile("<!--(.*?)-->", re.DOTALL)
head = re.compile("<\?(.*?)\?>")
+ strlitcount = 0
output = ""
for line in theme_file:
- output += line.rstrip("\r\n\t ").lstrip() + " \n"
+ output += line.rstrip("\r\n\t ").lstrip()
+ if not output.endswith('>'):
+ output += ' '
+ output += "\n"
output = re.sub(comm, "", output)
output = re.sub(head, "", output)
@@ -48,7 +52,9 @@ def parseSTX(theme_file, def_file):
for line in output.splitlines():
if line and not line.isspace():
+ strlitcount += len(line)
def_file.write("\"" + line + "\"\n")
+ return strlitcount
def buildDefTheme(themeName):
def_file = open("default.inc", "w")
@@ -57,16 +63,23 @@ def buildDefTheme(themeName):
print ("Cannot open default theme dir.")
def_file.write(""" "<?xml version = '1.0'?>"\n""")
+ strlitcount = 24
for filename in os.listdir(themeName):
filename = os.path.join(themeName, filename)
if os.path.isfile(filename) and filename.endswith(".stx"):
theme_file = open(filename, "r")
- parseSTX(theme_file, def_file)
+ strlitcount += parseSTX(theme_file, def_file)
theme_file.close()
def_file.close()
+ if strlitcount > 65535:
+ print("WARNING: default.inc string literal is of length %d which exceeds the" % strlitcount)
+ print(" maximum length of 65536 that C++ compilers are required to support.")
+ print(" It is likely that bugs will occur dependent on compiler behaviour.")
+ print(" To avoid this, reduce the size of the theme.")
+
def printUsage():
print ("===============================")
print ("ScummVM Theme Generation Script")
diff --git a/gui/widget.cpp b/gui/widget.cpp
index c3f10a861f..e96b62e359 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -287,7 +287,7 @@ ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Co
ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
: StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss),
- _cmd(cmd), _lastTime(0) {
+ _cmd(cmd), _hotkey(hotkey), _lastTime(0) {
if (hotkey == 0)
_hotkey = parseHotkey(label);
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
@@ -396,7 +396,7 @@ PicButtonWidget::~PicButtonWidget() {
void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
_gfx.free();
- if (!gfx || !gfx->pixels)
+ if (!gfx || !gfx->getPixels())
return;
if (gfx->format.bytesPerPixel == 1) {
@@ -429,7 +429,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
void PicButtonWidget::drawWidget() {
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags());
- if (_gfx.pixels) {
+ if (_gfx.getPixels()) {
// Check whether the set up surface needs to be converted to the GUI
// color format.
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
@@ -646,7 +646,7 @@ GraphicsWidget::~GraphicsWidget() {
void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
_gfx.free();
- if (!gfx || !gfx->pixels)
+ if (!gfx || !gfx->getPixels())
return;
if (gfx->format.bytesPerPixel == 1) {
@@ -676,7 +676,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
}
void GraphicsWidget::drawWidget() {
- if (_gfx.pixels) {
+ if (_gfx.getPixels()) {
// Check whether the set up surface needs to be converted to the GUI
// color format.
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 6fae9346b2..667850d6cc 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -277,7 +277,7 @@ void EditableWidget::drawCaret(bool erase) {
int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font);
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);
+ 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);
}
}
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index 3677f02e47..52527effd8 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -93,11 +93,15 @@ void EditTextWidget::drawWidget() {
// Draw the text
adjustOffset();
- g_gui.theme()->drawText(Common::Rect(_x+2+ _leftPadding,_y+2, _x+_leftPadding+getEditRect().width()+2, _y+_h-2), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font);
+
+ const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h);
+ setTextDrawableArea(r);
+
+ g_gui.theme()->drawText(Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 2, _y + _h), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
}
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 - 1);
return r;
}
diff --git a/po/POTFILES b/po/POTFILES
index b812620c25..869323b8f3 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -99,5 +99,5 @@ backends/events/default/default-events.cpp
backends/events/gph/gph-events.cpp
backends/events/openpandora/op-events.cpp
backends/updates/macosx/macosx-updates.mm
-backends/platform/bada/form.cpp
+backends/platform/tizen/form.cpp
backends/events/maemosdl/maemosdl-events.cpp
diff --git a/test/audio/raw.h b/test/audio/raw.h
index e7cb42ac44..3792f82674 100644
--- a/test/audio/raw.h
+++ b/test/audio/raw.h
@@ -1,6 +1,7 @@
#include <cxxtest/TestSuite.h>
#include "audio/decoders/raw.h"
+#include "audio/audiostream.h"
#include "helper.h"
diff --git a/test/common/hash-str.h b/test/common/hash-str.h
new file mode 100644
index 0000000000..0391e7167f
--- /dev/null
+++ b/test/common/hash-str.h
@@ -0,0 +1,164 @@
+#include <cxxtest/TestSuite.h>
+#include "common/hash-str.h"
+
+/**
+ * Test suite for common/hash-str.h
+ * We test a number of case sensitive/insensitive hash and compare functions
+ * using example strings and known hashes, trying to tackle
+ * as much edge cases as possible.
+ */
+class HashStrTestSuite : public CxxTest::TestSuite {
+
+ public:
+ void test_case_sensitive_string_equal_to() {
+
+ // Name says it all.
+ // This verifies that the function returns true
+ // for exactly the same string, false for the same
+ // string in mixed case and false for some edge cases
+ // with various spacings plus one character replaced
+ // by itself+128 (if there's some processing done after
+ // conversion to 7-bit ASCII this might yield funny results).
+
+ const Common::String lower("test");
+ const Common::String lower1("test");
+ const Common::String mixed("tESt");
+ const Common::String spaced("test ");
+ const Common::String doublespaced("test ");
+ const Common::String tabbed("test\t");
+ const Common::String plus128("t\345est");
+ // 'e'+128 = 0xE5 = 0o345
+
+ Common::CaseSensitiveString_EqualTo css_et;
+ TS_ASSERT_EQUALS(css_et(lower, mixed), false);
+ TS_ASSERT_EQUALS(css_et(lower, lower1), true);
+ TS_ASSERT_EQUALS(css_et(lower, lower), true);
+
+ // Different sorts of whitespace are to be treated differently.
+ TS_ASSERT_EQUALS(css_et(lower, spaced), false);
+ TS_ASSERT_EQUALS(css_et(lower, tabbed), false);
+ TS_ASSERT_EQUALS(css_et(spaced, tabbed), false);
+ TS_ASSERT_EQUALS(css_et(spaced, doublespaced), false);
+ TS_ASSERT_EQUALS(css_et(lower, plus128), false);
+ }
+
+ void test_ignore_case_equal_to() {
+
+ // This should be probably called case_insensitive_string_equal_to
+ // or something,but it's basically the same thing as
+ // test_case_sensitive_string_equal_to, only it's case
+ // insensitive.
+
+ const Common::String lower("test");
+ const Common::String lower1("test");
+ const Common::String mixed("tESt");
+ const Common::String spaced("test ");
+ const Common::String mixedspaced("tESt ");
+ const Common::String doublespaced("test ");
+ const Common::String tabbed("test\t");
+ const Common::String plus128("t\345est");
+
+ Common::IgnoreCase_EqualTo ic_et;
+ TS_ASSERT_EQUALS(ic_et(lower, mixed), true);
+ TS_ASSERT_EQUALS(ic_et(lower, lower1), true);
+ TS_ASSERT_EQUALS(ic_et(lower, lower), true);
+ // Edge case:
+ TS_ASSERT_EQUALS(ic_et(spaced, mixedspaced), true);
+
+ // Different sorts of whitespace are to be treated differently.
+ TS_ASSERT_EQUALS(ic_et(lower, spaced), false);
+ TS_ASSERT_EQUALS(ic_et(lower, tabbed), false);
+ TS_ASSERT_EQUALS(ic_et(spaced, tabbed), false);
+ TS_ASSERT_EQUALS(ic_et(spaced, doublespaced), false);
+ TS_ASSERT_EQUALS(ic_et(lower, plus128), false);
+ }
+
+ void test_case_sensitive_string_hash() {
+
+ // Here we compute string hashes for different
+ // strings and see that the functor is case sensitive
+ // and does not ignore spaces.
+
+ const Common::String lower("test");
+ const Common::String lower1("test");
+ const Common::String mixed("tESt");
+ const Common::String spaced("test ");
+ const Common::String mixedspaced("tESt ");
+ const Common::String doublespaced("test ");
+ const Common::String tabbed("test\t");
+
+ Common::CaseSensitiveString_Hash css_h;
+ TS_ASSERT_EQUALS(css_h(lower), css_h(lower1));
+ TS_ASSERT_DIFFERS(css_h(mixed), css_h(lower));
+ TS_ASSERT_DIFFERS(css_h(spaced), css_h(lower));
+ TS_ASSERT_DIFFERS(css_h(tabbed), css_h(spaced));
+ TS_ASSERT_DIFFERS(css_h(spaced), css_h(doublespaced));
+ }
+
+ void test_ignore_case_hash() {
+ // Same as test_case_sensitive_string_hash, but case insensitive.
+ const Common::String lower("test");
+ const Common::String lower1("test");
+ const Common::String mixed("tESt");
+ const Common::String spaced("test ");
+ const Common::String mixedspaced("tESt ");
+ const Common::String doublespaced("test ");
+ const Common::String tabbed("test\t");
+
+ Common::IgnoreCase_Hash ic_h;
+ TS_ASSERT_EQUALS(ic_h(lower), ic_h(lower1));
+ TS_ASSERT_EQUALS(ic_h(mixed), ic_h(lower));
+ TS_ASSERT_EQUALS(ic_h(spaced), ic_h(mixedspaced));
+ TS_ASSERT_DIFFERS(ic_h(tabbed), ic_h(lower));
+ TS_ASSERT_DIFFERS(ic_h(spaced), ic_h(doublespaced));
+ }
+
+ void test_cpp_string_hash()
+ {
+ // We run the same tests with Hash<String>,
+ // a template specialization of Hash, also a functor.
+ // It is supposed to be case sensitive.
+
+ const Common::String lower("test");
+ const Common::String lower1("test");
+ const Common::String mixed("tESt");
+ const Common::String spaced("test ");
+ const Common::String mixedspaced("tESt ");
+ const Common::String doublespaced("test ");
+ const Common::String tabbed("test\t");
+
+ Common::Hash<Common::String> h;
+ TS_ASSERT_EQUALS(h(lower), h(lower1));
+ TS_ASSERT_DIFFERS(h(mixed), h(lower));
+ TS_ASSERT_DIFFERS(h(spaced), h(lower));
+ TS_ASSERT_DIFFERS(h(tabbed), h(spaced));
+ TS_ASSERT_DIFFERS(h(spaced), h(doublespaced));
+ }
+
+ void test_c_style_string_hash()
+ {
+ // Same as test_cpp_string_hash but with Hash<const char*>,
+ // a template specialization of Hash, also a functor,
+ // that works with C-Style strings.
+ // It is supposed to be case sensitive.
+
+ char lower[] = "test";
+ char lower1[] = "test";
+ char mixed[] = "tESt";
+ char spaced[] = "test ";
+ char mixedspaced[] = "tESt ";
+ char doublespaced[] = "test ";
+ char tabbed[] = "test\t";
+
+ Common::Hash<const char *> h;
+ TS_ASSERT_EQUALS(h(lower), h(lower1));
+ TS_ASSERT_DIFFERS(h(mixed), h(lower));
+ TS_ASSERT_DIFFERS(h(spaced), h(lower));
+ TS_ASSERT_DIFFERS(h(spaced), h(mixedspaced));
+ TS_ASSERT_DIFFERS(h(tabbed), h(spaced));
+ TS_ASSERT_DIFFERS(h(spaced), h(doublespaced));
+
+ }
+
+
+};
diff --git a/test/common/huffman.h b/test/common/huffman.h
index 52199a8ffd..53353aaa60 100644
--- a/test/common/huffman.h
+++ b/test/common/huffman.h
@@ -3,20 +3,27 @@
#include "common/bitstream.h"
#include "common/memstream.h"
-class HuffmanTestSuite : public CxxTest::TestSuite
-{
+/**
+* A test suite for the Huffman decoder in common/huffman.h
+* The encoding used comes from the example on the Wikipedia page
+* for Huffman.
+* TODO: It could be improved by generating one at runtime.
+*/
+class HuffmanTestSuite : public CxxTest::TestSuite {
public:
void test_get_with_full_symbols() {
/*
- * Testing the Huffman decoder.
+ * The class can be initialized with or without providing
+ * a max_length and a symbol table.
+ * We test with a table.
*
* Encoding (arbitrary, for testing purpouses):
- * A=010
- * B=011
- * C=11
- * D=00
- * E=10
+ * 0xA=010
+ * 0xB=011
+ * 0xC=11
+ * 0xD=00
+ * 0xE=10
*/
uint32 codeCount = 5;
@@ -25,7 +32,7 @@ class HuffmanTestSuite : public CxxTest::TestSuite
const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2};
const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE};
- Common::Huffman h (maxLength, codeCount, codes, lengths, symbols);
+ Common::Huffman h(maxLength, codeCount, codes, lengths, symbols);
byte input[] = {0x4F, 0x20};
// Provided input...
@@ -53,8 +60,8 @@ class HuffmanTestSuite : public CxxTest::TestSuite
void test_get_without_symbols() {
/*
- * This is basically the same as above, but
- * I pass minimal arguments.
+ * This is basically the same as test_get_with_full_symbols, but
+ * I only pass the minimal required arguments.
* Specifically, I avoid passing the symbols table, so that
* array indices are used instead.
*
@@ -71,7 +78,7 @@ class HuffmanTestSuite : public CxxTest::TestSuite
const uint8 lengths[] = {3,3,2,2,2};
const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2};
- Common::Huffman h (0, codeCount, codes, lengths, 0);
+ Common::Huffman h(0, codeCount, codes, lengths, 0);
byte input[] = {0x4F, 0x20};
uint32 expected[] = {0, 1, 2, 3, 4, 3 ,3};
@@ -91,16 +98,23 @@ class HuffmanTestSuite : public CxxTest::TestSuite
void test_get_after_set_symbols() {
/*
- * Another variation of the above.
+ * Another variation of test_get_with_full_symbols.
* I use the setSymbols method to define, a posteriori,
- * an alphabet to be used in place of array indices
+ * an alphabet to be used in place of array indices.
+ * The encoding is, at first,
+ * 0=010
+ * 1=011
+ * 2=11
+ * 3=00
+ * 4=10
+ * (=array indices).
*/
uint32 codeCount = 5;
const uint8 lengths[] = {3,3,2,2,2};
const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2};
- Common::Huffman h (0, codeCount, codes, lengths, 0);
+ Common::Huffman h(0, codeCount, codes, lengths, 0);
const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE};
h.setSymbols(symbols);
diff --git a/test/common/rendermode.h b/test/common/rendermode.h
new file mode 100644
index 0000000000..e5e277f16b
--- /dev/null
+++ b/test/common/rendermode.h
@@ -0,0 +1,84 @@
+#include <cxxtest/TestSuite.h>
+#include "common/rendermode.h"
+#include "common/gui_options.h"
+#include "common/str.h"
+
+class RenderModeTestSuite : public CxxTest::TestSuite {
+ public:
+ void test_parse_render_mode_good() {
+ /*
+ * Tests for parseRenderMode.
+ * It takes a code (case-insensitive) and spits a RenderMode back at you.
+ * These cases should work - the inputs are standard, there's just some
+ * fun with caps being had in here.
+ */
+ TS_ASSERT_EQUALS(Common::parseRenderMode("fMTOwNs"), Common::kRenderFMTowns);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("hercGrEen"), Common::kRenderHercG);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("hercAmbeR"), Common::kRenderHercA);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("CgA"), Common::kRenderCGA);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("ega"), Common::kRenderEGA);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("Vga"), Common::kRenderVGA);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("AmigA"), Common::kRenderAmiga);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("pc9821"), Common::kRenderPC9821);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("PC9801"), Common::kRenderPC9801);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault);
+ }
+
+
+ void test_parse_render_mode_bad() {
+ /*
+ * These cases, according to the specification, should return the default.
+ * It is only mentioned that the function must be case insensitive.
+ * Whitespaces, in particular, should not be automatically trimmed.
+ */
+ TS_ASSERT_EQUALS(Common::parseRenderMode("fmtowns "), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("FM-TOWNS "), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode(" cga"), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("\tC g A"), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("\t"), Common::kRenderDefault);
+ // This is the only interesting bit: if the function was really, really
+ // broken it could be tempted to test for +-0x20.
+ TS_ASSERT_EQUALS(Common::parseRenderMode("pc Y8 21 "), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode(" PC\t9801 "), Common::kRenderDefault);
+ TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault);
+ }
+
+ void test_get_render_mode_code_back_and_forth() {
+ /*
+ * What does getRenderModeCode return?
+ * Notably, the output should not be in mixed case.
+ */
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns", 7);
+ TS_ASSERT_DIFFERS(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns");
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("CGA")), "cga", 3);
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("vga")), "vga", 3);
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("Ega")), "ega", 3);
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("AmiGa")), "amiga", 5);
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC9821")), "pc9821", 6);
+ TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC9801")), "pc9801", 6);
+ // Slightly more interesting:
+ // Make sure that we get a null pointer for 0 (and not the "0" string or stuff)
+ char *null_p = 0;
+ TS_ASSERT_EQUALS(Common::getRenderModeCode(Common::kRenderDefault), null_p);
+ }
+
+ void test_render_2_guio() {
+ /*
+ * Verify that a rendermode is taken and the corresponding
+ * GUIO_xxxxx is returned.
+ */
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercG), GUIO_RENDERHERCGREEN);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercA), GUIO_RENDERHERCAMBER);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderCGA), GUIO_RENDERCGA);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderEGA), GUIO_RENDEREGA);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderVGA), GUIO_RENDERVGA);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderAmiga), GUIO_RENDERAMIGA);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderFMTowns), GUIO_RENDERFMTOWNS);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC9821), GUIO_RENDERPC9821);
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC9801), GUIO_RENDERPC9801);
+ // renderMode2GUIO is supposed to return an empty string
+ // if given kRenderDefault as an argument
+ Common::String empty;
+ TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderDefault), empty);
+ }
+};
diff --git a/test/common/util.h b/test/common/util.h
index c11ab740de..cd65307612 100644
--- a/test/common/util.h
+++ b/test/common/util.h
@@ -1,46 +1,67 @@
#include <cxxtest/TestSuite.h>
#include "common/util.h"
+/**
+ * Test suite for the functions in common/util.h
+ */
class UtilTestSuite : public CxxTest::TestSuite {
-public:
+ public:
+ void test_parsebool_yesno() {
- void test_parsebool_good() {
-
- // Test the parseBool function
+ // First test for the parseBool function.
+ // These are the mixed case yes/no cases that must work
bool valasbool;
bool success;
- // 'Regular' cases that must work
- // (note that the function must be case insensitive):
-
- Common::String string_1 ("Yes");
- success = Common::parseBool (string_1, valasbool);
+ Common::String string_1("Yes");
+ success = Common::parseBool(string_1, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 1);
- Common::String string_2 ("nO");
- success = Common::parseBool (string_2, valasbool);
+ Common::String string_2("nO");
+ success = Common::parseBool(string_2, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 0);
+ }
+
+ void test_parsebool_truefalse() {
+
+ // First test for the parseBool function.
+ // These are the mixed case true/false cases that must work
- Common::String string_3 ("tRuE");
- success = Common::parseBool (string_3, valasbool);
+ bool valasbool;
+ bool success;
+
+ Common::String string_3("tRuE");
+ success = Common::parseBool(string_3, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 1);
- Common::String string_4 ("fAlSe");
- success = Common::parseBool (string_4, valasbool);
+ Common::String string_4("fAlSe");
+ success = Common::parseBool(string_4, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 0);
+ }
+
+ void test_parsebool_onezero() {
- Common::String string_5 ("1");
- success = Common::parseBool (string_5, valasbool);
+ // Third test for the parseBool function.
+ // These are the 1/0 cases that must work.
+ // Note that while 'a-z'+0x20 must work just fine,
+ // '0-1'+0x20 should NOT; this is addressed in
+ // parsebool_bad
+
+ bool valasbool;
+ bool success;
+
+ Common::String string_5("1");
+ success = Common::parseBool(string_5, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 1);
- Common::String string_6 ("0");
- success = Common::parseBool (string_6, valasbool);
+ Common::String string_6("0");
+ success = Common::parseBool(string_6, valasbool);
TS_ASSERT_EQUALS(success, 1);
TS_ASSERT_EQUALS(valasbool, 0);
@@ -53,20 +74,34 @@ public:
// Bad cases that should not return success #1:
// Random string
- Common::String string_1 ("u_f1ght_l1k3_a_c0w");
- success = Common::parseBool (string_1, valasbool);
+ Common::String string_1("u_f1ght_l1k3_a_c0w");
+ success = Common::parseBool(string_1, valasbool);
TS_ASSERT_EQUALS(success, 0);
// Bad cases that should not return success #2, #3:
// The function should NOT accept trailing whitespaces:
- Common::String string_2 (" yes");
- success = Common::parseBool (string_2, valasbool);
+ Common::String string_2(" yes");
+ success = Common::parseBool(string_2, valasbool);
+ TS_ASSERT_EQUALS(success, 0);
+
+ Common::String string_3("yes ");
+ success = Common::parseBool(string_3, valasbool);
TS_ASSERT_EQUALS(success, 0);
- Common::String string_3 ("yes ");
- success = Common::parseBool (string_3, valasbool);
+ // While 'a-z'+0x20 must work just fine,
+ // '0-1'+0x20 should NOT. '2' is not good either.
+
+ Common::String string_4("\x50");
+ success = Common::parseBool(string_4, valasbool);
TS_ASSERT_EQUALS(success, 0);
+ Common::String string_5("\x51");
+ success = Common::parseBool(string_5, valasbool);
+ TS_ASSERT_EQUALS(success, 0);
+
+ Common::String string_6("2");
+ success = Common::parseBool(string_6, valasbool);
+ TS_ASSERT_EQUALS(success, 0);
}
void test_is_al_num() {
@@ -177,8 +212,10 @@ public:
void test_is_space() {
// isSpace should return true iff the character is some kind of whitespace
// or tab character
- for (int c=0; c<255; c++) {
- if (c==' ' || c=='\t' || c=='\r' || c=='\n' || c=='\v' || c=='\f') {
+ for (int c = 0; c < 255; c++) {
+ if (c == ' ' || c == '\t' ||
+ c == '\r' || c == '\n' ||
+ c == '\v' || c == '\f') {
TS_ASSERT_EQUALS(Common::isSpace(c), 1);
} else {
TS_ASSERT_EQUALS(Common::isSpace(c), 0);
@@ -189,8 +226,8 @@ public:
void test_is_print() {
// isPrint should return true iff the input is a printable ascii char.
// That is to say, 0x20 to 0x7E.
- for (int c=0; c<255; c++) {
- if (c>=0x20 && c<=0x7E) {
+ for (int c = 0; c < 255; c++) {
+ if (c >= 0x20 && c <= 0x7E) {
TS_ASSERT_EQUALS(Common::isPrint(c), 1);
} else {
TS_ASSERT_EQUALS(Common::isPrint(c), 0);
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index ff728a8437..5e4b91d1bd 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -65,8 +65,10 @@ namespace Video {
#define ID_VEDT MKTAG('v','e','d','t')
#define ID_IDX1 MKTAG('i','d','x','1')
#define ID_STRD MKTAG('s','t','r','d')
-//#define ID_INFO MKTAG('I','N','F','O')
+#define ID_INFO MKTAG('I','N','F','O')
#define ID_ISFT MKTAG('I','S','F','T')
+#define ID_DISP MKTAG('D','I','S','P')
+#define ID_PRMI MKTAG('P','R','M','I')
// Codec tags
#define ID_RLE MKTAG('R','L','E',' ')
@@ -78,18 +80,13 @@ namespace Video {
#define ID_DUCK MKTAG('D','U','C','K')
#define ID_MPG2 MKTAG('m','p','g','2')
-static byte char2num(char c) {
- c = tolower((byte)c);
- return (c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - '0';
-}
+// Stream Types
+enum {
+ kStreamTypePaletteChange = MKTAG16('p', 'c'),
+ kStreamTypeRawVideo = MKTAG16('d', 'b'),
+ kStreamTypeAudio = MKTAG16('w', 'b')
+};
-static byte getStreamIndex(uint32 tag) {
- return char2num((tag >> 24) & 0xFF) << 4 | char2num((tag >> 16) & 0xFF);
-}
-
-static uint16 getStreamType(uint32 tag) {
- return tag & 0xffff;
-}
AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) {
initCommon();
@@ -107,29 +104,32 @@ AVIDecoder::~AVIDecoder() {
void AVIDecoder::initCommon() {
_decodedHeader = false;
_foundMovieList = false;
+ _movieListStart = 0;
_fileStream = 0;
- memset(&_ixInfo, 0, sizeof(_ixInfo));
memset(&_header, 0, sizeof(_header));
}
-void AVIDecoder::runHandle(uint32 tag) {
- assert(_fileStream);
+bool AVIDecoder::isSeekable() const {
+ // Only videos with an index can seek
+ // Anyone else who wants to seek is crazy.
+ return isVideoLoaded() && !_indexEntries.empty();
+}
+
+bool AVIDecoder::parseNextChunk() {
+ uint32 tag = _fileStream->readUint32BE();
+ uint32 size = _fileStream->readUint32LE();
+
if (_fileStream->eos())
- return;
+ return false;
debug(3, "Decoding tag %s", tag2str(tag));
switch (tag) {
- case ID_RIFF:
- /*_filesize = */_fileStream->readUint32LE();
- if (_fileStream->readUint32BE() != ID_AVI)
- error("RIFF file is not an AVI video");
- break;
case ID_LIST:
- handleList();
+ handleList(size);
break;
case ID_AVIH:
- _header.size = _fileStream->readUint32LE();
+ _header.size = size;
_header.microSecondsPerFrame = _fileStream->readUint32LE();
_header.maxBytesPerSecond = _fileStream->readUint32LE();
_header.padding = _fileStream->readUint32LE();
@@ -144,58 +144,74 @@ void AVIDecoder::runHandle(uint32 tag) {
_fileStream->skip(16);
break;
case ID_STRH:
- handleStreamHeader();
+ handleStreamHeader(size);
break;
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_ISFT: // Metadata, safe to ignore
- {
- uint32 junkSize = _fileStream->readUint32LE();
- _fileStream->skip(junkSize + (junkSize & 1)); // Alignment
- } break;
+ case ID_DISP: // Metadata, should be safe to ignore
+ skipChunk(size);
+ break;
case ID_IDX1:
- _ixInfo.size = _fileStream->readUint32LE();
- _ixInfo.indices = new OldIndex::Index[_ixInfo.size / 16];
- debug(0, "%d Indices", (_ixInfo.size / 16));
- for (uint32 i = 0; i < (_ixInfo.size / 16); i++) {
- _ixInfo.indices[i].id = _fileStream->readUint32BE();
- _ixInfo.indices[i].flags = _fileStream->readUint32LE();
- _ixInfo.indices[i].offset = _fileStream->readUint32LE();
- _ixInfo.indices[i].size = _fileStream->readUint32LE();
- debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(_ixInfo.indices[i].id), _ixInfo.indices[i].offset, _ixInfo.indices[i].size);
+ 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);
}
break;
default:
error("Unknown tag \'%s\' found", tag2str(tag));
}
+
+ return true;
}
-void AVIDecoder::handleList() {
- uint32 listSize = _fileStream->readUint32LE() - 4; // Subtract away listType's 4 bytes
+void AVIDecoder::skipChunk(uint32 size) {
+ // Make sure we're aligned on a word boundary
+ _fileStream->skip(size + (size & 1));
+}
+
+void AVIDecoder::handleList(uint32 listSize) {
uint32 listType = _fileStream->readUint32BE();
+ listSize -= 4; // Subtract away listType's 4 bytes
uint32 curPos = _fileStream->pos();
debug(0, "Found LIST of type %s", tag2str(listType));
- if (listType == ID_MOVI) {
- // Found the 'movi' list
- // We're done parsing everything
+ switch (listType) {
+ case ID_MOVI: // Movie List
+ // We found the movie block
_foundMovieList = true;
+ _movieListStart = curPos;
+ _fileStream->skip(listSize);
return;
+ case ID_HDRL: // Header List
+ // Mark the header as decoded
+ _decodedHeader = true;
+ break;
+ case ID_INFO: // Metadata
+ case ID_PRMI: // Unknown metadata, should be safe to ignore
+ // Ignore metadata
+ _fileStream->skip(listSize);
+ return;
+ case ID_STRL: // Stream list
+ default: // (Just hope we can parse it!)
+ break;
}
while ((_fileStream->pos() - curPos) < listSize)
- runHandle(_fileStream->readUint32BE());
-
- // We now have all the header data
- if (listType == ID_HDRL)
- _decodedHeader = true;
+ parseNextChunk();
}
-void AVIDecoder::handleStreamHeader() {
+void AVIDecoder::handleStreamHeader(uint32 size) {
AVIStreamHeader sHeader;
- sHeader.size = _fileStream->readUint32LE();
+ sHeader.size = size;
sHeader.streamType = _fileStream->readUint32BE();
if (sHeader.streamType == ID_MIDS || sHeader.streamType == ID_TXTS)
@@ -247,21 +263,22 @@ void AVIDecoder::handleStreamHeader() {
if (sHeader.streamHandler == 0)
sHeader.streamHandler = bmInfo.compression;
- AVIVideoTrack *track = new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo);
+ byte *initialPalette = 0;
if (bmInfo.bitCount == 8) {
- byte *palette = const_cast<byte *>(track->getPalette());
+ initialPalette = new byte[256 * 3];
+ memset(initialPalette, 0, 256 * 3);
+
+ byte *palette = initialPalette;
for (uint32 i = 0; i < bmInfo.clrUsed; i++) {
palette[i * 3 + 2] = _fileStream->readByte();
palette[i * 3 + 1] = _fileStream->readByte();
palette[i * 3] = _fileStream->readByte();
_fileStream->readByte();
}
-
- track->markPaletteDirty();
}
- addTrack(track);
+ addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette));
} else if (sHeader.streamType == ID_AUDS) {
PCMWaveFormat wvInfo;
wvInfo.tag = _fileStream->readUint16LE();
@@ -286,28 +303,41 @@ void AVIDecoder::handleStreamHeader() {
bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
- _fileStream = stream;
- _decodedHeader = false;
- _foundMovieList = false;
+ uint32 riffTag = stream->readUint32BE();
+ if (riffTag != ID_RIFF) {
+ warning("Failed to find RIFF header");
+ return false;
+ }
- // Read chunks until we have decoded the header
- while (!_decodedHeader && _fileStream->pos() < _fileStream->size())
- runHandle(_fileStream->readUint32BE());
+ /* uint32 fileSize = */ stream->readUint32LE();
+ uint32 riffType = stream->readUint32BE();
- if (_fileStream->pos() >= _fileStream->size()) {
- warning("Failed to find AVI header");
+ if (riffType != ID_AVI) {
+ warning("RIFF not an AVI file");
return false;
}
- // Then read until we find the movie list
- while (!_foundMovieList && _fileStream->pos() < _fileStream->size())
- runHandle(_fileStream->readUint32BE());
+ _fileStream = stream;
+
+ // Go through all chunks in the file
+ while (parseNextChunk())
+ ;
+
+ if (!_decodedHeader) {
+ warning("Failed to parse AVI header");
+ close();
+ return false;
+ }
- if (_fileStream->pos() >= _fileStream->size()) {
- warning("Failed to find AVI 'movi' LIST");
+ if (!_foundMovieList) {
+ warning("Failed to find 'MOVI' list");
+ close();
return false;
}
+ // Seek back to the start of the MOVI list
+ _fileStream->seek(_movieListStart);
+
return true;
}
@@ -318,33 +348,35 @@ void AVIDecoder::close() {
_fileStream = 0;
_decodedHeader = false;
_foundMovieList = false;
+ _movieListStart = 0;
- delete[] _ixInfo.indices;
- memset(&_ixInfo, 0, sizeof(_ixInfo));
+ _indexEntries.clear();
memset(&_header, 0, sizeof(_header));
}
void AVIDecoder::readNextPacket() {
uint32 nextTag = _fileStream->readUint32BE();
+ uint32 size = _fileStream->readUint32LE();
if (_fileStream->eos())
return;
if (nextTag == ID_LIST) {
// A list of audio/video chunks
- uint32 listSize = _fileStream->readUint32LE() - 4;
int32 startPos = _fileStream->pos();
if (_fileStream->readUint32BE() != ID_REC)
error("Expected 'rec ' LIST");
+ size -= 4; // subtract list type
+
// Decode chunks in the list
- while (_fileStream->pos() < startPos + (int32)listSize)
+ while (_fileStream->pos() < startPos + (int32)size)
readNextPacket();
return;
} else if (nextTag == ID_JUNK || nextTag == ID_IDX1) {
- runHandle(nextTag);
+ skipChunk(size);
return;
}
@@ -353,16 +385,15 @@ void AVIDecoder::readNextPacket() {
if (!track)
error("Cannot get track from tag '%s'", tag2str(nextTag));
- uint32 chunkSize = _fileStream->readUint32LE();
Common::SeekableReadStream *chunk = 0;
- if (chunkSize != 0) {
- chunk = _fileStream->readStream(chunkSize);
- _fileStream->skip(chunkSize & 1);
+ if (size != 0) {
+ chunk = _fileStream->readStream(size);
+ _fileStream->skip(size & 1);
}
if (track->getTrackType() == Track::kTrackTypeAudio) {
- if (getStreamType(nextTag) != MKTAG16('w', 'b'))
+ if (getStreamType(nextTag) != kStreamTypeAudio)
error("Invalid audio track tag '%s'", tag2str(nextTag));
assert(chunk);
@@ -370,29 +401,10 @@ void AVIDecoder::readNextPacket() {
} else {
AVIVideoTrack *videoTrack = (AVIVideoTrack *)track;
- if (getStreamType(nextTag) == MKTAG16('p', 'c')) {
+ if (getStreamType(nextTag) == kStreamTypePaletteChange) {
// Palette Change
- assert(chunk);
- byte firstEntry = chunk->readByte();
- uint16 numEntries = chunk->readByte();
- chunk->readUint16LE(); // Reserved
-
- // 0 entries means all colors are going to be changed
- if (numEntries == 0)
- numEntries = 256;
-
- byte *palette = const_cast<byte *>(videoTrack->getPalette());
-
- for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
- palette[i * 3] = chunk->readByte();
- palette[i * 3 + 1] = chunk->readByte();
- palette[i * 3 + 2] = chunk->readByte();
- chunk->readByte(); // Flags that don't serve us any purpose
- }
-
- delete chunk;
- videoTrack->markPaletteDirty();
- } else if (getStreamType(nextTag) == MKTAG16('d', 'b')) {
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else if (getStreamType(nextTag) == kStreamTypeRawVideo) {
// TODO: Check if this really is uncompressed. Many videos
// falsely put compressed data in here.
error("Uncompressed AVI frame found");
@@ -403,17 +415,220 @@ void AVIDecoder::readNextPacket() {
}
}
-AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader)
- : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader) {
- memset(_palette, 0, sizeof(_palette));
+bool AVIDecoder::rewind() {
+ if (!VideoDecoder::rewind())
+ return false;
+
+ _fileStream->seek(_movieListStart);
+ return true;
+}
+
+bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
+ // Can't seek beyond the end
+ if (time > getDuration())
+ return false;
+
+ // Track down our video track (optionally audio too).
+ // We only support seeking with one 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++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
+ if (videoTrack) {
+ // Already have one
+ // -> Not supported
+ return false;
+ }
+
+ 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;
+ }
+ }
+
+ // Need a video track to go forwards
+ // If there isn't a video track, why would anyone be using AVI then?
+ if (!videoTrack)
+ return false;
+
+ // If we seek directly to the end, just mark the tracks as over
+ if (time == getDuration()) {
+ videoTrack->setCurFrame(videoTrack->getFrameCount() - 1);
+
+ if (audioTrack)
+ audioTrack->resetStream();
+
+ return true;
+ }
+
+ // Get the frame we should be on at this time
+ uint frame = videoTrack->getFrameAtTime(time);
+
+ // Reset any palette, if necessary
+ videoTrack->useInitialPalette();
+
+ int lastKeyFrame = -1;
+ int frameIndex = -1;
+ int lastRecord = -1;
+ uint curFrame = 0;
+
+ // Go through and figure out where we should be
+ // If there's a palette, we need to find the palette too
+ for (uint32 i = 0; i < _indexEntries.size(); i++) {
+ const OldIndex &index = _indexEntries[i];
+
+ if (index.id == ID_REC) {
+ // Keep track of any records we find
+ lastRecord = i;
+ } else {
+ if (getStreamIndex(index.id) != videoIndex)
+ continue;
+
+ uint16 streamType = getStreamType(index.id);
+
+ if (streamType == kStreamTypePaletteChange) {
+ // We need to handle any palette change we see since there's no
+ // flag to tell if this is a "key" palette.
+ // Decode the palette
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = 0;
+
+ if (_indexEntries[i].size != 0)
+ chunk = _fileStream->readStream(_indexEntries[i].size);
+
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else {
+ // Check to see if this is a keyframe
+ // The first frame has to be a keyframe
+ if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0)
+ lastKeyFrame = i;
+
+ // Did we find the target frame?
+ if (frame == curFrame) {
+ frameIndex = i;
+ break;
+ }
+
+ curFrame++;
+ }
+ }
+ }
+
+ if (frameIndex < 0) // This shouldn't happen.
+ return false;
+
+ if (audioTrack) {
+ // We need to find where the start of audio should be.
+ // Which is exactly 'initialFrames' audio chunks back from where
+ // our found frame is.
+
+ // Recreate the audio stream
+ audioTrack->resetStream();
+
+ uint framesNeeded = _header.initialFrames;
+ uint startAudioChunk = 0;
+ int startAudioSearch = (lastRecord < 0) ? (frameIndex - 1) : (lastRecord - 1);
+
+ for (int i = startAudioSearch; i >= 0; i--) {
+ if (getStreamIndex(_indexEntries[i].id) != audioIndex)
+ continue;
+
+ assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
+
+ framesNeeded--;
+
+ if (framesNeeded == 0) {
+ startAudioChunk = i;
+ break;
+ }
+ }
+
+ // Now go forward and queue them all
+ for (int i = startAudioChunk; i <= startAudioSearch; i++) {
+ if (_indexEntries[i].id == ID_REC)
+ continue;
+
+ if (getStreamIndex(_indexEntries[i].id) != audioIndex)
+ continue;
+
+ assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
+
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = _fileStream->readStream(_indexEntries[i].size);
+ audioTrack->queueSound(chunk);
+ }
+
+ // Skip any audio to bring us to the right time
+ audioTrack->skipAudio(time, videoTrack->getFrameTime(frame));
+ }
+
+ // Decode from keyFrame to curFrame - 1
+ for (int i = lastKeyFrame; i < frameIndex; i++) {
+ if (_indexEntries[i].id == ID_REC)
+ continue;
+
+ if (getStreamIndex(_indexEntries[i].id) != videoIndex)
+ continue;
+
+ uint16 streamType = getStreamType(_indexEntries[i].id);
+
+ // Ignore palettes, they were already handled
+ if (streamType == kStreamTypePaletteChange)
+ continue;
+
+ // Frame, hopefully
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = 0;
+
+ if (_indexEntries[i].size != 0)
+ chunk = _fileStream->readStream(_indexEntries[i].size);
+
+ videoTrack->decodeFrame(chunk);
+ }
+
+ // Seek to the right spot
+ // To the beginning of the last record, or frame if that doesn't exist
+ if (lastRecord >= 0)
+ _fileStream->seek(_indexEntries[lastRecord].offset);
+ else
+ _fileStream->seek(_indexEntries[frameIndex].offset);
+
+ videoTrack->setCurFrame((int)frame - 1);
+
+ return true;
+}
+
+byte AVIDecoder::getStreamIndex(uint32 tag) const {
+ char string[3];
+ WRITE_BE_UINT16(string, tag >> 16);
+ string[2] = 0;
+ return strtol(string, 0, 16);
+}
+
+AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette)
+ : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) {
_videoCodec = createCodec();
- _dirtyPalette = false;
_lastFrame = 0;
_curFrame = -1;
+
+ useInitialPalette();
}
AVIDecoder::AVIVideoTrack::~AVIVideoTrack() {
delete _videoCodec;
+ delete[] _initialPalette;
}
void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) {
@@ -436,6 +651,47 @@ Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const {
return Graphics::PixelFormat();
}
+void AVIDecoder::AVIVideoTrack::loadPaletteFromChunk(Common::SeekableReadStream *chunk) {
+ assert(chunk);
+ byte firstEntry = chunk->readByte();
+ uint16 numEntries = chunk->readByte();
+ chunk->readUint16LE(); // Reserved
+
+ // 0 entries means all colors are going to be changed
+ if (numEntries == 0)
+ numEntries = 256;
+
+ for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
+ _palette[i * 3] = chunk->readByte();
+ _palette[i * 3 + 1] = chunk->readByte();
+ _palette[i * 3 + 2] = chunk->readByte();
+ chunk->readByte(); // Flags that don't serve us any purpose
+ }
+
+ delete chunk;
+ _dirtyPalette = true;
+}
+
+void AVIDecoder::AVIVideoTrack::useInitialPalette() {
+ _dirtyPalette = false;
+
+ if (_initialPalette) {
+ memcpy(_palette, _initialPalette, sizeof(_palette));
+ _dirtyPalette = true;
+ }
+}
+
+bool AVIDecoder::AVIVideoTrack::rewind() {
+ _curFrame = -1;
+
+ useInitialPalette();
+
+ delete _videoCodec;
+ _videoCodec = createCodec();
+ _lastFrame = 0;
+ return true;
+}
+
Codec *AVIDecoder::AVIVideoTrack::createCodec() {
switch (_vidsHeader.streamHandler) {
case ID_CRAM:
@@ -497,6 +753,31 @@ void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
}
}
+void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) {
+ Audio::Timestamp timeDiff = time.convertToFramerate(_wvInfo.samplesPerSec) - frameTime.convertToFramerate(_wvInfo.samplesPerSec);
+ int skipFrames = timeDiff.totalNumberOfFrames();
+
+ if (skipFrames <= 0)
+ return;
+
+ if (_audStream->isStereo())
+ skipFrames *= 2;
+
+ int16 *tempBuffer = new int16[skipFrames];
+ _audStream->readBuffer(tempBuffer, skipFrames);
+ delete[] tempBuffer;
+}
+
+void AVIDecoder::AVIAudioTrack::resetStream() {
+ delete _audStream;
+ _audStream = createAudioStream();
+}
+
+bool AVIDecoder::AVIAudioTrack::rewind() {
+ resetStream();
+ return true;
+}
+
Audio::AudioStream *AVIDecoder::AVIAudioTrack::getAudioStream() const {
return _audStream;
}
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 6082232464..fffcbfbe16 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef VIDEO_AVI_PLAYER_H
-#define VIDEO_AVI_PLAYER_H
+#ifndef VIDEO_AVI_DECODER_H
+#define VIDEO_AVI_DECODER_H
-#include "common/endian.h"
+#include "common/array.h"
#include "common/rational.h"
#include "common/rect.h"
#include "common/str.h"
@@ -66,8 +66,13 @@ public:
uint16 getWidth() const { return _header.width; }
uint16 getHeight() const { return _header.height; }
+ bool rewind();
+ bool isRewindable() const { return true; }
+ bool isSeekable() const;
+
protected:
void readNextPacket();
+ bool seekIntern(const Audio::Timestamp &time);
private:
struct BitmapInfoHeader {
@@ -102,13 +107,10 @@ private:
};
struct OldIndex {
+ uint32 id;
+ uint32 flags;
+ uint32 offset;
uint32 size;
- struct Index {
- uint32 id;
- uint32 flags;
- uint32 offset;
- uint32 size;
- } *indices;
};
// Index Flags
@@ -160,7 +162,7 @@ private:
class AVIVideoTrack : public FixedRateVideoTrack {
public:
- AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader);
+ AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette = 0);
~AVIVideoTrack();
void decodeFrame(Common::SeekableReadStream *stream);
@@ -173,7 +175,12 @@ private:
const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
const byte *getPalette() const { _dirtyPalette = false; return _palette; }
bool hasDirtyPalette() const { return _dirtyPalette; }
- void markPaletteDirty() { _dirtyPalette = true; }
+ void setCurFrame(int frame) { _curFrame = frame; }
+ void loadPaletteFromChunk(Common::SeekableReadStream *chunk);
+ void useInitialPalette();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
protected:
Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
@@ -182,6 +189,7 @@ private:
AVIStreamHeader _vidsHeader;
BitmapInfoHeader _bmInfo;
byte _palette[3 * 256];
+ byte *_initialPalette;
mutable bool _dirtyPalette;
int _frameCount, _curFrame;
@@ -197,6 +205,11 @@ private:
void queueSound(Common::SeekableReadStream *stream);
Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+ void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime);
+ void resetStream();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
protected:
Audio::AudioStream *getAudioStream() const;
@@ -218,19 +231,24 @@ private:
Audio::QueuingAudioStream *createAudioStream();
};
- OldIndex _ixInfo;
+ Common::Array<OldIndex> _indexEntries;
AVIHeader _header;
Common::SeekableReadStream *_fileStream;
- bool _decodedHeader, _foundMovieList;
+ bool _decodedHeader;
+ bool _foundMovieList;
+ uint32 _movieListStart;
Audio::Mixer::SoundType _soundType;
Common::Rational _frameRateOverride;
void initCommon();
- void runHandle(uint32 tag);
- void handleList();
- void handleStreamHeader();
+ bool parseNextChunk();
+ void skipChunk(uint32 size);
+ void handleList(uint32 listSize);
+ void handleStreamHeader(uint32 size);
+ uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
+ byte getStreamIndex(uint32 tag) const;
};
} // End of namespace Video
diff --git a/video/codecs/cdtoons.cpp b/video/codecs/cdtoons.cpp
index 528cee8094..68925ed0db 100644
--- a/video/codecs/cdtoons.cpp
+++ b/video/codecs/cdtoons.cpp
@@ -298,7 +298,7 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
for (uint i = 0; i < actions.size(); i++) {
CDToonsAction &action = actions[i];
if (i == 0 && action.blockId == 0)
- memset(_surface->pixels, backgroundColor, _surface->w * _surface->h);
+ memset(_surface->getPixels(), backgroundColor, _surface->w * _surface->h);
if (!_blocks.contains(action.blockId))
continue;
if (!action.rect.right)
diff --git a/video/codecs/cinepak.cpp b/video/codecs/cinepak.cpp
index bcf0cf1180..a7782f4192 100644
--- a/video/codecs/cinepak.cpp
+++ b/video/codecs/cinepak.cpp
@@ -41,11 +41,11 @@ namespace Video {
byte b = _clipTable[lum + (u << 1)]; \
\
if (_pixelFormat.bytesPerPixel == 2) \
- *((uint16 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b); \
+ *((uint16 *)_curFrame.surface->getPixels() + offset) = _pixelFormat.RGBToColor(r, g, b); \
else \
- *((uint32 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b); \
+ *((uint32 *)_curFrame.surface->getPixels() + offset) = _pixelFormat.RGBToColor(r, g, b); \
} else \
- *((byte *)_curFrame.surface->pixels + offset) = lum
+ *((byte *)_curFrame.surface->getPixels() + offset) = lum
CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec() {
_curFrame.surface = NULL;
diff --git a/video/codecs/codec.h b/video/codecs/codec.h
index c1194e461b..a4ad786bb0 100644
--- a/video/codecs/codec.h
+++ b/video/codecs/codec.h
@@ -51,7 +51,7 @@ public:
* containing the decoded frame.
*
* @return a pointer to the decoded frame
- * @note stream is not deleted
+ * @note stream is not deleted
*/
virtual const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream) = 0;
diff --git a/video/codecs/mpeg.cpp b/video/codecs/mpeg.cpp
index cb3c63fcfc..4540b4182e 100644
--- a/video/codecs/mpeg.cpp
+++ b/video/codecs/mpeg.cpp
@@ -58,7 +58,7 @@ const Graphics::Surface *MPEGDecoder::decodeImage(Common::SeekableReadStream *st
return _surface;
}
-bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst) {
+bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst) {
// Decode as much as we can out of this packet
uint32 size = 0xFFFFFFFF;
mpeg2_state_t state;
diff --git a/video/codecs/msrle.cpp b/video/codecs/msrle.cpp
index fa03a59efd..2f2ac0334f 100644
--- a/video/codecs/msrle.cpp
+++ b/video/codecs/msrle.cpp
@@ -53,7 +53,7 @@ void MSRLEDecoder::decode8(Common::SeekableReadStream *stream) {
int x = 0;
int y = _surface->h - 1;
- byte *data = (byte *) _surface->pixels;
+ byte *data = (byte *) _surface->getPixels();
uint16 width = _surface->w;
uint16 height = _surface->h;
diff --git a/video/codecs/msvideo1.cpp b/video/codecs/msvideo1.cpp
index 06e4640025..409d588ddf 100644
--- a/video/codecs/msvideo1.cpp
+++ b/video/codecs/msvideo1.cpp
@@ -48,7 +48,7 @@ MSVideo1Decoder::~MSVideo1Decoder() {
void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
byte colors[8];
- byte *pixels = (byte *)_surface->pixels;
+ byte *pixels = (byte *)_surface->getPixels();
uint16 stride = _surface->w;
int skipBlocks = 0;
diff --git a/video/codecs/qtrle.cpp b/video/codecs/qtrle.cpp
index d2cdea27de..1f1fee7997 100644
--- a/video/codecs/qtrle.cpp
+++ b/video/codecs/qtrle.cpp
@@ -61,7 +61,7 @@ QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Cod
void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- byte *rgb = (byte *)_surface->pixels;
+ byte *rgb = (byte *)_surface->getPixels();
while (linesToChange) {
CHECK_STREAM_PTR(2);
@@ -105,7 +105,7 @@ void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, ui
void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp) {
uint32 pixelPtr = 0;
- byte *rgb = (byte *)_surface->pixels;
+ byte *rgb = (byte *)_surface->getPixels();
byte numPixels = (bpp == 4) ? 8 : 16;
while (linesToChange--) {
@@ -165,7 +165,7 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- byte *rgb = (byte *)_surface->pixels;
+ byte *rgb = (byte *)_surface->getPixels();
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -210,7 +210,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- uint16 *rgb = (uint16 *)_surface->pixels;
+ uint16 *rgb = (uint16 *)_surface->getPixels();
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -248,7 +248,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- uint32 *rgb = (uint32 *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->getPixels();
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -294,7 +294,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- uint32 *rgb = (uint32 *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->getPixels();
while (linesToChange--) {
CHECK_STREAM_PTR(2);
diff --git a/video/codecs/rpza.cpp b/video/codecs/rpza.cpp
index 0a9f87747e..17a2c53d9b 100644
--- a/video/codecs/rpza.cpp
+++ b/video/codecs/rpza.cpp
@@ -58,7 +58,7 @@ RPZADecoder::~RPZADecoder() {
#define PUT_PIXEL(color) \
if ((int32)blockPtr < _surface->w * _surface->h) \
- WRITE_UINT16((uint16 *)_surface->pixels + blockPtr, color); \
+ WRITE_UINT16((uint16 *)_surface->getPixels() + blockPtr, color); \
blockPtr++
const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) {
diff --git a/video/codecs/smc.cpp b/video/codecs/smc.cpp
index 2eedb62a0f..c0f8152547 100644
--- a/video/codecs/smc.cpp
+++ b/video/codecs/smc.cpp
@@ -56,7 +56,7 @@ SMCDecoder::~SMCDecoder() {
}
const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *stream) {
- byte *pixels = (byte *)_surface->pixels;
+ byte *pixels = (byte *)_surface->getPixels();
uint32 numBlocks = 0;
uint32 colorFlags = 0;
diff --git a/video/codecs/truemotion1.cpp b/video/codecs/truemotion1.cpp
index e475c8426c..720e86a4ff 100644
--- a/video/codecs/truemotion1.cpp
+++ b/video/codecs/truemotion1.cpp
@@ -400,11 +400,14 @@ void TrueMotion1Decoder::decode16() {
const Graphics::Surface *TrueMotion1Decoder::decodeImage(Common::SeekableReadStream *stream) {
decodeHeader(stream);
- if (compressionTypes[_header.compression].algorithm == ALGO_NOP)
+ if (compressionTypes[_header.compression].algorithm == ALGO_NOP) {
+ delete[] _buf;
return 0;
+ }
if (compressionTypes[_header.compression].algorithm == ALGO_RGB24H) {
warning("Unhandled TrueMotion1 24bpp frame");
+ delete[] _buf;
return 0;
} else
decode16();
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index 4c3b6f8414..024e479bf7 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -97,12 +97,8 @@ void CoktelDecoder::setSurfaceMemory(void *mem, uint16 width, uint16 height, uin
assert(bpp == getPixelFormat().bytesPerPixel);
// Create a surface over this memory
- _surface.w = width;
- _surface.h = height;
- _surface.pitch = width * bpp;
- _surface.pixels = mem;
// TODO: Check whether it is fine to assume we want the setup PixelFormat.
- _surface.format = getPixelFormat();
+ _surface.init(width, height, width * bpp, mem, getPixelFormat());
_ownSurface = false;
}
@@ -122,7 +118,7 @@ const Graphics::Surface *CoktelDecoder::getSurface() const {
}
bool CoktelDecoder::hasSurface() {
- return _surface.pixels != 0;
+ return _surface.getPixels();
}
void CoktelDecoder::createSurface() {
@@ -143,7 +139,7 @@ void CoktelDecoder::freeSurface() {
_surface.w = 0;
_surface.h = 0;
_surface.pitch = 0;
- _surface.pixels = 0;
+ _surface.setPixels(0);
_surface.format = Graphics::PixelFormat();
} else
_surface.free();
@@ -473,7 +469,7 @@ void CoktelDecoder::renderBlockWhole(Graphics::Surface &dstSurf, const byte *src
rect.clip(dstSurf.w, dstSurf.h);
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left * dstSurf.format.bytesPerPixel;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
for (int i = 0; i < rect.height(); i++) {
memcpy(dst, src, rect.width() * dstSurf.format.bytesPerPixel);
@@ -488,7 +484,7 @@ void CoktelDecoder::renderBlockWhole4X(Graphics::Surface &dstSurf, const byte *s
rect.clip(dstSurf.w, dstSurf.h);
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
for (int i = 0; i < rect.height(); i++) {
byte *dstRow = dst;
const byte *srcRow = src;
@@ -515,7 +511,7 @@ void CoktelDecoder::renderBlockWhole2Y(Graphics::Surface &dstSurf, const byte *s
int16 height = rect.height();
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
while (height > 1) {
memcpy(dst , src, rect.width());
memcpy(dst + dstSurf.pitch, src, rect.width());
@@ -535,7 +531,7 @@ void CoktelDecoder::renderBlockSparse(Graphics::Surface &dstSurf, const byte *sr
rect.clip(dstSurf.w, dstSurf.h);
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
for (int i = 0; i < rect.height(); i++) {
byte *dstRow = dst;
int16 pixWritten = 0;
@@ -572,7 +568,7 @@ void CoktelDecoder::renderBlockSparse2Y(Graphics::Surface &dstSurf, const byte *
rect.clip(dstSurf.w, dstSurf.h);
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
for (int i = 0; i < rect.height(); i += 2) {
byte *dstRow = dst;
int16 pixWritten = 0;
@@ -604,7 +600,7 @@ void CoktelDecoder::renderBlockRLE(Graphics::Surface &dstSurf, const byte *src,
rect.clip(dstSurf.w, dstSurf.h);
- byte *dst = (byte *)dstSurf.pixels + (rect.top * dstSurf.pitch) + rect.left;
+ byte *dst = (byte *)dstSurf.getBasePtr(rect.left, rect.top);
for (int i = 0; i < rect.height(); i++) {
byte *dstRow = dst;
int16 pixWritten = 0;
@@ -865,7 +861,7 @@ void PreIMDDecoder::renderFrame() {
uint16 h = CLIP<int32>(_surface.h - _y, 0, _height);
const byte *src = _videoBuffer;
- byte *dst = (byte *)_surface.pixels + (_y * _surface.pitch) + _x;
+ byte *dst = (byte *)_surface.getBasePtr(_x, _y);
uint32 frameDataSize = _videoBufferSize;
@@ -1458,7 +1454,7 @@ bool IMDDecoder::renderFrame(Common::Rect &rect) {
const int offsetY = (_y + rect.top) * _surface.pitch;
const int offset = offsetX + offsetY;
- if (deLZ77((byte *)_surface.pixels + offset, dataPtr, dataSize,
+ if (deLZ77((byte *)_surface.getPixels() + offset, dataPtr, dataSize,
_surface.w * _surface.h * _surface.format.bytesPerPixel - offset))
return true;
}
@@ -1879,11 +1875,8 @@ bool VMDDecoder::assessVideoProperties() {
_videoBuffer[i] = new byte[_videoBufferSize];
memset(_videoBuffer[i], 0, _videoBufferSize);
- _8bppSurface[i].w = _width * _bytesPerPixel;
- _8bppSurface[i].h = _height;
- _8bppSurface[i].pitch = _width * _bytesPerPixel;
- _8bppSurface[i].pixels = _videoBuffer[i];
- _8bppSurface[i].format = Graphics::PixelFormat::createFormatCLUT8();
+ _8bppSurface[i].init(_width * _bytesPerPixel, _height, _width * _bytesPerPixel,
+ _videoBuffer[i], Graphics::PixelFormat::createFormatCLUT8());
}
}
@@ -2277,7 +2270,7 @@ bool VMDDecoder::renderFrame(Common::Rect &rect) {
rect = Common::Rect(_x, _y, _x + codecSurf->w, _y + codecSurf->h);
rect.clip(Common::Rect(_x, _y, _x + _width, _y + _height));
- renderBlockWhole(_surface, (const byte *) codecSurf->pixels, rect);
+ renderBlockWhole(_surface, (const byte *)codecSurf->getPixels(), rect);
return true;
}
@@ -2298,7 +2291,7 @@ bool VMDDecoder::renderFrame(Common::Rect &rect) {
const int offsetY = (_y + rect.top) * _surface.pitch;
const int offset = offsetX + offsetY;
- if (deLZ77((byte *)_surface.pixels + offset, dataPtr, dataSize,
+ if (deLZ77((byte *)_surface.getPixels() + offset, dataPtr, dataSize,
_surface.w * _surface.h * _surface.format.bytesPerPixel - offset))
return true;
}
@@ -2406,10 +2399,11 @@ void VMDDecoder::blit16(const Graphics::Surface &srcSurf, Common::Rect &rect) {
Graphics::PixelFormat pixelFormat = getPixelFormat();
- const byte *src = (byte *)srcSurf.pixels +
+ // We cannot use getBasePtr here because srcSurf.format.bytesPerPixel is
+ // different from _bytesPerPixel.
+ const byte *src = (const byte *)srcSurf.getPixels() +
(srcRect.top * srcSurf.pitch) + srcRect.left * _bytesPerPixel;
- byte *dst = (byte *)_surface.pixels +
- ((_y + rect.top) * _surface.pitch) + (_x + rect.left) * _surface.format.bytesPerPixel;
+ byte *dst = (byte *)_surface.getBasePtr(_x + rect.left, _y + rect.top);
for (int i = 0; i < rect.height(); i++) {
const byte *srcRow = src;
@@ -2446,10 +2440,11 @@ void VMDDecoder::blit24(const Graphics::Surface &srcSurf, Common::Rect &rect) {
Graphics::PixelFormat pixelFormat = getPixelFormat();
- const byte *src = (byte *)srcSurf.pixels +
+ // We cannot use getBasePtr here because srcSurf.format.bytesPerPixel is
+ // different from _bytesPerPixel.
+ const byte *src = (const byte *)srcSurf.getPixels() +
(srcRect.top * srcSurf.pitch) + srcRect.left * _bytesPerPixel;
- byte *dst = (byte *)_surface.pixels +
- ((_y + rect.top) * _surface.pitch) + (_x + rect.left) * _surface.format.bytesPerPixel;
+ byte *dst = (byte *)_surface.getBasePtr(_x + rect.left, _y + rect.top);
for (int i = 0; i < rect.height(); i++) {
const byte *srcRow = src;
diff --git a/video/dxa_decoder.cpp b/video/dxa_decoder.cpp
index 5ac9bd2088..27b1664b07 100644
--- a/video/dxa_decoder.cpp
+++ b/video/dxa_decoder.cpp
@@ -521,17 +521,17 @@ const Graphics::Surface *DXADecoder::DXAVideoTrack::decodeNextFrame() {
memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
memset(&_scaledBuffer[((2 * cy) + 1) * _width], 0, _width);
}
- _surface->pixels = _scaledBuffer;
+ _surface->setPixels(_scaledBuffer);
break;
case S_DOUBLE:
for (int cy = 0; cy < _curHeight; cy++) {
memcpy(&_scaledBuffer[2 * cy * _width], &_frameBuffer1[cy * _width], _width);
memcpy(&_scaledBuffer[((2 * cy) + 1) * _width], &_frameBuffer1[cy * _width], _width);
}
- _surface->pixels = _scaledBuffer;
+ _surface->setPixels(_scaledBuffer);
break;
case S_NONE:
- _surface->pixels = _frameBuffer1;
+ _surface->setPixels(_frameBuffer1);
break;
}
diff --git a/video/flic_decoder.cpp b/video/flic_decoder.cpp
index de545366b1..317dc14691 100644
--- a/video/flic_decoder.cpp
+++ b/video/flic_decoder.cpp
@@ -244,7 +244,7 @@ void FlicDecoder::FlicVideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch)
for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
for (int y = (*it).top; y < (*it).bottom; ++y) {
const int x = (*it).left;
- memcpy(dst + y * pitch + x, (byte *)_surface->pixels + y * getWidth() + x, (*it).right - x);
+ memcpy(dst + y * pitch + x, (byte *)_surface->getBasePtr(x, y), (*it).right - x);
}
}
@@ -252,7 +252,7 @@ void FlicDecoder::FlicVideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch)
}
void FlicDecoder::FlicVideoTrack::copyFrame(uint8 *data) {
- memcpy((byte *)_surface->pixels, data, getWidth() * getHeight());
+ memcpy((byte *)_surface->getPixels(), data, getWidth() * getHeight());
// Redraw
_dirtyRects.clear();
@@ -260,8 +260,8 @@ void FlicDecoder::FlicVideoTrack::copyFrame(uint8 *data) {
}
void FlicDecoder::FlicVideoTrack::decodeByteRun(uint8 *data) {
- byte *ptr = (byte *)_surface->pixels;
- while ((int32)(ptr - (byte *)_surface->pixels) < (getWidth() * getHeight())) {
+ byte *ptr = (byte *)_surface->getPixels();
+ while ((int32)(ptr - (byte *)_surface->getPixels()) < (getWidth() * getHeight())) {
int chunks = *data++;
while (chunks--) {
int count = (int8)*data++;
@@ -305,7 +305,7 @@ void FlicDecoder::FlicVideoTrack::decodeDeltaFLC(uint8 *data) {
case OP_UNDEFINED:
break;
case OP_LASTPIXEL:
- *((byte *)_surface->pixels + currentLine * getWidth() + getWidth() - 1) = (opcode & 0xFF);
+ *((byte *)_surface->getBasePtr(getWidth() - 1, currentLine)) = (opcode & 0xFF);
_dirtyRects.push_back(Common::Rect(getWidth() - 1, currentLine, getWidth(), currentLine + 1));
break;
case OP_LINESKIPCOUNT:
@@ -321,14 +321,14 @@ void FlicDecoder::FlicVideoTrack::decodeDeltaFLC(uint8 *data) {
column += *data++;
int rleCount = (int8)*data++;
if (rleCount > 0) {
- memcpy((byte *)_surface->pixels + (currentLine * getWidth()) + column, data, rleCount * 2);
+ memcpy((byte *)_surface->getBasePtr(column, currentLine), data, rleCount * 2);
data += rleCount * 2;
_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
} else if (rleCount < 0) {
rleCount = -rleCount;
uint16 dataWord = READ_UINT16(data); data += 2;
for (int i = 0; i < rleCount; ++i) {
- WRITE_UINT16((byte *)_surface->pixels + currentLine * getWidth() + column + i * 2, dataWord);
+ WRITE_UINT16((byte *)_surface->getBasePtr(column + i * 2, currentLine), dataWord);
}
_dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
} else { // End of cutscene ?
diff --git a/video/smk_decoder.cpp b/video/smk_decoder.cpp
index b622a0ab61..3dbcebcde4 100644
--- a/video/smk_decoder.cpp
+++ b/video/smk_decoder.cpp
@@ -580,7 +580,7 @@ void SmackerDecoder::SmackerVideoTrack::decodeFrame(Common::BitStream &bs) {
while (run-- && block < blocks) {
clr = _MClrTree->getCode(bs);
map = _MMapTree->getCode(bs);
- out = (byte *)_surface->pixels + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+ out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
hi = clr >> 8;
lo = clr & 0xff;
for (i = 0; i < 4; i++) {
@@ -613,7 +613,7 @@ void SmackerDecoder::SmackerVideoTrack::decodeFrame(Common::BitStream &bs) {
}
while (run-- && block < blocks) {
- out = (byte *)_surface->pixels + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+ out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
switch (mode) {
case 0:
for (i = 0; i < 4; ++i) {
@@ -679,7 +679,7 @@ void SmackerDecoder::SmackerVideoTrack::decodeFrame(Common::BitStream &bs) {
uint32 col;
mode = type >> 8;
while (run-- && block < blocks) {
- out = (byte *)_surface->pixels + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
+ out = (byte *)_surface->getPixels() + (block / bw) * (stride * 4 * doubleY) + (block % bw) * 4;
col = mode * 0x01010101;
for (i = 0; i < 4 * doubleY; ++i) {
out[0] = out[1] = out[2] = out[3] = col;
diff --git a/video/theora_decoder.cpp b/video/theora_decoder.cpp
index 63aa93e2f5..a0ee0a36b4 100644
--- a/video/theora_decoder.cpp
+++ b/video/theora_decoder.cpp
@@ -262,11 +262,8 @@ TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(const Graphics::PixelFormat &f
_surface.create(theoraInfo.frame_width, theoraInfo.frame_height, format);
// Set up a display surface
- _displaySurface.pixels = _surface.getBasePtr(theoraInfo.pic_x, theoraInfo.pic_y);
- _displaySurface.w = theoraInfo.pic_width;
- _displaySurface.h = theoraInfo.pic_height;
- _displaySurface.format = format;
- _displaySurface.pitch = _surface.pitch;
+ _displaySurface.init(theoraInfo.pic_width, theoraInfo.pic_height, _surface.pitch,
+ _surface.getBasePtr(theoraInfo.pic_x, theoraInfo.pic_y), format);
// Set the frame rate
_frameRate = Common::Rational(theoraInfo.fps_numerator, theoraInfo.fps_denominator);
@@ -280,7 +277,7 @@ TheoraDecoder::TheoraVideoTrack::~TheoraVideoTrack() {
th_decode_free(_theoraDecode);
_surface.free();
- _displaySurface.pixels = 0;
+ _displaySurface.setPixels(0);
}
bool TheoraDecoder::TheoraVideoTrack::decodePacket(ogg_packet &oggPacket) {
@@ -338,7 +335,7 @@ TheoraDecoder::VorbisAudioTrack::VorbisAudioTrack(Audio::Mixer::SoundType soundT
vorbis_block_init(&_vorbisDSP, &_vorbisBlock);
info = &vorbisInfo;
- _audStream = Audio::makeQueuingAudioStream(vorbisInfo.rate, vorbisInfo.channels);
+ _audStream = Audio::makeQueuingAudioStream(vorbisInfo.rate, vorbisInfo.channels != 1);
_audioBufferFill = 0;
_audioBuffer = 0;
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 5df811008c..0ab1478727 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -62,6 +62,8 @@ void VideoDecoder::close() {
delete *it;
_tracks.clear();
+ _internalTracks.clear();
+ _externalTracks.clear();
_dirtyPalette = false;
_palette = 0;
_startTime = 0;
@@ -336,7 +338,12 @@ bool VideoDecoder::seek(const Audio::Timestamp &time) {
if (isPlaying())
stopAudio();
- for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ // Do the actual seeking
+ if (!seekIntern(time))
+ return false;
+
+ // Seek any external track too
+ for (TrackListIterator it = _externalTracks.begin(); it != _externalTracks.end(); it++)
if (!(*it)->seek(time))
return false;
@@ -356,12 +363,12 @@ bool VideoDecoder::seek(const Audio::Timestamp &time) {
}
bool VideoDecoder::seekToFrame(uint frame) {
+ if (!isSeekable())
+ return false;
+
VideoTrack *track = 0;
for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
- if (!(*it)->isSeekable())
- return false;
-
if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
// We only allow seeking by frame when one video track
// is present
@@ -471,6 +478,14 @@ Audio::Timestamp VideoDecoder::getDuration() const {
return maxDuration;
}
+bool VideoDecoder::seekIntern(const Audio::Timestamp &time) {
+ for (TrackList::iterator it = _internalTracks.begin(); it != _internalTracks.end(); it++)
+ if (!(*it)->seek(time))
+ return false;
+
+ return true;
+}
+
VideoDecoder::Track::Track() {
_paused = false;
}
@@ -516,10 +531,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) con
if (frameRate == frameRate.toInt()) // The nice case (a whole number)
return Audio::Timestamp(0, frame, frameRate.toInt());
- // Just convert to milliseconds.
- Common::Rational time = frame * 1000;
- time /= frameRate;
- return Audio::Timestamp(time.toInt(), 1000);
+ // Convert as best as possible
+ Common::Rational time = frameRate.getInverse() * frame;
+ return Audio::Timestamp(0, time.getNumerator(), time.getDenominator());
}
uint VideoDecoder::FixedRateVideoTrack::getFrameAtTime(const Audio::Timestamp &time) const {
@@ -529,8 +543,10 @@ uint VideoDecoder::FixedRateVideoTrack::getFrameAtTime(const Audio::Timestamp &t
if (frameRate == time.framerate())
return time.totalNumberOfFrames();
- // Default case
- return (time.totalNumberOfFrames() * frameRate / time.framerate()).toInt();
+ // Create the rational based on the time first to hopefully cancel out
+ // *something* when multiplying by the frameRate (which can be large in
+ // some AVI videos).
+ return (Common::Rational(time.totalNumberOfFrames(), time.framerate()) * frameRate).toInt();
}
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {
@@ -641,9 +657,14 @@ bool VideoDecoder::StreamFileAudioTrack::loadFromFile(const Common::String &base
return _stream != 0;
}
-void VideoDecoder::addTrack(Track *track) {
+void VideoDecoder::addTrack(Track *track, bool isExternal) {
_tracks.push_back(track);
+ if (isExternal)
+ _externalTracks.push_back(track);
+ else
+ _internalTracks.push_back(track);
+
if (track->getTrackType() == Track::kTrackTypeAudio) {
// Update volume settings if it's an audio track
((AudioTrack *)track)->setVolume(_audioVolume);
@@ -673,7 +694,7 @@ bool VideoDecoder::addStreamFileTrack(const Common::String &baseName) {
bool result = track->loadFromFile(baseName);
if (result)
- addTrack(track);
+ addTrack(track, true);
else
delete track;
@@ -704,17 +725,17 @@ void VideoDecoder::setEndTime(const Audio::Timestamp &endTime) {
}
VideoDecoder::Track *VideoDecoder::getTrack(uint track) {
- if (track > _tracks.size())
+ if (track > _internalTracks.size())
return 0;
- return _tracks[track];
+ return _internalTracks[track];
}
const VideoDecoder::Track *VideoDecoder::getTrack(uint track) const {
- if (track > _tracks.size())
+ if (track > _internalTracks.size())
return 0;
- return _tracks[track];
+ return _internalTracks[track];
}
bool VideoDecoder::endOfVideoTracks() const {
diff --git a/video/video_decoder.h b/video/video_decoder.h
index d0a6e08005..ac6586d8dd 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -168,14 +168,15 @@ public:
/**
* Seek to a given time in the video.
*
- * If the video is playing, it will continue to play. The default
- * implementation will seek each track and must still be called
- * from any other implementation.
+ * If the video is playing, it will continue to play. This calls
+ * seekIntern(), which can be overriden. By default, seekIntern()
+ * will call Track::seek() on all tracks with the time passed to
+ * this function.
*
* @param time The time to seek to
* @return true on success, false otherwise
*/
- virtual bool seek(const Audio::Timestamp &time);
+ bool seek(const Audio::Timestamp &time);
/**
* Seek to a given frame.
@@ -593,17 +594,17 @@ protected:
virtual Audio::Timestamp getDuration() const;
Audio::Timestamp getFrameTime(uint frame) const;
- protected:
- /**
- * Get the rate at which this track is played.
- */
- virtual Common::Rational getFrameRate() const = 0;
-
/**
* Get the frame that should be displaying at the given time. This is
* helpful for someone implementing seek().
*/
uint getFrameAtTime(const Audio::Timestamp &time) const;
+
+ protected:
+ /**
+ * Get the rate at which this track is played.
+ */
+ virtual Common::Rational getFrameRate() const = 0;
};
/**
@@ -760,8 +761,11 @@ protected:
* Define a track to be used by this class.
*
* The pointer is then owned by this base class.
+ *
+ * @param track The track to add
+ * @param isExternal Is this an external track not found by loadStream()?
*/
- void addTrack(Track *track);
+ void addTrack(Track *track, bool isExternal = false);
/**
* Whether or not getTime() will sync with a playing audio track.
@@ -813,16 +817,27 @@ protected:
/**
* Get the begin iterator of the tracks
*/
- TrackListIterator getTrackListBegin() { return _tracks.begin(); }
+ TrackListIterator getTrackListBegin() { return _internalTracks.begin(); }
/**
* Get the end iterator of the tracks
*/
- TrackListIterator getTrackListEnd() { return _tracks.end(); }
+ TrackListIterator getTrackListEnd() { return _internalTracks.end(); }
+
+ /**
+ * The internal seek function that does the actual seeking.
+ *
+ * @see seek()
+ *
+ * @return true on success, false otherwise
+ */
+ virtual bool seekIntern(const Audio::Timestamp &time);
private:
// Tracks owned by this VideoDecoder
TrackList _tracks;
+ TrackList _internalTracks;
+ TrackList _externalTracks;
// Current playback status
bool _needsUpdate;