aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/advancedDetector.cpp13
-rw-r--r--engines/advancedDetector.h6
-rw-r--r--engines/agi/POTFILES2
-rw-r--r--engines/agi/agi.cpp4
-rw-r--r--engines/agi/configure.engine3
-rw-r--r--engines/agi/detection_tables.h2
-rw-r--r--engines/agi/loader_v1.cpp2
-rw-r--r--engines/agi/loader_v2.cpp2
-rw-r--r--engines/agi/loader_v3.cpp2
-rw-r--r--engines/agi/opcodes.cpp24
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/preagi_troll.cpp2
-rw-r--r--engines/agi/preagi_winnie.cpp1
-rw-r--r--engines/agi/wagparser.cpp2
-rw-r--r--engines/agi/words.cpp23
-rw-r--r--engines/agos/POTFILES2
-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/configure.engine4
-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.cpp22
-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/avalanche/animation.cpp1498
-rw-r--r--engines/avalanche/animation.h171
-rw-r--r--engines/avalanche/avalanche.cpp629
-rw-r--r--engines/avalanche/avalanche.h348
-rw-r--r--engines/avalanche/avalot.cpp1755
-rw-r--r--engines/avalanche/avalot.h104
-rw-r--r--engines/avalanche/background.cpp370
-rw-r--r--engines/avalanche/background.h79
-rw-r--r--engines/avalanche/closing.cpp75
-rw-r--r--engines/avalanche/closing.h62
-rw-r--r--engines/avalanche/configure.engine3
-rw-r--r--engines/avalanche/console.cpp53
-rw-r--r--engines/avalanche/console.h51
-rw-r--r--engines/avalanche/detection.cpp209
-rw-r--r--engines/avalanche/dialogs.cpp1212
-rw-r--r--engines/avalanche/dialogs.h116
-rw-r--r--engines/avalanche/enums.h132
-rw-r--r--engines/avalanche/graphics.cpp767
-rw-r--r--engines/avalanche/graphics.h142
-rw-r--r--engines/avalanche/menu.cpp844
-rw-r--r--engines/avalanche/menu.h182
-rw-r--r--engines/avalanche/module.mk27
-rw-r--r--engines/avalanche/nim.cpp177
-rw-r--r--engines/avalanche/nim.h76
-rw-r--r--engines/avalanche/parser.cpp2481
-rw-r--r--engines/avalanche/parser.h153
-rw-r--r--engines/avalanche/pingo.cpp106
-rw-r--r--engines/avalanche/pingo.h59
-rw-r--r--engines/avalanche/sequence.cpp230
-rw-r--r--engines/avalanche/sequence.h80
-rw-r--r--engines/avalanche/sound.cpp88
-rw-r--r--engines/avalanche/sound.h53
-rw-r--r--engines/avalanche/timer.cpp693
-rw-r--r--engines/avalanche/timer.h178
-rw-r--r--engines/cge/cge.cpp1
-rw-r--r--engines/cge/cge.h6
-rw-r--r--engines/cge/cge_main.cpp8
-rw-r--r--engines/cge/configure.engine3
-rw-r--r--engines/cge/detection.cpp119
-rw-r--r--engines/cge/snail.cpp2
-rw-r--r--engines/cge/text.cpp5
-rw-r--r--engines/cge/vga13h.cpp9
-rw-r--r--engines/cine/configure.engine3
-rw-r--r--engines/cine/script_fw.cpp3
-rw-r--r--engines/cine/sound.cpp6
-rw-r--r--engines/composer/composer.cpp25
-rw-r--r--engines/composer/composer.h4
-rw-r--r--engines/composer/configure.engine3
-rw-r--r--engines/composer/graphics.cpp10
-rw-r--r--engines/configure.engines54
-rw-r--r--engines/cruise/POTFILES1
-rw-r--r--engines/cruise/configure.engine3
-rw-r--r--engines/cruise/cruise.h4
-rw-r--r--engines/cruise/detection.cpp37
-rw-r--r--engines/draci/barchive.cpp12
-rw-r--r--engines/draci/configure.engine3
-rw-r--r--engines/draci/draci.cpp26
-rw-r--r--engines/draci/game.cpp55
-rw-r--r--engines/draci/screen.cpp4
-rw-r--r--engines/draci/script.cpp110
-rw-r--r--engines/draci/sprite.cpp4
-rw-r--r--engines/draci/surface.cpp4
-rw-r--r--engines/draci/walking.cpp6
-rw-r--r--engines/draci/walking.h12
-rw-r--r--engines/drascula/POTFILES2
-rw-r--r--engines/drascula/actors.cpp16
-rw-r--r--engines/drascula/animation.cpp22
-rw-r--r--engines/drascula/configure.engine3
-rw-r--r--engines/drascula/console.cpp2
-rw-r--r--engines/drascula/converse.cpp22
-rw-r--r--engines/drascula/detection.cpp126
-rw-r--r--engines/drascula/drascula.cpp188
-rw-r--r--engines/drascula/drascula.h16
-rw-r--r--engines/drascula/graphics.cpp32
-rw-r--r--engines/drascula/interface.cpp8
-rw-r--r--engines/drascula/objects.cpp77
-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/POTFILES1
-rw-r--r--engines/dreamweb/configure.engine3
-rw-r--r--engines/dreamweb/dreamweb.cpp44
-rw-r--r--engines/dreamweb/dreamweb.h3
-rw-r--r--engines/dreamweb/monitor.cpp10
-rw-r--r--engines/dreamweb/print.cpp2
-rw-r--r--engines/engine.cpp2
-rw-r--r--engines/engines.mk248
-rw-r--r--engines/fullpipe/behavior.cpp334
-rw-r--r--engines/fullpipe/behavior.h88
-rw-r--r--engines/fullpipe/configure.engine3
-rw-r--r--engines/fullpipe/constants.h296
-rw-r--r--engines/fullpipe/detection.cpp112
-rw-r--r--engines/fullpipe/floaters.cpp45
-rw-r--r--engines/fullpipe/floaters.h67
-rw-r--r--engines/fullpipe/fullpipe.cpp451
-rw-r--r--engines/fullpipe/fullpipe.h262
-rw-r--r--engines/fullpipe/gameloader.cpp513
-rw-r--r--engines/fullpipe/gameloader.h117
-rw-r--r--engines/fullpipe/gfx.cpp1250
-rw-r--r--engines/fullpipe/gfx.h218
-rw-r--r--engines/fullpipe/init.cpp247
-rw-r--r--engines/fullpipe/input.cpp277
-rw-r--r--engines/fullpipe/input.h77
-rw-r--r--engines/fullpipe/interaction.cpp528
-rw-r--r--engines/fullpipe/interaction.h98
-rw-r--r--engines/fullpipe/inventory.cpp437
-rw-r--r--engines/fullpipe/inventory.h132
-rw-r--r--engines/fullpipe/lift.cpp108
-rw-r--r--engines/fullpipe/messagehandlers.cpp743
-rw-r--r--engines/fullpipe/messages.cpp791
-rw-r--r--engines/fullpipe/messages.h181
-rw-r--r--engines/fullpipe/modal.cpp242
-rw-r--r--engines/fullpipe/modal.h80
-rw-r--r--engines/fullpipe/module.mk39
-rw-r--r--engines/fullpipe/motion.cpp1611
-rw-r--r--engines/fullpipe/motion.h372
-rw-r--r--engines/fullpipe/ngiarchive.cpp156
-rw-r--r--engines/fullpipe/ngiarchive.h69
-rw-r--r--engines/fullpipe/objectnames.h250
-rw-r--r--engines/fullpipe/objects.h97
-rw-r--r--engines/fullpipe/scene.cpp691
-rw-r--r--engines/fullpipe/scene.h107
-rw-r--r--engines/fullpipe/scenes.cpp712
-rw-r--r--engines/fullpipe/scenes.h132
-rw-r--r--engines/fullpipe/scenes/scene01.cpp117
-rw-r--r--engines/fullpipe/scenes/scene02.cpp137
-rw-r--r--engines/fullpipe/scenes/scene03.cpp294
-rw-r--r--engines/fullpipe/scenes/scene04.cpp731
-rw-r--r--engines/fullpipe/scenes/sceneDbg.cpp107
-rw-r--r--engines/fullpipe/scenes/sceneIntro.cpp109
-rw-r--r--engines/fullpipe/sound.cpp140
-rw-r--r--engines/fullpipe/sound.h62
-rw-r--r--engines/fullpipe/stateloader.cpp321
-rw-r--r--engines/fullpipe/statics.cpp1910
-rw-r--r--engines/fullpipe/statics.h257
-rw-r--r--engines/fullpipe/utils.cpp501
-rw-r--r--engines/fullpipe/utils.h155
-rw-r--r--engines/gob/POTFILES3
-rw-r--r--engines/gob/configure.engine3
-rw-r--r--engines/gob/iniconfig.cpp4
-rw-r--r--engines/gob/iniconfig.h4
-rw-r--r--engines/gob/surface.cpp18
-rw-r--r--engines/gob/videoplayer.cpp6
-rw-r--r--engines/groovie/POTFILES2
-rw-r--r--engines/groovie/configure.engine4
-rw-r--r--engines/groovie/font.cpp4
-rw-r--r--engines/groovie/font.h6
-rw-r--r--engines/groovie/graphics.cpp6
-rw-r--r--engines/groovie/roq.cpp28
-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.cpp86
-rw-r--r--engines/hopkins/computer.h2
-rw-r--r--engines/hopkins/configure.engine3
-rw-r--r--engines/hopkins/detection.cpp5
-rw-r--r--engines/hopkins/detection_tables.h134
-rw-r--r--engines/hopkins/dialogs.cpp15
-rw-r--r--engines/hopkins/events.cpp2
-rw-r--r--engines/hopkins/globals.cpp4
-rw-r--r--engines/hopkins/graphics.cpp14
-rw-r--r--engines/hopkins/graphics.h2
-rw-r--r--engines/hopkins/hopkins.cpp136
-rw-r--r--engines/hopkins/hopkins.h4
-rw-r--r--engines/hopkins/lines.cpp1
-rw-r--r--engines/hopkins/menu.cpp38
-rw-r--r--engines/hopkins/saveload.cpp61
-rw-r--r--engines/hopkins/saveload.h6
-rw-r--r--engines/hopkins/script.cpp31
-rw-r--r--engines/hopkins/sound.cpp57
-rw-r--r--engines/hopkins/talk.cpp13
-rw-r--r--engines/hugo/configure.engine3
-rw-r--r--engines/hugo/dialogs.cpp12
-rw-r--r--engines/hugo/display.cpp8
-rw-r--r--engines/hugo/file.cpp6
-rw-r--r--engines/hugo/hugo.cpp48
-rw-r--r--engines/hugo/hugo.h5
-rw-r--r--engines/hugo/intro.cpp22
-rw-r--r--engines/hugo/inventory.cpp4
-rw-r--r--engines/hugo/mouse.cpp6
-rw-r--r--engines/hugo/object.cpp42
-rw-r--r--engines/hugo/parser.cpp26
-rw-r--r--engines/hugo/route.cpp13
-rw-r--r--engines/hugo/route.h4
-rw-r--r--engines/hugo/schedule.cpp62
-rw-r--r--engines/hugo/sound.cpp5
-rw-r--r--engines/hugo/text.cpp31
-rw-r--r--engines/kyra/POTFILES3
-rw-r--r--engines/kyra/animator_lok.cpp2
-rw-r--r--engines/kyra/chargen.cpp4
-rw-r--r--engines/kyra/configure.engine5
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/kyra_rpg.cpp2
-rw-r--r--engines/kyra/resource.cpp8
-rw-r--r--engines/kyra/scene_mr.cpp1
-rw-r--r--engines/kyra/screen.cpp11
-rw-r--r--engines/kyra/screen_v2.cpp2
-rw-r--r--engines/kyra/sequences_lok.cpp3
-rw-r--r--engines/kyra/sound_towns.cpp1
-rw-r--r--engines/kyra/text_rpg.cpp2
-rw-r--r--engines/lastexpress/configure.engine3
-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/entities/entity.h136
-rw-r--r--engines/lastexpress/entities/servers0.cpp4
-rw-r--r--engines/lastexpress/entities/verges.cpp2
-rw-r--r--engines/lastexpress/game/entities.h8
-rw-r--r--engines/lastexpress/game/inventory.cpp2
-rw-r--r--engines/lastexpress/game/logic.cpp4
-rw-r--r--engines/lastexpress/game/logic.h2
-rw-r--r--engines/lastexpress/game/object.cpp7
-rw-r--r--engines/lastexpress/game/savegame.h2
-rw-r--r--engines/lastexpress/game/scenes.cpp4
-rw-r--r--engines/lastexpress/game/state.h13
-rw-r--r--engines/lastexpress/graphics.cpp12
-rw-r--r--engines/lastexpress/lastexpress.cpp4
-rw-r--r--engines/lure/configure.engine3
-rw-r--r--engines/lure/debugger.cpp4
-rw-r--r--engines/lure/hotspots.cpp198
-rw-r--r--engines/lure/menu.cpp3
-rw-r--r--engines/made/configure.engine3
-rw-r--r--engines/made/detection.cpp114
-rw-r--r--engines/made/graphics.cpp4
-rw-r--r--engines/made/made.cpp6
-rw-r--r--engines/made/pmvplayer.cpp2
-rw-r--r--engines/made/screen.cpp8
-rw-r--r--engines/made/screenfx.cpp6
-rw-r--r--engines/made/scriptfuncs.cpp2
-rw-r--r--engines/made/sound.cpp2
-rw-r--r--engines/mohawk/POTFILES3
-rw-r--r--engines/mohawk/bitmap.cpp10
-rw-r--r--engines/mohawk/configure.engine6
-rw-r--r--engines/mohawk/cstime.cpp9
-rw-r--r--engines/mohawk/cstime_game.cpp2
-rw-r--r--engines/mohawk/cstime_ui.cpp2
-rw-r--r--engines/mohawk/cstime_ui.h3
-rw-r--r--engines/mohawk/cursors.cpp4
-rw-r--r--engines/mohawk/livingbooks.cpp16
-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/configure.engine3
-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.cpp271
-rw-r--r--engines/mortevielle/mouse.h53
-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.cpp3405
-rw-r--r--engines/neverhood/POTFILES2
-rw-r--r--engines/neverhood/background.cpp6
-rw-r--r--engines/neverhood/blbarchive.cpp19
-rw-r--r--engines/neverhood/configure.engine3
-rw-r--r--engines/neverhood/console.cpp269
-rw-r--r--engines/neverhood/console.h51
-rw-r--r--engines/neverhood/detection.cpp34
-rw-r--r--engines/neverhood/diskplayerscene.cpp56
-rw-r--r--engines/neverhood/diskplayerscene.h7
-rw-r--r--engines/neverhood/entity.cpp20
-rw-r--r--engines/neverhood/entity.h18
-rw-r--r--engines/neverhood/gamemodule.cpp51
-rw-r--r--engines/neverhood/gamemodule.h7
-rw-r--r--engines/neverhood/gamevars.cpp7
-rw-r--r--engines/neverhood/gamevars.h6
-rw-r--r--engines/neverhood/graphics.cpp32
-rw-r--r--engines/neverhood/graphics.h16
-rw-r--r--engines/neverhood/klaymen.cpp3525
-rw-r--r--engines/neverhood/klaymen.h429
-rw-r--r--engines/neverhood/menumodule.cpp229
-rw-r--r--engines/neverhood/menumodule.h11
-rw-r--r--engines/neverhood/microtiles.cpp4
-rw-r--r--engines/neverhood/module.cpp4
-rw-r--r--engines/neverhood/module.h4
-rw-r--r--engines/neverhood/module.mk19
-rw-r--r--engines/neverhood/modules/module1000.cpp1034
-rw-r--r--engines/neverhood/modules/module1000.h190
-rw-r--r--engines/neverhood/modules/module1000_sprites.cpp1632
-rw-r--r--engines/neverhood/modules/module1000_sprites.h262
-rw-r--r--engines/neverhood/modules/module1100.cpp248
-rw-r--r--engines/neverhood/modules/module1100.h51
-rw-r--r--engines/neverhood/modules/module1100_sprites.cpp265
-rw-r--r--engines/neverhood/modules/module1100_sprites.h88
-rw-r--r--engines/neverhood/modules/module1200.cpp688
-rw-r--r--engines/neverhood/modules/module1200.h136
-rw-r--r--engines/neverhood/modules/module1200_sprites.cpp810
-rw-r--r--engines/neverhood/modules/module1200_sprites.h187
-rw-r--r--engines/neverhood/modules/module1300.cpp678
-rw-r--r--engines/neverhood/modules/module1300.h129
-rw-r--r--engines/neverhood/modules/module1300_sprites.cpp935
-rw-r--r--engines/neverhood/modules/module1300_sprites.h200
-rw-r--r--engines/neverhood/modules/module1400.cpp910
-rw-r--r--engines/neverhood/modules/module1400.h151
-rw-r--r--engines/neverhood/modules/module1400_sprites.cpp1129
-rw-r--r--engines/neverhood/modules/module1400_sprites.h198
-rw-r--r--engines/neverhood/modules/module1500.cpp8
-rw-r--r--engines/neverhood/modules/module1600.cpp857
-rw-r--r--engines/neverhood/modules/module1600.h91
-rw-r--r--engines/neverhood/modules/module1600_sprites.cpp934
-rw-r--r--engines/neverhood/modules/module1600_sprites.h126
-rw-r--r--engines/neverhood/modules/module1700.cpp54
-rw-r--r--engines/neverhood/modules/module1700.h17
-rw-r--r--engines/neverhood/modules/module1700_sprites.cpp156
-rw-r--r--engines/neverhood/modules/module1700_sprites.h55
-rw-r--r--engines/neverhood/modules/module1800.cpp11
-rw-r--r--engines/neverhood/modules/module1900.cpp419
-rw-r--r--engines/neverhood/modules/module1900.h73
-rw-r--r--engines/neverhood/modules/module1900_sprites.cpp456
-rw-r--r--engines/neverhood/modules/module1900_sprites.h107
-rw-r--r--engines/neverhood/modules/module2000.cpp13
-rw-r--r--engines/neverhood/modules/module2000.h3
-rw-r--r--engines/neverhood/modules/module2000_sprites.cpp92
-rw-r--r--engines/neverhood/modules/module2000_sprites.h41
-rw-r--r--engines/neverhood/modules/module2100.cpp141
-rw-r--r--engines/neverhood/modules/module2100.h32
-rw-r--r--engines/neverhood/modules/module2100_sprites.cpp260
-rw-r--r--engines/neverhood/modules/module2100_sprites.h75
-rw-r--r--engines/neverhood/modules/module2200.cpp958
-rw-r--r--engines/neverhood/modules/module2200.h178
-rw-r--r--engines/neverhood/modules/module2200_sprites.cpp1429
-rw-r--r--engines/neverhood/modules/module2200_sprites.h275
-rw-r--r--engines/neverhood/modules/module2300.cpp14
-rw-r--r--engines/neverhood/modules/module2400.cpp371
-rw-r--r--engines/neverhood/modules/module2400.h70
-rw-r--r--engines/neverhood/modules/module2400_sprites.cpp741
-rw-r--r--engines/neverhood/modules/module2400_sprites.h139
-rw-r--r--engines/neverhood/modules/module2500.cpp84
-rw-r--r--engines/neverhood/modules/module2500.h18
-rw-r--r--engines/neverhood/modules/module2500_sprites.cpp127
-rw-r--r--engines/neverhood/modules/module2500_sprites.h51
-rw-r--r--engines/neverhood/modules/module2600.cpp95
-rw-r--r--engines/neverhood/modules/module2600.h18
-rw-r--r--engines/neverhood/modules/module2600_sprites.cpp115
-rw-r--r--engines/neverhood/modules/module2600_sprites.h54
-rw-r--r--engines/neverhood/modules/module2700.cpp184
-rw-r--r--engines/neverhood/modules/module2700.h37
-rw-r--r--engines/neverhood/modules/module2700_sprites.cpp178
-rw-r--r--engines/neverhood/modules/module2700_sprites.h74
-rw-r--r--engines/neverhood/modules/module2800.cpp1162
-rw-r--r--engines/neverhood/modules/module2800.h238
-rw-r--r--engines/neverhood/modules/module2800_sprites.cpp1626
-rw-r--r--engines/neverhood/modules/module2800_sprites.h337
-rw-r--r--engines/neverhood/modules/module2900.cpp219
-rw-r--r--engines/neverhood/modules/module2900.h36
-rw-r--r--engines/neverhood/modules/module2900_sprites.cpp232
-rw-r--r--engines/neverhood/modules/module2900_sprites.h72
-rw-r--r--engines/neverhood/modules/module3000.cpp764
-rw-r--r--engines/neverhood/modules/module3000.h162
-rw-r--r--engines/neverhood/modules/module3000_sprites.cpp763
-rw-r--r--engines/neverhood/modules/module3000_sprites.h185
-rw-r--r--engines/neverhood/mouse.cpp52
-rw-r--r--engines/neverhood/mouse.h2
-rw-r--r--engines/neverhood/navigationscene.cpp47
-rw-r--r--engines/neverhood/navigationscene.h2
-rw-r--r--engines/neverhood/neverhood.cpp53
-rw-r--r--engines/neverhood/neverhood.h22
-rw-r--r--engines/neverhood/palette.cpp19
-rw-r--r--engines/neverhood/resource.cpp74
-rw-r--r--engines/neverhood/resource.h4
-rw-r--r--engines/neverhood/resourceman.cpp56
-rw-r--r--engines/neverhood/resourceman.h2
-rw-r--r--engines/neverhood/saveload.cpp29
-rw-r--r--engines/neverhood/scene.cpp97
-rw-r--r--engines/neverhood/scene.h62
-rw-r--r--engines/neverhood/screen.cpp61
-rw-r--r--engines/neverhood/screen.h1
-rw-r--r--engines/neverhood/smackerplayer.cpp56
-rw-r--r--engines/neverhood/smackerplayer.h3
-rw-r--r--engines/neverhood/smackerscene.cpp8
-rw-r--r--engines/neverhood/smackerscene.h1
-rw-r--r--engines/neverhood/sound.cpp89
-rw-r--r--engines/neverhood/sound.h36
-rw-r--r--engines/neverhood/sprite.cpp34
-rw-r--r--engines/neverhood/sprite.h27
-rw-r--r--engines/neverhood/staticdata.cpp26
-rw-r--r--engines/neverhood/todo.txt45
-rw-r--r--engines/parallaction/POTFILES1
-rw-r--r--engines/parallaction/configure.engine3
-rw-r--r--engines/parallaction/debug.cpp4
-rw-r--r--engines/parallaction/disk_br.cpp8
-rw-r--r--engines/parallaction/disk_ns.cpp6
-rw-r--r--engines/parallaction/exec.h2
-rw-r--r--engines/parallaction/exec_ns.cpp4
-rw-r--r--engines/parallaction/font.cpp3
-rw-r--r--engines/parallaction/graphics.cpp24
-rw-r--r--engines/parallaction/graphics.h4
-rw-r--r--engines/parallaction/gui.h2
-rw-r--r--engines/parallaction/gui_br.cpp5
-rw-r--r--engines/parallaction/gui_ns.cpp3
-rw-r--r--engines/parallaction/input.cpp2
-rw-r--r--engines/parallaction/input.h2
-rw-r--r--engines/parallaction/inventory.h2
-rw-r--r--engines/parallaction/objects.h6
-rw-r--r--engines/parallaction/parallaction.cpp30
-rw-r--r--engines/parallaction/parallaction.h4
-rw-r--r--engines/parallaction/parallaction_br.cpp12
-rw-r--r--engines/parallaction/parallaction_ns.cpp12
-rw-r--r--engines/parallaction/parser.h11
-rw-r--r--engines/parallaction/sound.h6
-rw-r--r--engines/parallaction/sound_br.cpp1
-rw-r--r--engines/parallaction/sound_ns.cpp1
-rw-r--r--engines/pegasus/POTFILES1
-rw-r--r--engines/pegasus/configure.engine3
-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/delta/globegame.cpp10
-rw-r--r--engines/pegasus/neighborhood/norad/delta/noraddelta.cpp5
-rw-r--r--engines/pegasus/neighborhood/norad/norad.cpp4
-rw-r--r--engines/pegasus/neighborhood/tsa/fulltsa.cpp1
-rw-r--r--engines/pegasus/neighborhood/tsa/tinytsa.cpp1
-rw-r--r--engines/pegasus/neighborhood/wsc/wsc.cpp13
-rw-r--r--engines/pegasus/pegasus.cpp10
-rw-r--r--engines/pegasus/timers.cpp5
-rw-r--r--engines/pegasus/transition.cpp2
-rw-r--r--engines/plugins_table.h121
-rw-r--r--engines/queen/POTFILES1
-rw-r--r--engines/queen/configure.engine3
-rw-r--r--engines/saga/animation.cpp4
-rw-r--r--engines/saga/configure.engine5
-rw-r--r--engines/saga/events.cpp3
-rw-r--r--engines/saga/gfx.h2
-rw-r--r--engines/saga/introproc_ihnm.cpp8
-rw-r--r--engines/saga/introproc_ite.cpp4
-rw-r--r--engines/saga/introproc_saga2.cpp2
-rw-r--r--engines/saga/music.cpp2
-rw-r--r--engines/saga/saga.h2
-rw-r--r--engines/saga/scene.cpp6
-rw-r--r--engines/saga/shorten.cpp2
-rw-r--r--engines/saga/sndres.cpp6
-rw-r--r--engines/saga/sprite.cpp28
-rw-r--r--engines/sci/POTFILES2
-rw-r--r--engines/sci/configure.engine4
-rw-r--r--engines/sci/console.cpp13
-rw-r--r--engines/sci/detection.cpp5
-rw-r--r--engines/sci/detection_tables.h834
-rw-r--r--engines/sci/engine/features.cpp6
-rw-r--r--engines/sci/engine/kernel.cpp12
-rw-r--r--engines/sci/engine/kernel.h4
-rw-r--r--engines/sci/engine/kernel_tables.h2
-rw-r--r--engines/sci/engine/kfile.cpp2
-rw-r--r--engines/sci/engine/kpathing.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp2
-rw-r--r--engines/sci/engine/kvideo.cpp4
-rw-r--r--engines/sci/engine/savegame.cpp7
-rw-r--r--engines/sci/engine/savegame.h3
-rw-r--r--engines/sci/engine/script.cpp2
-rw-r--r--engines/sci/engine/script.h10
-rw-r--r--engines/sci/engine/script_patches.cpp2686
-rw-r--r--engines/sci/engine/seg_manager.cpp10
-rw-r--r--engines/sci/engine/seg_manager.h2
-rw-r--r--engines/sci/engine/vm.cpp17
-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.cpp33
-rw-r--r--engines/sci/engine/workarounds.h1
-rw-r--r--engines/sci/graphics/frameout.cpp12
-rw-r--r--engines/sci/graphics/maciconbar.cpp6
-rw-r--r--engines/sci/graphics/picture.cpp17
-rw-r--r--engines/sci/graphics/ports.cpp4
-rw-r--r--engines/sci/graphics/screen.cpp18
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/sci.cpp73
-rw-r--r--engines/sci/sci.h50
-rw-r--r--engines/sci/sound/midiparser_sci.cpp286
-rw-r--r--engines/sci/sound/midiparser_sci.h5
-rw-r--r--engines/sci/sound/music.cpp3
-rw-r--r--engines/sci/sound/music.h2
-rw-r--r--engines/sci/sound/soundcmd.cpp43
-rw-r--r--engines/sci/video/robot_decoder.cpp2
-rw-r--r--engines/sci/video/seq_decoder.cpp4
-rw-r--r--engines/scumm/POTFILES3
-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/configure.engine5
-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.cpp26
-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/intern_he.h1
-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.cpp54
-rw-r--r--engines/scumm/imuse/imuse_internal.h1
-rw-r--r--engines/scumm/imuse_digi/dimuse.cpp5
-rw-r--r--engines/scumm/imuse_digi/dimuse_sndmgr.cpp13
-rw-r--r--engines/scumm/input.cpp2
-rw-r--r--engines/scumm/insane/insane_enemy.cpp4
-rw-r--r--engines/scumm/module.mk33
-rw-r--r--engines/scumm/nut_renderer.cpp10
-rw-r--r--engines/scumm/object.cpp2
-rw-r--r--engines/scumm/players/player_ad.cpp959
-rw-r--r--engines/scumm/players/player_ad.h190
-rw-r--r--engines/scumm/players/player_apple2.cpp (renamed from engines/scumm/player_apple2.cpp)2
-rw-r--r--engines/scumm/players/player_apple2.h (renamed from engines/scumm/player_apple2.h)4
-rw-r--r--engines/scumm/players/player_mac.cpp (renamed from engines/scumm/player_mac.cpp)12
-rw-r--r--engines/scumm/players/player_mac.h (renamed from engines/scumm/player_mac.h)4
-rw-r--r--engines/scumm/players/player_mod.cpp (renamed from engines/scumm/player_mod.cpp)2
-rw-r--r--engines/scumm/players/player_mod.h (renamed from engines/scumm/player_mod.h)4
-rw-r--r--engines/scumm/players/player_nes.cpp (renamed from engines/scumm/player_nes.cpp)2
-rw-r--r--engines/scumm/players/player_nes.h (renamed from engines/scumm/player_nes.h)4
-rw-r--r--engines/scumm/players/player_pce.cpp (renamed from engines/scumm/player_pce.cpp)2
-rw-r--r--engines/scumm/players/player_pce.h (renamed from engines/scumm/player_pce.h)4
-rw-r--r--engines/scumm/players/player_sid.cpp (renamed from engines/scumm/player_sid.cpp)2
-rw-r--r--engines/scumm/players/player_sid.h (renamed from engines/scumm/player_sid.h)4
-rw-r--r--engines/scumm/players/player_towns.cpp (renamed from engines/scumm/player_towns.cpp)2
-rw-r--r--engines/scumm/players/player_towns.h (renamed from engines/scumm/player_towns.h)4
-rw-r--r--engines/scumm/players/player_v1.cpp (renamed from engines/scumm/player_v1.cpp)2
-rw-r--r--engines/scumm/players/player_v1.h (renamed from engines/scumm/player_v1.h)6
-rw-r--r--engines/scumm/players/player_v2.cpp (renamed from engines/scumm/player_v2.cpp)2
-rw-r--r--engines/scumm/players/player_v2.h (renamed from engines/scumm/player_v2.h)6
-rw-r--r--engines/scumm/players/player_v2a.cpp (renamed from engines/scumm/player_v2a.cpp)2
-rw-r--r--engines/scumm/players/player_v2a.h (renamed from engines/scumm/player_v2a.h)6
-rw-r--r--engines/scumm/players/player_v2base.cpp (renamed from engines/scumm/player_v2base.cpp)2
-rw-r--r--engines/scumm/players/player_v2base.h (renamed from engines/scumm/player_v2base.h)4
-rw-r--r--engines/scumm/players/player_v2cms.cpp (renamed from engines/scumm/player_v2cms.cpp)2
-rw-r--r--engines/scumm/players/player_v2cms.h (renamed from engines/scumm/player_v2cms.h)6
-rw-r--r--engines/scumm/players/player_v3a.cpp (renamed from engines/scumm/player_v3a.cpp)2
-rw-r--r--engines/scumm/players/player_v3a.h (renamed from engines/scumm/player_v3a.h)6
-rw-r--r--engines/scumm/players/player_v3m.cpp (renamed from engines/scumm/player_v3m.cpp)4
-rw-r--r--engines/scumm/players/player_v3m.h (renamed from engines/scumm/player_v3m.h)6
-rw-r--r--engines/scumm/players/player_v4a.cpp (renamed from engines/scumm/player_v4a.cpp)2
-rw-r--r--engines/scumm/players/player_v4a.h (renamed from engines/scumm/player_v4a.h)4
-rw-r--r--engines/scumm/players/player_v5m.cpp (renamed from engines/scumm/player_v5m.cpp)2
-rw-r--r--engines/scumm/players/player_v5m.h (renamed from engines/scumm/player_v5m.h)6
-rw-r--r--engines/scumm/saveload.cpp101
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script_v5.cpp2
-rw-r--r--engines/scumm/script_v6.cpp2
-rw-r--r--engines/scumm/scumm-md5.h11
-rw-r--r--engines/scumm/scumm.cpp36
-rw-r--r--engines/scumm/scumm.h10
-rw-r--r--engines/scumm/sound.cpp26
-rw-r--r--engines/scumm/vars.cpp6
-rw-r--r--engines/sky/POTFILES2
-rw-r--r--engines/sky/configure.engine3
-rw-r--r--engines/sky/music/musicbase.cpp5
-rw-r--r--engines/sky/sky.cpp7
-rw-r--r--engines/sword1/POTFILES4
-rw-r--r--engines/sword1/animation.cpp62
-rw-r--r--engines/sword1/animation.h3
-rw-r--r--engines/sword1/configure.engine3
-rw-r--r--engines/sword1/music.cpp6
-rw-r--r--engines/sword1/music.h2
-rw-r--r--engines/sword1/screen.cpp24
-rw-r--r--engines/sword1/sound.cpp3
-rw-r--r--engines/sword1/sword1.cpp11
-rw-r--r--engines/sword2/POTFILES2
-rw-r--r--engines/sword2/animation.cpp59
-rw-r--r--engines/sword2/animation.h3
-rw-r--r--engines/sword2/configure.engine3
-rw-r--r--engines/sword25/configure.engine3
-rw-r--r--engines/sword25/fmv/movieplayer.cpp4
-rw-r--r--engines/sword25/gfx/animation.cpp20
-rw-r--r--engines/sword25/gfx/animation.h12
-rw-r--r--engines/sword25/gfx/animationdescription.cpp4
-rw-r--r--engines/sword25/gfx/animationdescription.h8
-rw-r--r--engines/sword25/gfx/animationresource.cpp2
-rw-r--r--engines/sword25/gfx/animationtemplate.cpp4
-rw-r--r--engines/sword25/gfx/animationtemplateregistry.cpp6
-rw-r--r--engines/sword25/gfx/bitmap.h6
-rw-r--r--engines/sword25/gfx/dynamicbitmap.cpp4
-rw-r--r--engines/sword25/gfx/image/art.cpp3
-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.cpp143
-rw-r--r--engines/sword25/gfx/image/renderedimage.h3
-rw-r--r--engines/sword25/gfx/microtiles.cpp3
-rw-r--r--engines/sword25/gfx/panel.cpp4
-rw-r--r--engines/sword25/gfx/panel.h2
-rw-r--r--engines/sword25/gfx/renderobject.cpp40
-rw-r--r--engines/sword25/gfx/renderobject.h52
-rw-r--r--engines/sword25/gfx/renderobjectmanager.cpp31
-rw-r--r--engines/sword25/gfx/screenshot.cpp4
-rw-r--r--engines/sword25/gfx/staticbitmap.cpp2
-rw-r--r--engines/sword25/gfx/text.cpp12
-rw-r--r--engines/sword25/gfx/text.h10
-rw-r--r--engines/sword25/input/inputengine.cpp8
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.cpp10
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.h4
-rw-r--r--engines/sword25/kernel/objectregistry.h6
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.cpp8
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.h4
-rw-r--r--engines/sword25/kernel/persistenceservice.cpp2
-rw-r--r--engines/sword25/math/polygon.cpp8
-rw-r--r--engines/sword25/math/polygon.h2
-rw-r--r--engines/sword25/math/region.cpp20
-rw-r--r--engines/sword25/math/regionregistry.cpp6
-rw-r--r--engines/sword25/math/walkregion.cpp22
-rw-r--r--engines/sword25/sfx/soundengine.cpp15
-rw-r--r--engines/sword25/sfx/soundengine.h8
-rw-r--r--engines/sword25/util/lua/lcode.cpp2
-rw-r--r--engines/sword25/util/lua/ldebug.cpp5
-rw-r--r--engines/sword25/util/lua/lfunc.cpp2
-rw-r--r--engines/sword25/util/lua/lgc.cpp2
-rw-r--r--engines/sword25/util/lua/llimits.h3
-rw-r--r--engines/sword25/util/lua/lmem.cpp2
-rw-r--r--engines/sword25/util/lua/lopcodes.cpp3
-rw-r--r--engines/sword25/util/lua/lparser.cpp2
-rw-r--r--engines/sword25/util/lua/lstate.cpp2
-rw-r--r--engines/sword25/util/lua/lstring.cpp2
-rw-r--r--engines/sword25/util/lua/lstrlib.cpp6
-rw-r--r--engines/sword25/util/lua/ltablib.cpp2
-rw-r--r--engines/sword25/util/lua/lua.h2
-rw-r--r--engines/sword25/util/pluto/pluto.cpp539
-rw-r--r--engines/teenagent/POTFILES1
-rw-r--r--engines/teenagent/callbacks.cpp6
-rw-r--r--engines/teenagent/configure.engine3
-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-params.cpp2
-rw-r--r--engines/testbed/config.cpp8
-rw-r--r--engines/testbed/config.h6
-rw-r--r--engines/testbed/configure.engine3
-rw-r--r--engines/testbed/events.cpp5
-rw-r--r--engines/testbed/graphics.cpp22
-rw-r--r--engines/testbed/midi.cpp2
-rw-r--r--engines/tinsel/POTFILES1
-rw-r--r--engines/tinsel/bmv.cpp2
-rw-r--r--engines/tinsel/configure.engine3
-rw-r--r--engines/tinsel/detection.cpp2
-rw-r--r--engines/tinsel/detection_tables.h43
-rw-r--r--engines/tinsel/graphics.cpp2
-rw-r--r--engines/tinsel/handle.cpp2
-rw-r--r--engines/tinsel/music.cpp35
-rw-r--r--engines/tinsel/rince.cpp3
-rw-r--r--engines/tinsel/scene.cpp20
-rw-r--r--engines/tinsel/sound.cpp10
-rw-r--r--engines/tinsel/tinsel.cpp6
-rw-r--r--engines/tinsel/tinsel.h8
-rw-r--r--engines/toltecs/POTFILES2
-rw-r--r--engines/toltecs/configure.engine3
-rw-r--r--engines/toltecs/detection.cpp14
-rw-r--r--engines/toltecs/menu.cpp4
-rw-r--r--engines/toltecs/render.cpp2
-rw-r--r--engines/toltecs/saveload.cpp2
-rw-r--r--engines/toltecs/screen.cpp6
-rw-r--r--engines/toltecs/script.cpp10
-rw-r--r--engines/toltecs/segmap.cpp2
-rw-r--r--engines/toltecs/toltecs.cpp8
-rw-r--r--engines/tony/configure.engine3
-rw-r--r--engines/tony/detection.cpp29
-rw-r--r--engines/tony/detection_tables.h34
-rw-r--r--engines/tony/game.cpp3
-rw-r--r--engines/tony/gfxcore.cpp3
-rw-r--r--engines/tony/gfxcore.h6
-rw-r--r--engines/tony/gfxengine.cpp9
-rw-r--r--engines/tony/mpal/mpal.cpp38
-rw-r--r--engines/tony/mpal/mpal.h2
-rw-r--r--engines/tony/sound.cpp6
-rw-r--r--engines/tony/window.cpp8
-rw-r--r--engines/toon/anim.cpp14
-rw-r--r--engines/toon/audio.cpp3
-rw-r--r--engines/toon/character.cpp10
-rw-r--r--engines/toon/character.h1
-rw-r--r--engines/toon/configure.engine3
-rw-r--r--engines/toon/font.cpp5
-rw-r--r--engines/toon/movie.cpp11
-rw-r--r--engines/toon/movie.h3
-rw-r--r--engines/toon/path.cpp2
-rw-r--r--engines/toon/picture.cpp11
-rw-r--r--engines/toon/resource.cpp1
-rw-r--r--engines/toon/resource.h1
-rw-r--r--engines/toon/script.cpp5
-rw-r--r--engines/toon/script_func.cpp6
-rw-r--r--engines/toon/state.cpp4
-rw-r--r--engines/toon/tools.cpp7
-rw-r--r--engines/toon/toon.cpp54
-rw-r--r--engines/touche/configure.engine3
-rw-r--r--engines/touche/touche.cpp79
-rw-r--r--engines/touche/touche.h2
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp42
-rw-r--r--engines/tsage/blue_force/blueforce_logic.h18
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp12
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp22
-rw-r--r--engines/tsage/blue_force/blueforce_scenes2.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.cpp91
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.h6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.cpp122
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.h12
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp41
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes6.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp32
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.h3
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.cpp69
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.h1
-rw-r--r--engines/tsage/blue_force/blueforce_speakers.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_speakers.h2
-rw-r--r--engines/tsage/configure.engine3
-rw-r--r--engines/tsage/converse.cpp202
-rw-r--r--engines/tsage/converse.h14
-rw-r--r--engines/tsage/core.cpp280
-rw-r--r--engines/tsage/core.h26
-rw-r--r--engines/tsage/debugger.cpp98
-rw-r--r--engines/tsage/detection.cpp1
-rw-r--r--engines/tsage/detection_tables.h2
-rw-r--r--engines/tsage/dialogs.cpp78
-rw-r--r--engines/tsage/events.cpp17
-rw-r--r--engines/tsage/events.h1
-rw-r--r--engines/tsage/globals.cpp425
-rw-r--r--engines/tsage/globals.h116
-rw-r--r--engines/tsage/graphics.cpp192
-rw-r--r--engines/tsage/graphics.h9
-rw-r--r--engines/tsage/ringworld/ringworld_logic.cpp5
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.cpp691
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.h82
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.cpp2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.cpp3
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.h1
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.cpp11
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.h6
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.cpp8
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.h2
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp39
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.h3
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp1438
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h285
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp3044
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h293
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp10364
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h836
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp3169
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.h481
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp4983
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.h587
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp977
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h179
-rw-r--r--engines/tsage/saveload.cpp11
-rw-r--r--engines/tsage/saveload.h17
-rw-r--r--engines/tsage/scenes.cpp21
-rw-r--r--engines/tsage/sound.cpp254
-rw-r--r--engines/tsage/sound.h48
-rw-r--r--engines/tsage/staticres.cpp210
-rw-r--r--engines/tsage/staticres.h21
-rw-r--r--engines/tsage/tsage.cpp5
-rw-r--r--engines/tsage/user_interface.cpp44
-rw-r--r--engines/tsage/user_interface.h4
-rw-r--r--engines/tucker/configure.engine3
-rw-r--r--engines/tucker/sequences.cpp4
-rw-r--r--engines/tucker/tucker.cpp13
-rw-r--r--engines/voyeur/animation.cpp10
-rw-r--r--engines/voyeur/configure.engine3
-rw-r--r--engines/voyeur/events.cpp2
-rw-r--r--engines/voyeur/graphics.cpp8
-rw-r--r--engines/voyeur/voyeur.cpp8
-rw-r--r--engines/wintermute/ad/ad_actor.cpp86
-rw-r--r--engines/wintermute/ad/ad_actor.h6
-rw-r--r--engines/wintermute/ad/ad_entity.cpp88
-rw-r--r--engines/wintermute/ad/ad_entity.h6
-rw-r--r--engines/wintermute/ad/ad_game.cpp66
-rw-r--r--engines/wintermute/ad/ad_game.h6
-rw-r--r--engines/wintermute/ad/ad_inventory.cpp4
-rw-r--r--engines/wintermute/ad/ad_inventory.h2
-rw-r--r--engines/wintermute/ad/ad_inventory_box.cpp58
-rw-r--r--engines/wintermute/ad/ad_inventory_box.h4
-rw-r--r--engines/wintermute/ad/ad_item.cpp70
-rw-r--r--engines/wintermute/ad/ad_item.h6
-rw-r--r--engines/wintermute/ad/ad_layer.cpp42
-rw-r--r--engines/wintermute/ad/ad_layer.h4
-rw-r--r--engines/wintermute/ad/ad_node_state.cpp14
-rw-r--r--engines/wintermute/ad/ad_node_state.h2
-rw-r--r--engines/wintermute/ad/ad_object.cpp38
-rw-r--r--engines/wintermute/ad/ad_object.h4
-rw-r--r--engines/wintermute/ad/ad_path.cpp6
-rw-r--r--engines/wintermute/ad/ad_path.h2
-rw-r--r--engines/wintermute/ad/ad_path_point.cpp6
-rw-r--r--engines/wintermute/ad/ad_path_point.h2
-rw-r--r--engines/wintermute/ad/ad_region.cpp46
-rw-r--r--engines/wintermute/ad/ad_region.h4
-rw-r--r--engines/wintermute/ad/ad_response.cpp12
-rw-r--r--engines/wintermute/ad/ad_response.h2
-rw-r--r--engines/wintermute/ad/ad_response_box.cpp124
-rw-r--r--engines/wintermute/ad/ad_response_box.h4
-rw-r--r--engines/wintermute/ad/ad_response_context.cpp6
-rw-r--r--engines/wintermute/ad/ad_response_context.h2
-rw-r--r--engines/wintermute/ad/ad_rot_level.cpp20
-rw-r--r--engines/wintermute/ad/ad_rot_level.h4
-rw-r--r--engines/wintermute/ad/ad_scale_level.cpp20
-rw-r--r--engines/wintermute/ad/ad_scale_level.h4
-rw-r--r--engines/wintermute/ad/ad_scene.cpp151
-rw-r--r--engines/wintermute/ad/ad_scene.h4
-rw-r--r--engines/wintermute/ad/ad_scene_node.cpp4
-rw-r--r--engines/wintermute/ad/ad_scene_state.cpp4
-rw-r--r--engines/wintermute/ad/ad_scene_state.h2
-rw-r--r--engines/wintermute/ad/ad_sentence.cpp28
-rw-r--r--engines/wintermute/ad/ad_sentence.h2
-rw-r--r--engines/wintermute/ad/ad_sprite_set.cpp32
-rw-r--r--engines/wintermute/ad/ad_sprite_set.h4
-rw-r--r--engines/wintermute/ad/ad_talk_def.cpp22
-rw-r--r--engines/wintermute/ad/ad_talk_def.h4
-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.cpp34
-rw-r--r--engines/wintermute/ad/ad_talk_node.h4
-rw-r--r--engines/wintermute/ad/ad_types.h2
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.cpp32
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.h4
-rw-r--r--engines/wintermute/base/base.cpp20
-rw-r--r--engines/wintermute/base/base.h6
-rw-r--r--engines/wintermute/base/base_active_rect.cpp6
-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.cpp22
-rw-r--r--engines/wintermute/base/base_fader.h2
-rw-r--r--engines/wintermute/base/base_file_manager.cpp85
-rw-r--r--engines/wintermute/base/base_file_manager.h2
-rw-r--r--engines/wintermute/base/base_frame.cpp28
-rw-r--r--engines/wintermute/base/base_frame.h4
-rw-r--r--engines/wintermute/base/base_game.cpp182
-rw-r--r--engines/wintermute/base/base_game.h18
-rw-r--r--engines/wintermute/base/base_game_music.cpp124
-rw-r--r--engines/wintermute/base/base_game_music.h8
-rw-r--r--engines/wintermute/base/base_game_settings.cpp92
-rw-r--r--engines/wintermute/base/base_game_settings.h6
-rw-r--r--engines/wintermute/base/base_keyboard_state.cpp28
-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.cpp80
-rw-r--r--engines/wintermute/base/base_object.h4
-rw-r--r--engines/wintermute/base/base_parser.cpp6
-rw-r--r--engines/wintermute/base/base_parser.h2
-rw-r--r--engines/wintermute/base/base_persistence_manager.cpp128
-rw-r--r--engines/wintermute/base/base_persistence_manager.h29
-rw-r--r--engines/wintermute/base/base_point.cpp6
-rw-r--r--engines/wintermute/base/base_point.h2
-rw-r--r--engines/wintermute/base/base_quick_msg.cpp12
-rw-r--r--engines/wintermute/base/base_quick_msg.h10
-rw-r--r--engines/wintermute/base/base_region.cpp44
-rw-r--r--engines/wintermute/base/base_region.h4
-rw-r--r--engines/wintermute/base/base_script_holder.cpp26
-rw-r--r--engines/wintermute/base/base_script_holder.h4
-rw-r--r--engines/wintermute/base/base_scriptable.cpp4
-rw-r--r--engines/wintermute/base/base_scriptable.h2
-rw-r--r--engines/wintermute/base/base_sprite.cpp78
-rw-r--r--engines/wintermute/base/base_sprite.h13
-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.cpp106
-rw-r--r--engines/wintermute/base/base_sub_frame.h4
-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.cpp13
-rw-r--r--engines/wintermute/base/base_viewport.h2
-rw-r--r--engines/wintermute/base/file/base_disk_file.cpp15
-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.cpp8
-rw-r--r--engines/wintermute/base/font/base_font.h2
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.cpp33
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.h4
-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.cpp103
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h17
-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.cpp32
-rw-r--r--engines/wintermute/base/gfx/base_renderer.h4
-rw-r--r--engines/wintermute/base/gfx/base_surface.cpp6
-rw-r--r--engines/wintermute/base/gfx/base_surface.h7
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp314
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h60
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp193
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h21
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp136
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.h41
-rw-r--r--engines/wintermute/base/particles/part_emitter.cpp95
-rw-r--r--engines/wintermute/base/particles/part_emitter.h2
-rw-r--r--engines/wintermute/base/particles/part_force.cpp12
-rw-r--r--engines/wintermute/base/particles/part_force.h2
-rw-r--r--engines/wintermute/base/particles/part_particle.cpp48
-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.cpp37
-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.cpp4
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.cpp16
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.cpp12
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.cpp3
-rw-r--r--engines/wintermute/base/scriptables/script_ext_math.h2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp4
-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.cpp22
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.h2
-rw-r--r--engines/wintermute/base/scriptables/script_stack.cpp4
-rw-r--r--engines/wintermute/base/scriptables/script_stack.h2
-rw-r--r--engines/wintermute/base/scriptables/script_value.cpp35
-rw-r--r--engines/wintermute/base/scriptables/script_value.h2
-rw-r--r--engines/wintermute/base/sound/base_sound.cpp22
-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.cpp10
-rw-r--r--engines/wintermute/base/timer.h6
-rw-r--r--engines/wintermute/coll_templ.h22
-rw-r--r--engines/wintermute/configure.engine3
-rw-r--r--engines/wintermute/dcgf.h2
-rw-r--r--engines/wintermute/dctypes.h5
-rw-r--r--engines/wintermute/debugger.cpp6
-rw-r--r--engines/wintermute/debugger.h6
-rw-r--r--engines/wintermute/detection.cpp3
-rw-r--r--engines/wintermute/detection_tables.h266
-rw-r--r--engines/wintermute/graphics/transform_struct.cpp119
-rw-r--r--engines/wintermute/graphics/transform_struct.h89
-rw-r--r--engines/wintermute/graphics/transform_tools.cpp87
-rw-r--r--engines/wintermute/graphics/transform_tools.h53
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp974
-rw-r--r--engines/wintermute/graphics/transparent_surface.h82
-rw-r--r--engines/wintermute/math/floatpoint.h52
-rw-r--r--engines/wintermute/math/math_util.cpp4
-rw-r--r--engines/wintermute/math/math_util.h2
-rw-r--r--engines/wintermute/math/matrix4.cpp4
-rw-r--r--engines/wintermute/math/matrix4.h2
-rw-r--r--engines/wintermute/math/rect32.h41
-rw-r--r--engines/wintermute/math/vector2.cpp4
-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.cpp59
-rw-r--r--engines/wintermute/platform_osystem.h8
-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.cpp120
-rw-r--r--engines/wintermute/ui/ui_button.h60
-rw-r--r--engines/wintermute/ui/ui_edit.cpp70
-rw-r--r--engines/wintermute/ui/ui_edit.h29
-rw-r--r--engines/wintermute/ui/ui_entity.cpp28
-rw-r--r--engines/wintermute/ui/ui_entity.h8
-rw-r--r--engines/wintermute/ui/ui_object.cpp102
-rw-r--r--engines/wintermute/ui/ui_object.h58
-rw-r--r--engines/wintermute/ui/ui_text.cpp56
-rw-r--r--engines/wintermute/ui/ui_text.h8
-rw-r--r--engines/wintermute/ui/ui_tiled_image.cpp155
-rw-r--r--engines/wintermute/ui/ui_tiled_image.h6
-rw-r--r--engines/wintermute/ui/ui_window.cpp144
-rw-r--r--engines/wintermute/ui/ui_window.h51
-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.cpp211
-rw-r--r--engines/wintermute/utils/string_util.h5
-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.cpp35
-rw-r--r--engines/wintermute/video/video_theora_player.h8
-rw-r--r--engines/wintermute/wintermute.cpp10
-rw-r--r--engines/wintermute/wintypes.h2
-rw-r--r--engines/zvision/animation/rlf_animation.cpp331
-rw-r--r--engines/zvision/animation/rlf_animation.h163
-rw-r--r--engines/zvision/archives/zfs_archive.cpp157
-rw-r--r--engines/zvision/archives/zfs_archive.h126
-rw-r--r--engines/zvision/configure.engine3
-rw-r--r--engines/zvision/core/console.cpp218
-rw-r--r--engines/zvision/core/console.h55
-rw-r--r--engines/zvision/core/events.cpp186
-rw-r--r--engines/zvision/core/menu.h28
-rw-r--r--engines/zvision/core/save_manager.cpp206
-rw-r--r--engines/zvision/core/save_manager.h91
-rw-r--r--engines/zvision/cursors/cursor.cpp94
-rw-r--r--engines/zvision/cursors/cursor.h66
-rw-r--r--engines/zvision/cursors/cursor_manager.cpp152
-rw-r--r--engines/zvision/cursors/cursor_manager.h114
-rw-r--r--engines/zvision/detection.cpp272
-rw-r--r--engines/zvision/detection.h44
-rw-r--r--engines/zvision/fonts/truetype_font.cpp116
-rw-r--r--engines/zvision/fonts/truetype_font.h81
-rw-r--r--engines/zvision/graphics/render_manager.cpp526
-rw-r--r--engines/zvision/graphics/render_manager.h328
-rw-r--r--engines/zvision/graphics/render_table.cpp240
-rw-r--r--engines/zvision/graphics/render_table.h85
-rw-r--r--engines/zvision/inventory/inventory_manager.h28
-rw-r--r--engines/zvision/module.mk43
-rw-r--r--engines/zvision/scripting/actions.cpp401
-rw-r--r--engines/zvision/scripting/actions.h346
-rw-r--r--engines/zvision/scripting/control.cpp124
-rw-r--r--engines/zvision/scripting/control.h146
-rw-r--r--engines/zvision/scripting/controls/animation_control.cpp263
-rw-r--r--engines/zvision/scripting/controls/animation_control.h87
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp142
-rw-r--r--engines/zvision/scripting/controls/input_control.h60
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp402
-rw-r--r--engines/zvision/scripting/controls/lever_control.h127
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.cpp98
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.h67
-rw-r--r--engines/zvision/scripting/controls/timer_node.cpp73
-rw-r--r--engines/zvision/scripting/controls/timer_node.h55
-rw-r--r--engines/zvision/scripting/puzzle.h74
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp302
-rw-r--r--engines/zvision/scripting/script_manager.cpp444
-rw-r--r--engines/zvision/scripting/script_manager.h225
-rw-r--r--engines/zvision/sound/zork_raw.cpp217
-rw-r--r--engines/zvision/sound/zork_raw.h120
-rw-r--r--engines/zvision/strings/string_manager.cpp255
-rw-r--r--engines/zvision/strings/string_manager.h85
-rw-r--r--engines/zvision/subtitles/subtitles.h29
-rw-r--r--engines/zvision/utility/clock.cpp70
-rw-r--r--engines/zvision/utility/clock.h78
-rw-r--r--engines/zvision/utility/lzss_read_stream.cpp103
-rw-r--r--engines/zvision/utility/lzss_read_stream.h72
-rw-r--r--engines/zvision/utility/single_value_container.cpp348
-rw-r--r--engines/zvision/utility/single_value_container.h183
-rw-r--r--engines/zvision/utility/utility.cpp237
-rw-r--r--engines/zvision/utility/utility.h115
-rw-r--r--engines/zvision/video/video.cpp171
-rw-r--r--engines/zvision/video/zork_avi_decoder.cpp53
-rw-r--r--engines/zvision/video/zork_avi_decoder.h60
-rw-r--r--engines/zvision/zvision.cpp184
-rw-r--r--engines/zvision/zvision.h151
1116 files changed, 95922 insertions, 34602 deletions
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index b1d1008b60..40783a2407 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -29,7 +29,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "common/translation.h"
-
+#include "gui/EventRecorder.h"
#include "engines/advancedDetector.h"
#include "engines/obsolete.h"
@@ -78,7 +78,7 @@ static Common::String generatePreferredTarget(const Common::String &id, const AD
res = res + "-cd";
}
- if (desc->platform != Common::kPlatformDOS && desc->platform != Common::kPlatformUnknown) {
+ if (desc->platform != Common::kPlatformDOS && desc->platform != Common::kPlatformUnknown && !(desc->flags & ADGF_DROPPLATFORM)) {
res = res + "-" + getPlatformAbbrev(desc->platform);
}
@@ -301,6 +301,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
return Common::kUserCanceled;
debug(2, "Running %s", gameDescriptor.description().c_str());
+ initSubSystems(agdDesc);
if (!createInstance(syst, engine, agdDesc))
return Common::kNoGameDataFoundError;
else
@@ -606,3 +607,11 @@ AdvancedMetaEngine::AdvancedMetaEngine(const void *descs, uint descItemSize, con
_maxScanDepth = 1;
_directoryGlobs = NULL;
}
+
+void AdvancedMetaEngine::initSubSystems(const ADGameDescription *gameDesc) const {
+#ifdef ENABLE_EVENTRECORDER
+ if (gameDesc) {
+ g_eventRec.processGameDescription(gameDesc);
+ }
+#endif
+}
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 3eec33abe5..376a59e471 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -87,7 +87,8 @@ enum ADGameFlags {
ADGF_ADDENGLISH = (1 << 24), ///< always add English as language option
ADGF_MACRESFORK = (1 << 25), ///< the md5 for this entry will be calculated from the resource fork
ADGF_USEEXTRAASTITLE = (1 << 26), ///< Extra field value will be used as main game title, not gameid
- ADGF_DROPLANGUAGE = (1 << 28), ///< don't add language to gameid
+ ADGF_DROPLANGUAGE = (1 << 27), ///< don't add language to gameid
+ ADGF_DROPPLATFORM = (1 << 28), ///< don't add platform to gameid
ADGF_CD = (1 << 29), ///< add "-cd" to gameid
ADGF_DEMO = (1 << 30) ///< add "-demo" to gameid
};
@@ -280,6 +281,9 @@ protected:
return 0;
}
+private:
+ void initSubSystems(const ADGameDescription *gameDesc) const;
+
protected:
/**
* Detect games in specified directory.
diff --git a/engines/agi/POTFILES b/engines/agi/POTFILES
new file mode 100644
index 0000000000..414bf2250d
--- /dev/null
+++ b/engines/agi/POTFILES
@@ -0,0 +1,2 @@
+engines/agi/detection.cpp
+engines/agi/saveload.cpp
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/configure.engine b/engines/agi/configure.engine
new file mode 100644
index 0000000000..fad659f86d
--- /dev/null
+++ b/engines/agi/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agi "AGI" yes
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 0c2c3ed3be..a7a3920df8 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),
@@ -848,6 +849,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Tonight The Shrieking Corpses Bleed (Demo v0.11)", "bcc57a7c8d563fa0c333107ae1c0a6e6"),
FANMADE("Tonight The Shrieking Corpses Bleed (v1.01)", "36b38f621b38e8d104aa0807302dc8c9"),
FANMADE("Turks' Quest - Heir to the Planet", "3d19254b737c8b218e5bc4580542b79a"),
+ FANMADE("Ultimate AGI Fangame (Demo)", "2d14d6fa2a2136d681e46e06821905bf"),
FANMADE("URI Quest (v0.173 Feb 27)", "3986eefcf546dafc45f920ae91a697c3"),
FANMADE("URI Quest (v0.173 Jan 29)", "494150940d34130605a4f2e67ee40b12"),
{
diff --git a/engines/agi/loader_v1.cpp b/engines/agi/loader_v1.cpp
index 33e956af41..3b862ed91f 100644
--- a/engines/agi/loader_v1.cpp
+++ b/engines/agi/loader_v1.cpp
@@ -202,7 +202,7 @@ int AgiLoader_v1::loadResource(int t, int n) {
uint8 *data = NULL;
debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/loader_v2.cpp b/engines/agi/loader_v2.cpp
index ee69bb5b27..458927a3bc 100644
--- a/engines/agi/loader_v2.cpp
+++ b/engines/agi/loader_v2.cpp
@@ -178,7 +178,7 @@ int AgiLoader_v2::loadResource(int t, int n) {
uint8 *data = NULL;
debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index 250d8e7615..1dd00dc18e 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -257,7 +257,7 @@ int AgiLoader_v3::loadResource(int t, int n) {
int ec = errOK;
uint8 *data = NULL;
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp
index 807ab2dc2c..d893e44c12 100644
--- a/engines/agi/opcodes.cpp
+++ b/engines/agi/opcodes.cpp
@@ -367,6 +367,18 @@ void AgiEngine::setupOpcodes() {
logicNamesTest = insV2Test;
logicNamesCmd = insV2;
+
+ // Alter opcode parameters for specific games
+ // TODO: This could be either turned into a game feature, or a version
+ // specific check, instead of a game version check
+
+ // The Apple IIGS versions of MH1 and Goldrush both have a parameter for
+ // show.mouse and hide.mouse. Fixes bugs #3577754 and #3426946.
+ if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
+ getPlatform() == Common::kPlatformApple2GS) {
+ logicNamesCmd[176].args = "n"; // hide.mouse
+ logicNamesCmd[178].args = "n"; // show.mouse
+ }
} else {
for (int i = 0; i < ARRAYSIZE(insV1Test); ++i)
_agiCondCommands[i] = insV1Test[i].func;
@@ -376,18 +388,6 @@ void AgiEngine::setupOpcodes() {
logicNamesTest = insV1Test;
logicNamesCmd = insV1;
}
-
- // Alter opcode parameters for specific games
- // TODO: This could be either turned into a game feature, or a version
- // specific check, instead of a game version check
-
- // The Apple IIGS versions of MH1 and Goldrush both have a parameter for
- // show.mouse and hide.mouse. Fixes bugs #3577754 and #3426946.
- if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
- getPlatform() == Common::kPlatformApple2GS) {
- logicNamesCmd[176].args = "n"; // hide.mouse
- logicNamesCmd[178].args = "n"; // show.mouse
- }
}
}
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index ed4882fcab..d0f6540651 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -850,7 +850,7 @@ void MickeyEngine::drawRoomAnimation() {
}
void MickeyEngine::drawRoom() {
- uint8 buffer[256];
+ uint8 buffer[512];
int pBuf = 0;
int nObjs;
diff --git a/engines/agi/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/agi/wagparser.cpp b/engines/agi/wagparser.cpp
index 8dee6545c0..644ca7c103 100644
--- a/engines/agi/wagparser.cpp
+++ b/engines/agi/wagparser.cpp
@@ -178,7 +178,7 @@ bool WagFileParser::parse(const Common::FSNode &node) {
_parsedOk = false; // We haven't parsed the file yet
stream = node.createReadStream(); // Open the file
- if (stream) { // Check that opening the file was succesful
+ if (stream) { // Check that opening the file was successful
if (checkWagVersion(*stream)) { // Check that WinAGI version string is valid
// It seems we've got a valid *.wag file so let's parse its properties from the start.
stream->seek(0); // Rewind the stream
diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp
index 9c5b3d349a..f423995de8 100644
--- a/engines/agi/words.cpp
+++ b/engines/agi/words.cpp
@@ -93,14 +93,25 @@ int AgiEngine::loadWords(const char *fname) {
} while (!(c & 0x80) && k < (int)sizeof(str) - 1);
str[k] = 0;
- // And store it in our internal dictionary
- AgiWord *w = new AgiWord;
- w->word = myStrndup(str, k);
- w->id = fp.readUint16BE();
- _game.words[i].push_back(w);
+ // WORKAROUND:
+ // The SQ0 fan game stores words starting with numbers (like '7up')
+ // in its dictionary under the 'a' entry. We skip these.
+ // See bug #3615061
+ if (str[0] == 'a' + i) {
+ // And store it in our internal dictionary
+ AgiWord *w = new AgiWord;
+ w->word = myStrndup(str, k);
+ w->id = fp.readUint16BE();
+ _game.words[i].push_back(w);
+ }
+
+ k = fp.readByte();
// Are there more words with an already known prefix?
- if (!(k = fp.readByte()))
+ // WORKAROUND: We only break after already seeing words with the
+ // right prefix, for the SQ0 words starting with digits filed under
+ // 'a'. See above comment and bug #3615061.
+ if (k == 0 && str[0] >= 'a' + i)
break;
}
}
diff --git a/engines/agos/POTFILES b/engines/agos/POTFILES
new file mode 100644
index 0000000000..7045ed9afe
--- /dev/null
+++ b/engines/agos/POTFILES
@@ -0,0 +1,2 @@
+engines/agos/saveload.cpp
+engines/agos/animation.cpp
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/configure.engine b/engines/agos/configure.engine
new file mode 100644
index 0000000000..3ae1fb16f2
--- /dev/null
+++ b/engines/agos/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
+add_engine agos2 "AGOS 2 games" yes
diff --git a/engines/agos/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..5647fece7e 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;
@@ -1089,15 +1089,15 @@ bool AGOSEngine_PN::ifObjectInInv(uint16 a) {
}
bool AGOSEngine_PN::testContainer(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 0) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 0) != 0;
}
bool AGOSEngine_PN::testObvious(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 4) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 4) != 0;
}
bool AGOSEngine_PN::testSeen(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 3) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 3) != 0;
}
void AGOSEngine_PN::printIcon(HitArea *ha, uint8 i, uint8 r) {
diff --git a/engines/agos/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/avalanche/animation.cpp b/engines/avalanche/animation.cpp
new file mode 100644
index 0000000000..cef4088722
--- /dev/null
+++ b/engines/avalanche/animation.cpp
@@ -0,0 +1,1498 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* TRIP5 Trippancy V - the sprite animation subsystem */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/animation.h"
+
+namespace Avalanche {
+
+// Art gallery at 2,1; notice about this at 2,2.
+const int32 Animation::kCatacombMap[8][8] = {
+ // Geida's room
+ // 1 2 3 4 5 6 7 8
+ {0x204, 0x200, 0xd0f0, 0xf0ff, 0xff, 0xd20f, 0xd200, 0x200},
+ {0x50f1, 0x20ff, 0x2ff, 0xff, 0xe0ff, 0x20ff, 0x200f, 0x7210},
+ {0xe3f0, 0xe10f, 0x72f0, 0xff, 0xe0ff, 0xff, 0xff, 0x800f},
+ {0x2201, 0x2030, 0x800f, 0x220, 0x20f, 0x30, 0xff, 0x23f}, // >> Oubliette
+ {0x5024, 0xf3, 0xff, 0x200f, 0x22f0, 0x20f, 0x200, 0x7260},
+ {0xf0, 0x2ff, 0xe2ff, 0xff, 0x200f, 0x50f0, 0x72ff, 0x201f},
+ {0xf6, 0x220f, 0x22f0, 0x30f, 0xf0, 0x20f, 0x8200, 0x2f0}, // <<< In here
+ {0x34, 0x200f, 0x51f0, 0x201f, 0xf1, 0x50ff, 0x902f, 0x2062}
+};
+
+AnimationType::AnimationType(Animation *anim) {
+ _anim = anim;
+
+ _xLength = 0;
+ _yLength = 0;
+ for (int i = 0; i < 24; i++) {
+ _mani[i] = nullptr;
+ _sil[i] = nullptr;
+ }
+ _frameNum = 0;
+ _seq = 0;
+ _characterId = 0;
+ _count = 0;
+ _facingDir = kDirNone;
+ _stepNum = 0;
+ _x = 0;
+ _y = 0;
+ _moveX = 0;
+ _moveY = 0;
+ _quick = false;
+ _visible = false;
+ _homing = false;
+ _doCheck = false;
+ _homingX = 0;
+ _homingY = 0;
+ _speedX = 0;
+ _speedY = 0;
+ _vanishIfStill = false;
+ _callEachStepFl = false;
+ _eachStepProc = Animation::kProcNone;
+ _fgBubbleCol = kColorWhite;
+ _bgBubbleCol = kColorBlack;
+ _id = 177;
+}
+
+/**
+ * Loads & sets up the sprite.
+ */
+void AnimationType::init(byte spritenum, bool doCheck) {
+ const int32 idshould = -1317732048;
+
+ if (spritenum == 177)
+ return; // Already running!
+
+ Common::File inf;
+ Common::String filename = Common::String::format("sprite%d.avd", spritenum);
+ if (!inf.open(filename))
+ error("AVALANCHE: Trip: File not found: %s", filename.c_str());
+
+ inf.seek(177);
+
+ int32 id = inf.readSint32LE();
+ if (id != idshould) {
+ inf.close();
+ return;
+ }
+
+ // Replace variable named 'soa' in the original code.
+ inf.skip(2);
+ // Skip real name Size (1 byte) then fixed sized zone containing name (12 bytes)
+ inf.skip(1 + 12);
+ // Skip real comment size (1 byte) then fixed sized zone containing comment (16 bytes)
+ inf.skip(1 + 16);
+
+ _frameNum = inf.readByte();
+ _xLength = inf.readByte();
+ _yLength = inf.readByte();
+ _seq = inf.readByte();
+ uint16 size = inf.readUint16LE();
+ assert (size > 6);
+ _fgBubbleCol = (Color)inf.readByte();
+ _bgBubbleCol = (Color)inf.readByte();
+ _characterId = inf.readByte();
+
+ byte xWidth = _xLength / 8;
+ if ((_xLength % 8) > 0)
+ xWidth++;
+ for (int i = 0; i < _frameNum; i++) {
+ _sil[i] = new SilType[11 * (_yLength + 1)];
+ _mani[i] = new ManiType[size - 6];
+ for (int j = 0; j <= _yLength; j++)
+ inf.read((*_sil[i])[j], xWidth);
+ inf.read(*_mani[i], size - 6);
+ }
+
+ _x = 0;
+ _y = 0;
+ _quick = true;
+ _visible = false;
+ _speedX = kWalk;
+ _speedY = 1;
+ _homing = false;
+ _moveX = 0;
+ _moveY = 0;
+ _stepNum = 0;
+ _doCheck = doCheck;
+ _count = 0;
+ _id = spritenum;
+ _vanishIfStill = false;
+ _callEachStepFl = false;
+
+ inf.close();
+}
+
+/**
+ * Just sets 'quick' to false.
+ * @remarks Originally called 'original'
+ */
+void AnimationType::reset() {
+ _quick = false;
+ _id = 177;
+}
+
+/**
+ * Drops sprite onto screen.
+ * @remarks Originally called 'andexor'
+ */
+void AnimationType::draw() {
+ if (_vanishIfStill && (_moveX == 0) && (_moveY == 0))
+ return;
+
+ byte picnum = _facingDir * _seq + _stepNum;
+
+ _anim->_vm->_graphics->drawSprite(this, picnum, _x, _y);
+}
+
+/**
+ * Turns character round.
+ */
+void AnimationType::turn(Direction whichway) {
+ if (whichway == 8)
+ _facingDir = kDirUp;
+ else
+ _facingDir = whichway;
+}
+
+/**
+ * Switches it on.
+ */
+void AnimationType::appear(int16 wx, int16 wy, Direction wf) {
+ _x = (wx / 8) * 8;
+ _y = wy;
+ _oldX[_anim->_vm->_cp] = wx;
+ _oldY[_anim->_vm->_cp] = wy;
+ turn(wf);
+ _visible = true;
+ _moveX = 0;
+ _moveY = 0;
+}
+
+/**
+ * Check collision
+ * @remarks Originally called 'collision_check'
+ */
+bool AnimationType::checkCollision() {
+ for (int i = 0; i < _anim->kSpriteNumbMax; i++) {
+ AnimationType *spr = _anim->_sprites[i];
+ if (spr->_quick && (spr->_id != _id) && (_x + _xLength > spr->_x) && (_x < spr->_x + spr->_xLength) && (spr->_y == _y))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Prepares for draw(), etc.
+ */
+void AnimationType::walk() {
+ if (!_anim->_vm->_doingSpriteRun) {
+ _oldX[_anim->_vm->_cp] = _x;
+ _oldY[_anim->_vm->_cp] = _y;
+ if (_homing)
+ homeStep();
+ _x += _moveX;
+ _y += _moveY;
+ }
+
+ if (_doCheck) {
+ if (checkCollision()) {
+ bounce();
+ return;
+ }
+
+ byte magicColor = _anim->checkFeet(_x, _x + _xLength, _oldY[_anim->_vm->_cp], _y, _yLength) - 1;
+ // -1 is because the modified array indexes of magics[] compared to Pascal .
+
+ if ((magicColor != 255) & !_anim->_vm->_doingSpriteRun) {
+ MagicType *magic = &_anim->_vm->_magics[magicColor];
+ switch (magic->_operation) {
+ case kMagicExclaim:
+ bounce();
+ _anim->_mustExclaim = true;
+ _anim->_sayWhat = magic->_data;
+ break;
+ case kMagicBounce:
+ bounce();
+ break;
+ case kMagicTransport:
+ _anim->_vm->flipRoom((Room)(magic->_data >> 8), magic->_data & 0xff);
+ break;
+ case kMagicUnfinished: {
+ bounce();
+ Common::String tmpStr = Common::String::format("%c%cSorry.%cThis place is not available yet!",
+ kControlBell, kControlCenter, kControlRoman);
+ _anim->_vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kMagicSpecial:
+ _anim->callSpecial(magic->_data);
+ break;
+ case kMagicOpenDoor:
+ _anim->_vm->openDoor((Room)(magic->_data >> 8), magic->_data & 0xff, magicColor);
+ break;
+ }
+ }
+ }
+
+ if (!_anim->_vm->_doingSpriteRun) {
+ _count++;
+ if (((_moveX != 0) || (_moveY != 0)) && (_count > 1)) {
+ _stepNum++;
+ if (_stepNum == _seq)
+ _stepNum = 0;
+ _count = 0;
+ }
+ }
+}
+
+/**
+ * Bounces off walls
+ */
+void AnimationType::bounce() {
+ _x = _oldX[_anim->_vm->_cp];
+ _y = _oldY[_anim->_vm->_cp];
+ if (_doCheck)
+ _anim->stopWalking();
+ else
+ stopWalk();
+ _anim->_vm->drawDirection();
+}
+
+int8 AnimationType::getSign(int16 val) {
+ if (val > 0)
+ return 1;
+ else if (val < 0)
+ return -1;
+ else
+ return 0;
+}
+
+/**
+ * Home in on a point.
+ */
+void AnimationType::walkTo(byte pedNum) {
+ PedType *curPed = &_anim->_vm->_peds[pedNum];
+
+ setSpeed(getSign(curPed->_x - _x) * 4, getSign(curPed->_y - _y));
+ _homingX = curPed->_x - _xLength / 2;
+ _homingY = curPed->_y - _yLength;
+ _homing = true;
+}
+
+void AnimationType::stopHoming() {
+ _homing = false;
+}
+
+/**
+ * Calculates ix & iy for one homing step.
+ */
+void AnimationType::homeStep() {
+ int16 temp;
+
+ if ((_homingX == _x) && (_homingY == _y)) {
+ // touching the target
+ stopWalk();
+ return;
+ }
+ _moveX = 0;
+ _moveY = 0;
+ if (_homingY != _y) {
+ temp = _homingY - _y;
+ if (temp > 4)
+ _moveY = 4;
+ else if (temp < -4)
+ _moveY = -4;
+ else
+ _moveY = temp;
+ }
+ if (_homingX != _x) {
+ temp = _homingX - _x;
+ if (temp > 4)
+ _moveX = 4;
+ else if (temp < -4)
+ _moveX = -4;
+ else
+ _moveX = temp;
+ }
+}
+
+/**
+ * Sets ix & iy, non-homing, etc.
+ */
+void AnimationType::setSpeed(int8 xx, int8 yy) {
+ _moveX = xx;
+ _moveY = yy;
+ if ((_moveX == 0) && (_moveY == 0))
+ return; // no movement
+ if (_moveX == 0) {
+ // No horz movement
+ if (_moveY < 0)
+ turn(kDirUp);
+ else
+ turn(kDirDown);
+ } else {
+ if (_moveX < 0)
+ turn(kDirLeft);
+ else
+ turn(kDirRight);
+ }
+}
+
+/**
+ * Stops the sprite from moving.
+ */
+void AnimationType::stopWalk() {
+ _moveX = 0;
+ _moveY = 0;
+ _homing = false;
+}
+
+/**
+ * Sets up talk vars.
+ */
+void AnimationType::chatter() {
+ _anim->_vm->_dialogs->setTalkPos(_x + _xLength / 2, _y);
+ _anim->_vm->_graphics->setDialogColor(_bgBubbleCol, _fgBubbleCol);
+}
+
+void AnimationType::remove() {
+ for (int i = 0; i < _frameNum; i++) {
+ delete[] _mani[i];
+ delete[] _sil[i];
+ }
+
+ _quick = false;
+ _id = 177;
+}
+
+Animation::Animation(AvalancheEngine *vm) {
+ _vm = vm;
+ _mustExclaim = false;
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ _sprites[i] = new AnimationType(this);
+ }
+
+ _direction = kDirNone;
+ _oldDirection = kDirNone;
+ _arrowTriggered = false;
+ _geidaSpin = 0;
+ _geidaTime = 0;
+ _sayWhat = 0;
+}
+
+Animation::~Animation() {
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+
+ if (curSpr->_quick)
+ curSpr->remove();
+ delete(curSpr);
+ }
+}
+
+/**
+ * Resets Animation variables.
+ * @remarks Originally called 'loadtrip'
+ */
+void Animation::resetAnims() {
+ setDirection(kDirStopped);
+ for (int16 i = 0; i < kSpriteNumbMax; i++)
+ _sprites[i]->reset();
+}
+
+byte Animation::checkFeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) {
+ if (!_vm->_alive)
+ return 0;
+
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 > 639)
+ x2 = 639;
+
+ int16 minY = MIN(oy, y) + yl;
+ int16 maxY = MAX(oy, y) + yl;
+
+ return _vm->_graphics->getAlsoColor(x1, minY, x2, maxY);
+}
+
+byte Animation::geidaPed(byte ped) {
+ switch (ped) {
+ case 1:
+ return 6;
+ case 2:
+ case 6:
+ return 7;
+ case 3:
+ case 5:
+ return 8;
+ case 4:
+ return 9;
+ default:
+ error("geidaPed(): Unhandled ped value %d", ped);
+ }
+}
+
+/**
+ * When you enter a new position in the catacombs, this procedure should be
+ * called. It changes the 'also' codes so that they may match the picture
+ * on the screen.
+ */
+void Animation::catacombMove(byte ped) {
+ // XY_uint16 is _catacombX+_catacombY*256. Thus, every room in the
+ // catacombs has a different number for it.
+ uint16 xy = _vm->_catacombX + _vm->_catacombY * 256;
+ _geidaSpin = 0;
+
+ switch (xy) {
+ case 1801: // Exit catacombs
+ _vm->flipRoom(kRoomLustiesRoom, 4);
+ _vm->_dialogs->displayText("Phew! Nice to be out of there!");
+ return;
+ case 1033:{ // Oubliette
+ _vm->flipRoom(kRoomOubliette, 1);
+ Common::String tmpStr = Common::String::format("Oh, NO!%c1%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ return;
+ case 4:
+ _vm->flipRoom(kRoomGeidas, 1);
+ return;
+ case 2307:
+ _vm->flipRoom(kRoomLusties, 5);
+ _vm->_dialogs->displayText("Oh no... here we go again...");
+ _vm->_userMovesAvvy = false;
+ _sprites[0]->_moveY = 1;
+ _sprites[0]->_moveX = 0;
+ return;
+ }
+
+ if (!_vm->_enterCatacombsFromLustiesRoom)
+ _vm->loadRoom(29);
+ int32 here = kCatacombMap[_vm->_catacombY - 1][_vm->_catacombX - 1];
+
+ switch (here & 0xf) { // West.
+ case 0: // no connection (wall)
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27);
+ break;
+ case 0x1: // no connection (wall + shield),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 28); // ...shield.
+ break;
+ case 0x2: // wall with door
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door.
+ break;
+ case 0x3: // wall with door and shield
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 28); // ...shield.
+ break;
+ case 0x4: // no connection (wall + window),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 4); // ...window.
+ break;
+ case 0x5: // wall with door and window
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 4); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // No door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 6); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 6); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_magics[1]._operation = kMagicNothing; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicSpecial; // Straight wall.
+ break;
+ }
+
+ /* ---- */
+
+ switch ((here & 0xf0) >> 4) { // East
+ case 0: // no connection (wall)
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 18);
+ break;
+ case 0x1: // no connection (wall + window),
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 19); // ...window.
+ break;
+ case 0x2: // wall with door
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 20); // ...door.
+ break;
+ case 0x3: // wall with door and window
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 19); // ...door, and...
+ _vm->_background->draw(-1, -1, 20); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // No door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 17); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 20); // ...door, and...
+ _vm->_background->draw(-1, -1, 17); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_magics[4]._operation = kMagicNothing; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicSpecial; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ break;
+ }
+
+ switch ((here & 0xf00) >> 8) { // South
+ case 0: // No connection.
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[11]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ case 0x1:
+ _vm->_background->draw(-1, -1, 21);
+
+ if ((xy == 2051) && _vm->_geidaFollows)
+ _vm->_magics[12]._operation = kMagicExclaim;
+ else
+ _vm->_magics[12]._operation = kMagicSpecial; // Right exit south.
+
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[11]._operation = kMagicBounce;
+ break;
+ case 0x2:
+ _vm->_background->draw(-1, -1, 22);
+ _vm->_magics[6]._operation = kMagicSpecial; // Middle exit south.
+ _vm->_magics[11]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ case 0x3:
+ _vm->_background->draw(-1, -1, 23);
+ _vm->_magics[11]._operation = kMagicSpecial; // Left exit south.
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ }
+
+ switch ((here & 0xf000) >> 12) { // North
+ case 0: // No connection
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ break;
+ // LEFT handles:
+#if 0
+ case 0x1:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->magics[1].op = _vm->bounces; // { Left exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ case 0x2:
+ _vm->_background->draw(-1, -1, 3);
+ _vm->_magics[0]._operation = kMagicBounce; // Middle exit north.
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x3:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->magics[1].op = _vm->bounces; // { Right exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+ // RIGHT handles:
+ case 0x4:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->magics[1].op = _vm->bounces; // { Left exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ case 0x5:
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_magics[0]._operation = kMagicBounce; // Middle exit north.
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x6:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->magics[1].op = _vm->bounces; // { Right exit north. }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ // ARCHWAYS:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ _vm->_background->draw(-1, -1, 5);
+
+ if (((here & 0xf000) >> 12) > 0x7)
+ _vm->_background->draw(-1, -1, 30);
+ if (((here & 0xf000) >> 12) == 0x9)
+ _vm->_background->draw(-1, -1, 31);
+
+ _vm->_magics[0]._operation = kMagicSpecial; // Middle arch north.
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ break;
+ // DECORATIONS:
+ case 0xd: // No connection + WINDOW
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 13);
+ break;
+ case 0xe: // No connection + TORCH
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 7);
+ break;
+ // Recessed door:
+ case 0xf:
+ _vm->_magics[0]._operation = kMagicNothing; // Door to Geida's room.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+ }
+
+ switch (xy) {
+ case 514:
+ _vm->_background->draw(-1, -1, 16);
+ break; // [2,2] : "Art Gallery" sign over door.
+ case 264:
+ _vm->_background->draw(-1, -1, 8);
+ break; // [8,1] : "The Wrong Way!" sign.
+ case 1797:
+ _vm->_background->draw(-1, -1, 1);
+ break; // [5,7] : "Ite Mingite" sign.
+ case 258:
+ for (int i = 0; i <= 2; i++) { // [2,1] : Art gallery - pictures
+ _vm->_background->draw(130 + i * 120, 70, 14);
+ _vm->_background->draw(184 + i * 120, 78, 15);
+ }
+ break;
+ case 1287:
+ for (int i = 10; i <= 13; i++)
+ _vm->_background->draw(-1, -1, i - 1);
+ break; // [7,5] : 4 candles.
+ case 776:
+ _vm->_background->draw(-1, -1, 9);
+ break; // [8,3] : 1 candle.
+ case 2049:
+ _vm->_background->draw(-1, -1, 10);
+ break; // [1,8] : another candle.
+ case 257:
+ _vm->_background->draw(-1, -1, 11);
+ _vm->_background->draw(-1, -1, 12);
+ break; // [1,1] : the other two.
+ }
+
+ if (_vm->_geidaFollows && (ped > 0)) {
+ AnimationType *spr1 = _sprites[1];
+
+ if (!spr1->_quick) // If we don't already have her...
+ spr1->init(5, true); // ...Load Geida.
+ appearPed(1, geidaPed(ped));
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = kProcGeida;
+ }
+}
+
+/**
+ * This proc gets called whenever you touch a line defined as _vm->special.
+ */
+void Animation::dawnDelay() {
+ _vm->_timer->addTimer(2, Timer::kProcDawnDelay, Timer::kReasonDawndelay);
+}
+
+void Animation::callSpecial(uint16 which) {
+ switch (which) {
+ case 1: // _vm->special 1: Room 22: top of stairs.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_brummieStairs = 1;
+ _vm->_magics[9]._operation = kMagicNothing;
+ _vm->_timer->addTimer(10, Timer::kProcStairs, Timer::kReasonBrummieStairs);
+ stopWalking();
+ _vm->_userMovesAvvy = false;
+ break;
+ case 2: // _vm->special 2: Room 22: bottom of stairs.
+ _vm->_brummieStairs = 3;
+ _vm->_magics[10]._operation = kMagicNothing;
+ _vm->_magics[11]._operation = kMagicExclaim;
+ _vm->_magics[11]._data = 5;
+ _vm->_magics[3]._operation = kMagicBounce; // Now works as planned!
+ stopWalking();
+ _vm->_dialogs->displayScrollChain('Q', 26);
+ _vm->_userMovesAvvy = true;
+ break;
+ case 3: // _vm->special 3: Room 71: triggers dart.
+ _sprites[0]->bounce(); // Must include that.
+
+ if (!_arrowTriggered) {
+ _arrowTriggered = true;
+
+ AnimationType *spr1 = _sprites[1];
+ appearPed(1, 3); // The dart starts at ped 4, and...
+ spr1->walkTo(4); // flies to ped 5 (- 1 for pascal to C conversion).
+ spr1->_facingDir = kDirUp; // Only face.
+ // Should call some kind of Eachstep procedure which will deallocate
+ // the sprite when it hits the wall, and replace it with the chunk
+ // graphic of the arrow buried in the plaster. */
+
+ // OK!
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = kProcArrow;
+ }
+ break;
+ case 4: // This is the ghost room link.
+ _vm->fadeOut();
+ _sprites[0]->turn(kDirRight); // you'll see this after we get back from bootstrap
+ _vm->_timer->addTimer(1, Timer::kProcGhostRoomPhew, Timer::kReasonGhostRoomPhew);
+ //_vm->_enid->backToBootstrap(3); TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+ break;
+ case 5:
+ if (_vm->_friarWillTieYouUp) {
+ // _vm->special 5: Room 42: touched tree, and get tied up.
+ _vm->_magics[4]._operation = kMagicBounce; // Boundary effect is now working again.
+ _vm->_dialogs->displayScrollChain('Q', 35);
+ _sprites[0]->remove();
+
+ AnimationType *spr1 = _sprites[1];
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_dialogs->displayScrollChain('Q', 36);
+ _vm->_tiedUp = true;
+ _vm->_friarWillTieYouUp = false;
+ spr1->walkTo(2);
+ spr1->_vanishIfStill = true;
+ spr1->_doCheck = true; // One of them must have Check_Me switched on.
+ _vm->setRoom(kPeopleFriarTuck, kRoomDummy); // Not here, then.
+ _vm->_timer->addTimer(364, Timer::kProcHangAround, Timer::kReasonHangingAround);
+ }
+ break;
+ case 6: {
+ // _vm->special 6: fall down oubliette.
+ AnimationType *avvy = _sprites[0];
+ _vm->_userMovesAvvy = false;
+ avvy->_moveX = 3;
+ avvy->_moveY = 0;
+ avvy->_facingDir = kDirRight;
+ _vm->_timer->addTimer(1, Timer::kProcFallDownOubliette, Timer::kReasonFallingDownOubliette);
+ }
+ break;
+ case 7: // _vm->special 7: stop falling down oubliette.
+ _sprites[0]->_visible = false;
+ _vm->_magics[9]._operation = kMagicNothing;
+ stopWalking();
+ _vm->_timer->loseTimer(Timer::kReasonFallingDownOubliette);
+ //_vm->mblit(12, 80, 38, 160, 3, 0);
+ //_vm->mblit(12, 80, 38, 160, 3, 1);
+ _vm->_dialogs->displayText("Oh dear, you seem to be down the bottom of an oubliette.");
+ _vm->_timer->addTimer(200, Timer::kProcMeetAvaroid, Timer::kReasonMeetingAvaroid);
+ break;
+ case 8: // _vm->special 8: leave du Lustie's room.
+ if (_vm->_geidaFollows && !_vm->_lustieIsAsleep) {
+ AnimationType *spr1 = _sprites[1];
+ _vm->_dialogs->displayScrollChain('Q', 63);
+ spr1->turn(kDirDown);
+ spr1->stopWalk();
+ spr1->_callEachStepFl = false; // Geida
+ _vm->gameOver();
+ }
+ break;
+ case 9: {
+ // _vm->special 9: lose Geida to Robin Hood...
+ if (!_vm->_geidaFollows)
+ return; // DOESN'T COUNT: no Geida.
+ AnimationType *spr1 = _sprites[1];
+ spr1->_callEachStepFl = false; // She no longer follows Avvy around.
+ spr1->walkTo(3); // She walks to somewhere...
+ _sprites[0]->remove(); // Lose Avvy.
+ _vm->_userMovesAvvy = false;
+ _vm->_timer->addTimer(40, Timer::kProcRobinHoodAndGeida, Timer::kReasonRobinHoodAndGeida);
+ }
+ break;
+ case 10: // _vm->special 10: transfer north in catacombs.
+ if ((_vm->_catacombX == 4) && (_vm->_catacombY == 1)) {
+ // Into Geida's room.
+ if (_vm->_objects[kObjectKey - 1])
+ _vm->_dialogs->displayScrollChain('Q', 62);
+ else {
+ _vm->_dialogs->displayScrollChain('Q', 61);
+ return;
+ }
+ }
+ _vm->fadeOut();
+ _vm->_catacombY--;
+ catacombMove(4);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ switch ((kCatacombMap[_vm->_catacombY - 1][_vm->_catacombX - 1] & 0xf00) >> 8) {
+ case 0x1:
+ appearPed(0, 11);
+ break;
+ case 0x3:
+ appearPed(0, 10);
+ break;
+ default:
+ appearPed(0, 3);
+ }
+ dawnDelay();
+ break;
+ case 11: // _vm->special 11: transfer east in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombX++;
+ catacombMove(1);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 0);
+ dawnDelay();
+ break;
+ case 12: // _vm->special 12: transfer south in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombY++;
+ catacombMove(2);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 1);
+ dawnDelay();
+ break;
+ case 13: // _vm->special 13: transfer west in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombX--;
+ catacombMove(3);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 2);
+ dawnDelay();
+ break;
+ }
+}
+
+void Animation::updateSpeed() {
+ AnimationType *avvy = _sprites[0];
+ // Given that you've just changed the speed in _speedX, this adjusts _moveX.
+ avvy->_moveX = (avvy->_moveX / 3) * avvy->_speedX;
+ _vm->_graphics->drawSpeedBar(avvy->_speedX);
+}
+
+void Animation::setMoveSpeed(byte t, Direction dir) {
+ AnimationType *spr = _sprites[t];
+ switch (dir) {
+ case kDirUp:
+ spr->setSpeed(0, -spr->_speedY);
+ break;
+ case kDirDown:
+ spr->setSpeed(0, spr->_speedY);
+ break;
+ case kDirLeft:
+ spr->setSpeed(-spr->_speedX, 0);
+ break;
+ case kDirRight:
+ spr->setSpeed(spr->_speedX, 0);
+ break;
+ case kDirUpLeft:
+ spr->setSpeed(-spr->_speedX, -spr->_speedY);
+ break;
+ case kDirUpRight:
+ spr->setSpeed(spr->_speedX, -spr->_speedY);
+ break;
+ case kDirDownLeft:
+ spr->setSpeed(-spr->_speedX, spr->_speedY);
+ break;
+ case kDirDownRight:
+ spr->setSpeed(spr->_speedX, spr->_speedY);
+ break;
+ default:
+ break;
+ }
+}
+
+void Animation::appearPed(byte sprNum, byte pedNum) {
+ AnimationType *curSpr = _sprites[sprNum];
+ PedType *curPed = &_vm->_peds[pedNum];
+ curSpr->appear(curPed->_x - curSpr->_xLength / 2, curPed->_y - curSpr->_yLength, curPed->_direction);
+ setMoveSpeed(sprNum, curPed->_direction);
+}
+
+/**
+ * @remarks Originally called 'follow_avvy_y'
+ */
+void Animation::followAvalotY(byte tripnum) {
+ if (_sprites[0]->_facingDir == kDirLeft)
+ return;
+
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *spr1 = _sprites[1];
+
+ if (tripSpr->_homing)
+ tripSpr->_homingY = spr1->_y;
+ else {
+ if (tripSpr->_y < spr1->_y)
+ tripSpr->_y++;
+ else if (tripSpr->_y > spr1->_y)
+ tripSpr->_y--;
+ else
+ return;
+
+ if (tripSpr->_moveX == 0) {
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ tripSpr->_count = 0;
+ }
+ }
+}
+
+void Animation::backAndForth(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (!tripSpr->_homing) {
+ if (tripSpr->_facingDir == kDirRight)
+ tripSpr->walkTo(3);
+ else
+ tripSpr->walkTo(4);
+ }
+}
+
+void Animation::faceAvvy(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (!tripSpr->_homing) {
+ if (_sprites[0]->_x >= tripSpr->_x)
+ tripSpr->_facingDir = kDirRight;
+ else
+ tripSpr->_facingDir = kDirLeft;
+ }
+}
+
+void Animation::arrowProcs(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[tripnum];
+
+ if (tripSpr->_homing) {
+ // Arrow is still in flight.
+ // We must check whether or not the arrow has collided tr[tripnum] Avvy's head.
+ // This is so if: a) the bottom of the arrow is below Avvy's head,
+ // b) the left of the arrow is left of the right of Avvy's head, and
+ // c) the right of the arrow is right of the left of Avvy's head.
+ if ((tripSpr->_y + tripSpr->_yLength >= avvy->_y) // A
+ && (tripSpr->_x <= avvy->_x + avvy->_xLength) // B
+ && (tripSpr->_x + tripSpr->_xLength >= avvy->_x)) { // C
+ // OK, it's hit him... what now?
+
+ _sprites[1]->_callEachStepFl = false; // prevent recursion.
+ _vm->_dialogs->displayScrollChain('Q', 47); // Complaint!
+ tripSpr->remove(); // Deallocate the arrow.
+
+ _vm->gameOver();
+
+ _vm->_userMovesAvvy = false; // Stop the user from moving him.
+ _vm->_timer->addTimer(55, Timer::kProcNaughtyDuke, Timer::kReasonNaughtyDuke);
+ }
+ } else { // Arrow has hit the wall!
+ tripSpr->remove(); // Deallocate the arrow.
+ _vm->_background->draw(-1, -1, 2); // Show pic of arrow stuck into the door.
+ _vm->_arrowInTheDoor = true; // So that we can pick it up.
+ }
+}
+
+void Animation::grabAvvy(byte tripnum) { // For Friar Tuck, in Nottingham.
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[0];
+
+ int16 tox = avvy->_x + 17;
+ int16 toy = avvy->_y - 1;
+ if ((tripSpr->_x == tox) && (tripSpr->_y == toy)) {
+ tripSpr->_callEachStepFl = false;
+ tripSpr->_facingDir = kDirLeft;
+ tripSpr->stopWalk();
+ // ... whatever ...
+ } else {
+ // Still some way to go.
+ if (tripSpr->_x < tox) {
+ tripSpr->_x += 5;
+ if (tripSpr->_x > tox)
+ tripSpr->_x = tox;
+ }
+ if (tripSpr->_y < toy)
+ tripSpr->_y++;
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ }
+}
+
+void Animation::takeAStep(byte &tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (tripSpr->_moveX == 0) {
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ tripSpr->_count = 0;
+ }
+}
+
+void Animation::spin(Direction dir, byte &tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (tripSpr->_facingDir == dir)
+ return;
+
+ tripSpr->_facingDir = dir;
+ if (tripSpr->_id == 2)
+ return; // Not for Spludwick
+
+ _geidaSpin++;
+ _geidaTime = 20;
+ if (_geidaSpin == 5) {
+ _vm->_dialogs->displayText("Steady on, Avvy, you'll make the poor girl dizzy!");
+ _geidaSpin = 0;
+ _geidaTime = 0; // knock out records
+ }
+}
+
+void Animation::geidaProcs(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[0];
+
+ if (_geidaTime > 0) {
+ _geidaTime--;
+ if (_geidaTime == 0)
+ _geidaSpin = 0;
+ }
+
+ if (tripSpr->_y < (avvy->_y - 2)) {
+ // Geida is further from the screen than Avvy.
+ spin(kDirDown, tripnum);
+ tripSpr->_moveY = 1;
+ tripSpr->_moveX = 0;
+ takeAStep(tripnum);
+ return;
+ } else if (tripSpr->_y > (avvy->_y + 2)) {
+ // Avvy is further from the screen than Geida.
+ spin(kDirUp, tripnum);
+ tripSpr->_moveY = -1;
+ tripSpr->_moveX = 0;
+ takeAStep(tripnum);
+ return;
+ }
+
+ tripSpr->_moveY = 0;
+ // These 12-s are not in the original, I added them to make the following method more "smooth".
+ // Now the NPC which is following Avvy won't block his way and will walk next to him properly.
+ if (tripSpr->_x < avvy->_x - avvy->_speedX * 8 - 12) {
+ tripSpr->_moveX = avvy->_speedX;
+ spin(kDirRight, tripnum);
+ takeAStep(tripnum);
+ } else if (tripSpr->_x > avvy->_x + avvy->_speedX * 8 + 12) {
+ tripSpr->_moveX = -avvy->_speedX;
+ spin(kDirLeft, tripnum);
+ takeAStep(tripnum);
+ } else
+ tripSpr->_moveX = 0;
+}
+
+/**
+ * @remarks Originally called 'call_andexors'
+ */
+void Animation::drawSprites() {
+ int8 order[5];
+ byte temp;
+ bool ok;
+
+ for (int i = 0; i < 5; i++)
+ order[i] = -1;
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_visible)
+ order[i] = i;
+ }
+
+ do {
+ ok = true;
+ for (int i = 0; i < 4; i++) {
+ if ((order[i] != -1) && (order[i + 1] != -1) && (_sprites[order[i]]->_y > _sprites[order[i + 1]]->_y)) {
+ // Swap them!
+ temp = order[i];
+ order[i] = order[i + 1];
+ order[i + 1] = temp;
+ ok = false;
+ }
+ }
+ } while (!ok);
+
+ _vm->_graphics->refreshBackground();
+
+ for (int i = 0; i < 5; i++) {
+ if (order[i] > -1)
+ _sprites[order[i]]->draw();
+ }
+}
+
+/**
+ * Animation links
+ * @remarks Originally called 'trippancy_link'
+ */
+void Animation::animLink() {
+ if (_vm->_menu->isActive() || _vm->_seeScroll)
+ return;
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_visible)
+ curSpr->walk();
+ }
+
+ drawSprites();
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_callEachStepFl) {
+ switch (curSpr->_eachStepProc) {
+ case kProcFollowAvvyY :
+ followAvalotY(i);
+ break;
+ case kProcBackAndForth :
+ backAndForth(i);
+ break;
+ case kProcFaceAvvy :
+ faceAvvy(i);
+ break;
+ case kProcArrow :
+ arrowProcs(i);
+ break;
+ // PROCSpludwick_procs : spludwick_procs(fv);
+ case kProcGrabAvvy :
+ grabAvvy(i);
+ break;
+ case kProcGeida :
+ geidaProcs(i);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_mustExclaim) {
+ _mustExclaim = false;
+ _vm->_dialogs->displayScrollChain('X', _sayWhat);
+ }
+}
+
+void Animation::stopWalking() {
+ AnimationType *avvy = _sprites[0];
+
+ avvy->stopWalk();
+ _direction = kDirStopped;
+ if (_vm->_alive)
+ avvy->_stepNum = 1;
+}
+
+/**
+ * Hide in the cupboard
+ * @remarks Originally called 'hide_in_the_cupboard'
+ */
+void Animation::hideInCupboard() {
+ if (_vm->_avvysInTheCupboard) {
+ if (_vm->_parser->_wearing == kObjectDummy) {
+ Common::String tmpStr = Common::String::format("%cAVVY!%cGet dressed first!", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ _sprites[0]->_visible = true;
+ _vm->_userMovesAvvy = true;
+ appearPed(0, 2); // Walk out of the cupboard.
+ _vm->_dialogs->displayText("You leave the cupboard. Nice to be out of there!");
+ _vm->_avvysInTheCupboard = false;
+ _vm->_sequence->startCupboardSeq();
+ }
+ } else {
+ // Not hiding in the cupboard
+ _sprites[0]->_visible = false;
+ _vm->_userMovesAvvy = false;
+ Common::String tmpStr = Common::String::format("You walk into the room...%cIt seems to be an empty, " \
+ "but dusty, cupboard. Hmmmm... you leave the door slightly open to avoid suffocation.", kControlParagraph);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->_avvysInTheCupboard = true;
+ _vm->_background->draw(-1, -1, 7);
+ }
+}
+
+/**
+ * Returns true if you're within field "which".
+ */
+bool Animation::inField(byte which) {
+ AnimationType *avvy = _sprites[0];
+
+ FieldType *curField = &_vm->_fields[which];
+ int16 yy = avvy->_y + avvy->_yLength;
+
+ return (avvy->_x >= curField->_x1) && (avvy->_x <= curField->_x2) && (yy >= curField->_y1) && (yy <= curField->_y2);
+}
+
+/**
+ * Returns True if you're near a door.
+ */
+bool Animation::nearDoor() {
+ if (_vm->_fieldNum < 8)
+ // there ARE no doors here!
+ return false;
+
+ AnimationType *avvy = _sprites[0];
+
+ int16 ux = avvy->_x;
+ int16 uy = avvy->_y + avvy->_yLength;
+
+ for (int i = 8; i < _vm->_fieldNum; i++) {
+ FieldType *curField = &_vm->_fields[i];
+ if ((ux >= curField->_x1) && (ux <= curField->_x2) && (uy >= curField->_y1) && (uy <= curField->_y2))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @remarks Originally called 'tripkey'
+ */
+void Animation::handleMoveKey(const Common::Event &event) {
+ if (!_vm->_userMovesAvvy)
+ return;
+
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ _vm->_parser->tryDropdown();
+ else {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ if (_direction != kDirUp) {
+ _direction = kDirUp;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_DOWN:
+ if (_direction != kDirDown) {
+ _direction = kDirDown;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_LEFT:
+ if (_direction != kDirLeft) {
+ _direction = kDirLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_RIGHT:
+ if (_direction != kDirRight) {
+ _direction = kDirRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_PAGEUP:
+ if (_direction != kDirUpRight) {
+ _direction = kDirUpRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ if (_direction != kDirDownRight) {
+ _direction = kDirDownRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_END:
+ if (_direction != kDirDownLeft) {
+ _direction = kDirDownLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_HOME:
+ if (_direction != kDirUpLeft) {
+ _direction = kDirUpLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_KP5:
+ stopWalking();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void Animation::setDirection(Direction dir) {
+ _direction = dir;
+}
+
+void Animation::setOldDirection(Direction dir) {
+ _oldDirection = dir;
+}
+
+Direction Animation::getDirection() {
+ return _direction;
+}
+
+Direction Animation::getOldDirection() {
+ return _oldDirection;
+}
+
+void Animation::setAvvyClothes(int id) {
+ AnimationType *spr = _sprites[0];
+ if (spr->_id == id)
+ return;
+
+ int16 x = spr->_x;
+ int16 y = spr->_y;
+ spr->remove();
+ spr->init(id, true);
+ spr->appear(x, y, kDirLeft);
+ spr->_visible = false;
+}
+
+int Animation::getAvvyClothes() {
+ return _sprites[0]->_id;
+}
+
+void Animation::resetVariables() {
+ _geidaSpin = 0;
+ _geidaTime = 0;
+ _arrowTriggered = false;
+}
+
+void Animation::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_direction);
+ sz.syncAsByte(_geidaSpin);
+ sz.syncAsByte(_geidaTime);
+
+ byte spriteNum = 0;
+ if (sz.isSaving()) {
+ for (int i = 0; i < kSpriteNumbMax; i++) {
+ if (_sprites[i]->_quick)
+ spriteNum++;
+ }
+ }
+ sz.syncAsByte(spriteNum);
+
+ if (sz.isLoading()) {
+ for (int i = 0; i < kSpriteNumbMax; i++) { // Deallocate sprites.
+ AnimationType *spr = _sprites[i];
+ if (spr->_quick)
+ spr->remove();
+ }
+ }
+
+ for (int i = 0; i < spriteNum; i++) {
+ AnimationType *spr = _sprites[i];
+ sz.syncAsByte(spr->_id);
+ sz.syncAsByte(spr->_doCheck);
+
+ if (sz.isLoading()) {
+ spr->_quick = true;
+ spr->init(spr->_id, spr->_doCheck);
+ }
+
+ sz.syncAsByte(spr->_moveX);
+ sz.syncAsByte(spr->_moveY);
+ sz.syncAsByte(spr->_facingDir);
+ sz.syncAsByte(spr->_stepNum);
+ sz.syncAsByte(spr->_visible);
+ sz.syncAsByte(spr->_homing);
+ sz.syncAsByte(spr->_count);
+ sz.syncAsByte(spr->_speedX);
+ sz.syncAsByte(spr->_speedY);
+ sz.syncAsByte(spr->_frameNum);
+ sz.syncAsSint16LE(spr->_homingX);
+ sz.syncAsSint16LE(spr->_homingY);
+ sz.syncAsByte(spr->_callEachStepFl);
+ sz.syncAsByte(spr->_eachStepProc);
+ sz.syncAsByte(spr->_vanishIfStill);
+ sz.syncAsSint16LE(spr->_x);
+ sz.syncAsSint16LE(spr->_y);
+
+ if (sz.isLoading() && spr->_visible)
+ spr->appear(spr->_x, spr->_y, spr->_facingDir);
+ }
+
+ sz.syncAsByte(_arrowTriggered);
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/animation.h b/engines/avalanche/animation.h
new file mode 100644
index 0000000000..cda5f05bd0
--- /dev/null
+++ b/engines/avalanche/animation.h
@@ -0,0 +1,171 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TRIP5 / Trippancy V - the sprite animation subsystem */
+
+#ifndef AVALANCHE_ANIMATION_H
+#define AVALANCHE_ANIMATION_H
+
+namespace Avalanche {
+class AvalancheEngine;
+class Animation;
+
+enum Direction {
+ kDirUp = 0, kDirRight, kDirDown, kDirLeft,
+ kDirUpRight, kDirDownRight, kDirDownLeft, kDirUpLeft,
+ kDirStopped, kDirNone = 177
+};
+
+class AnimationType {
+public:
+ byte _id;
+
+ byte _xLength, _yLength;
+ ManiType *_mani[24];
+ SilType *_sil[24];
+ byte _frameNum; // Number of pictures.
+ byte _seq; // How many in one stride.
+ byte _characterId; // The number according to Acci. (1=Avvy, etc.)
+ byte _count; // Counts before changing step.
+
+ Direction _facingDir;
+ byte _stepNum;
+ int16 _x, _y; // Current xy coords.
+ int8 _moveX, _moveY; // Amount to move sprite by, each step.
+ bool _quick, _visible, _homing, _doCheck;
+ int16 _homingX, _homingY; // Homing x & y coords.
+ byte _speedX, _speedY;
+ bool _vanishIfStill;
+ bool _callEachStepFl;
+ byte _eachStepProc;
+
+ AnimationType(Animation *anim);
+
+ void init(byte spritenum, bool doCheck);
+ void reset();
+ void draw();
+ void turn(Direction whichway);
+ void appear(int16 wx, int16 wy, Direction wf);
+ void bounce();
+ void walk();
+ void walkTo(byte pednum);
+ void stopHoming();
+ void setSpeed(int8 xx, int8 yy);
+ void stopWalk();
+ void chatter();
+ void remove();
+
+private:
+ Animation *_anim;
+
+ int16 _oldX[2], _oldY[2]; // Last xy coords.
+ Color _fgBubbleCol, _bgBubbleCol; // Foreground & background bubble colors.
+
+ bool checkCollision();
+ int8 getSign(int16 val);
+ void homeStep();
+};
+
+class Animation {
+public:
+ friend class AnimationType;
+
+ static const byte kSpriteNumbMax = 5; // current max no. of sprites
+
+ enum Proc {
+ kProcNone = 0,
+ kProcFollowAvvyY,
+ kProcBackAndForth,
+ kProcFaceAvvy,
+ kProcArrow,
+ kProcSpludwick, // Unused
+ kProcGrabAvvy,
+ kProcGeida // Spludwick uses it as well for homing! TODO: Unify it with kProcSpludwick.
+ };
+
+ AnimationType *_sprites[kSpriteNumbMax];
+
+ Animation(AvalancheEngine *vm);
+ ~Animation();
+
+ void animLink();
+ void resetAnims();
+ void callSpecial(uint16 which);
+ void catacombMove(byte ped);
+ void stopWalking();
+ void setMoveSpeed(byte t, Direction dir);
+ void appearPed(byte sprNum, byte pedNum);
+ bool inField(byte which);
+ bool nearDoor();
+ void updateSpeed();
+ void handleMoveKey(const Common::Event &event);
+ void hideInCupboard();
+
+ void setDirection(Direction dir);
+ void setOldDirection(Direction dir);
+ Direction getDirection();
+ Direction getOldDirection();
+
+ void setAvvyClothes(int id);
+ int getAvvyClothes();
+
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+private:
+ Direction _direction; // The direction Avvy is currently facing.
+ Direction _oldDirection;
+ static const int32 kCatacombMap[8][8];
+ bool _arrowTriggered; // And has the arrow been triggered?
+ bool _mustExclaim;
+ byte _geidaSpin, _geidaTime; // For the making "Geida dizzy" joke.
+ uint16 _sayWhat;
+
+ AvalancheEngine *_vm;
+
+ byte checkFeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl);
+ byte geidaPed(byte ped);
+ void dawnDelay();
+
+ void grabAvvy(byte tripnum);
+ void arrowProcs(byte tripnum);
+
+ // Different movements for NPCs:
+ void followAvalotY(byte tripnum);
+ void backAndForth(byte tripnum);
+ void faceAvvy(byte tripnum);
+
+ // Movements for Homing NPCs: Spludwick and Geida.
+ void spin(Direction dir, byte &tripnum);
+ void takeAStep(byte &tripnum);
+ void geidaProcs(byte tripnum);
+
+ void drawSprites();
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_ANIMATION_H
diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp
new file mode 100644
index 0000000000..2bb927646e
--- /dev/null
+++ b/engines/avalanche/avalanche.cpp
@@ -0,0 +1,629 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+
+#include "common/random.h"
+#include "common/savefile.h"
+#include "graphics/thumbnail.h"
+
+namespace Avalanche {
+
+AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription *gd) : Engine(syst), _gameDescription(gd), _fxHidden(false), _interrogation(0) {
+ _system = syst;
+ _console = new AvalancheConsole(this);
+
+ _rnd = new Common::RandomSource("avalanche");
+ TimeDate time;
+ _system->getTimeAndDate(time);
+ _rnd->setSeed(time.tm_sec + time.tm_min + time.tm_hour);
+ _showDebugLines = false;
+
+ _clock = nullptr;
+ _graphics = nullptr;
+ _parser = nullptr;
+ _pingo = nullptr;
+ _dialogs = nullptr;
+ _background = nullptr;
+ _sequence = nullptr;
+ _timer = nullptr;
+ _animation = nullptr;
+ _menu = nullptr;
+ _closing = nullptr;
+ _sound = nullptr;
+ _nim = nullptr;
+
+ _platform = gd->desc.platform;
+ initVariables();
+}
+
+AvalancheEngine::~AvalancheEngine() {
+ delete _console;
+ delete _rnd;
+
+ delete _graphics;
+ delete _parser;
+
+ delete _clock;
+ delete _pingo;
+ delete _dialogs;
+ delete _background;
+ delete _sequence;
+ delete _timer;
+ delete _animation;
+ delete _menu;
+ delete _closing;
+ delete _sound;
+ delete _nim;
+
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr) {
+ delete _also[i][j];
+ _also[i][j] = nullptr;
+ }
+ }
+ }
+}
+
+void AvalancheEngine::initVariables() {
+ for (int i = 0; i < 31; i++) {
+ _also[i][0] = nullptr;
+ _also[i][1] = nullptr;
+ }
+
+ memset(_fxPal, 0, 16 * 16 * 3);
+
+ for (int i = 0; i < 15; i++) {
+ _peds[i]._direction = kDirNone;
+ _peds[i]._x = 0;
+ _peds[i]._y = 0;
+ _magics[i]._operation = kMagicNothing;
+ _magics[i]._data = 0;
+ }
+
+ for (int i = 0; i < 7; i++) {
+ _portals[i]._operation = kMagicNothing;
+ _portals[i]._data = 0;
+ }
+
+ for (int i = 0; i < 30; i++) {
+ _fields[i]._x1 = 0;
+ _fields[i]._y1 = 0;
+ _fields[i]._x2 = 0;
+ _fields[i]._y2 = 0;
+ }
+
+ _fieldNum = 0;
+ _cp = 0;
+ _ledStatus = 177;
+ _alive = false;
+ _subjectNum = 0;
+ _him = kPeoplePardon;
+ _her = kPeoplePardon;
+ _it = Parser::kPardon;
+ _roomCycles = 0;
+ _doingSpriteRun = false;
+ _isLoaded = false;
+ _soundFx = true;
+ _holdTheDawn = false;
+
+ _lineNum = 0;
+ for (int i = 0; i < 50; i++)
+ _lines[i]._color = kColorWhite;
+ _dropsOk = false;
+ _cheat = false;
+ _letMeOut = false;
+ _thinks = 2;
+ _thinkThing = true;
+ _seeScroll = false;
+ _currentMouse = 177;
+ _holdLeftMouse = false;
+
+ _jumpStatus = 0;
+ _mushroomGrowing = false;
+ _crapulusWillTell = false;
+ _enterCatacombsFromLustiesRoom = false;
+ _teetotal = false;
+ _malagauche = 0;
+ _drinking = '\0';
+ _enteredLustiesRoomAsMonk = false;
+ _catacombX = 0;
+ _catacombY = 0;
+ _avvysInTheCupboard = false;
+ _geidaFollows = false;
+ _givenPotionToGeida = false;
+ _lustieIsAsleep = false;
+ _beenTiedUp = false;
+ _sittingInPub = false;
+ _spurgeTalkCount = 0;
+ _metAvaroid = false;
+ _takenMushroom = false;
+ _givenPenToAyles = false;
+ _askedDogfoodAboutNim = false;
+ _spludwickAtHome = false;
+ _passedCwytalotInHerts = false;
+ _lastRoom = _lastRoomNotMap = kRoomDummy;
+}
+
+Common::ErrorCode AvalancheEngine::initialize() {
+ _graphics = new GraphicManager(this);
+ _parser = new Parser(this);
+
+ _clock = new Clock(this);
+ _pingo = new Pingo(this);
+ _dialogs = new Dialogs(this);
+ _background = new Background(this);
+ _sequence = new Sequence(this);
+ _timer = new Timer(this);
+ _animation = new Animation(this);
+ _menu = new Menu(this);
+ _closing = new Closing(this);
+ _sound = new SoundHandler(this);
+ _nim = new Nim(this);
+
+ _graphics->init();
+ _dialogs->init();
+ init();
+ _parser->init();
+
+ return Common::kNoError;
+}
+
+GUI::Debugger *AvalancheEngine::getDebugger() {
+ return _console;
+}
+
+Common::Platform AvalancheEngine::getPlatform() const {
+ return _platform;
+}
+
+bool AvalancheEngine::hasFeature(EngineFeature f) const {
+ return (f == kSupportsSavingDuringRuntime) || (f == kSupportsLoadingDuringRuntime);
+}
+
+const char *AvalancheEngine::getCopyrightString() const {
+ return "Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.";
+}
+
+void AvalancheEngine::synchronize(Common::Serializer &sz) {
+ _animation->synchronize(sz);
+ _parser->synchronize(sz);
+ _nim->synchronize(sz);
+ _sequence->synchronize(sz);
+ _background->synchronize(sz);
+
+ sz.syncAsByte(_carryNum);
+ for (int i = 0; i < kObjectNum; i++)
+ sz.syncAsByte(_objects[i]);
+ sz.syncAsSint16LE(_dnascore);
+ sz.syncAsSint32LE(_money);
+ sz.syncAsByte(_room);
+ if (sz.isSaving())
+ _saveNum++;
+ sz.syncAsByte(_saveNum);
+ sz.syncBytes(_roomCount, 100);
+ sz.syncAsByte(_wonNim);
+ sz.syncAsByte(_wineState);
+ sz.syncAsByte(_cwytalotGone);
+ sz.syncAsByte(_passwordNum);
+ sz.syncAsByte(_aylesIsAwake);
+ sz.syncAsByte(_drawbridgeOpen);
+ sz.syncAsByte(_avariciusTalk);
+ sz.syncAsByte(_rottenOnion);
+ sz.syncAsByte(_onionInVinegar);
+ sz.syncAsByte(_givenToSpludwick);
+ sz.syncAsByte(_brummieStairs);
+ sz.syncAsByte(_cardiffQuestionNum);
+ sz.syncAsByte(_passedCwytalotInHerts);
+ sz.syncAsByte(_avvyIsAwake);
+ sz.syncAsByte(_avvyInBed);
+ sz.syncAsByte(_userMovesAvvy);
+ sz.syncAsByte(_npcFacing);
+ sz.syncAsByte(_givenBadgeToIby);
+ sz.syncAsByte(_friarWillTieYouUp);
+ sz.syncAsByte(_tiedUp);
+ sz.syncAsByte(_boxContent);
+ sz.syncAsByte(_talkedToCrapulus);
+ sz.syncAsByte(_jacquesState);
+ sz.syncAsByte(_bellsAreRinging);
+ sz.syncAsByte(_standingOnDais);
+ sz.syncAsByte(_takenPen);
+ sz.syncAsByte(_arrowInTheDoor);
+
+ if (sz.isSaving()) {
+ uint16 like2drinkSize = _favoriteDrink.size();
+ sz.syncAsUint16LE(like2drinkSize);
+ for (uint16 i = 0; i < like2drinkSize; i++) {
+ char actChr = _favoriteDrink[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 favoriteSongSize = _favoriteSong.size();
+ sz.syncAsUint16LE(favoriteSongSize);
+ for (uint16 i = 0; i < favoriteSongSize; i++) {
+ char actChr = _favoriteSong[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 worst_place_on_earthSize = _worstPlaceOnEarth.size();
+ sz.syncAsUint16LE(worst_place_on_earthSize);
+ for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
+ char actChr = _worstPlaceOnEarth[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 spare_eveningSize = _spareEvening.size();
+ sz.syncAsUint16LE(spare_eveningSize);
+ for (uint16 i = 0; i < spare_eveningSize; i++) {
+ char actChr = _spareEvening[i];
+ sz.syncAsByte(actChr);
+ }
+ } else {
+ if (!_favoriteDrink.empty())
+ _favoriteDrink.clear();
+ uint16 like2drinkSize = 0;
+ char actChr = ' ';
+ sz.syncAsUint16LE(like2drinkSize);
+ for (uint16 i = 0; i < like2drinkSize; i++) {
+ sz.syncAsByte(actChr);
+ _favoriteDrink += actChr;
+ }
+
+ if (!_favoriteSong.empty())
+ _favoriteSong.clear();
+ uint16 favourite_songSize = 0;
+ sz.syncAsUint16LE(favourite_songSize);
+ for (uint16 i = 0; i < favourite_songSize; i++) {
+ sz.syncAsByte(actChr);
+ _favoriteSong += actChr;
+ }
+
+ if (!_worstPlaceOnEarth.empty())
+ _worstPlaceOnEarth.clear();
+ uint16 worst_place_on_earthSize = 0;
+ sz.syncAsUint16LE(worst_place_on_earthSize);
+ for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
+ sz.syncAsByte(actChr);
+ _worstPlaceOnEarth += actChr;
+ }
+
+ if (!_spareEvening.empty())
+ _spareEvening.clear();
+ uint16 spare_eveningSize = 0;
+ sz.syncAsUint16LE(spare_eveningSize);
+ for (uint16 i = 0; i < spare_eveningSize; i++) {
+ sz.syncAsByte(actChr);
+ _spareEvening += actChr;
+ }
+ }
+
+ sz.syncAsSint32LE(_totalTime);
+ sz.syncAsByte(_jumpStatus);
+ sz.syncAsByte(_mushroomGrowing);
+ sz.syncAsByte(_spludwickAtHome);
+ sz.syncAsByte(_lastRoom);
+ sz.syncAsByte(_lastRoomNotMap);
+ sz.syncAsByte(_crapulusWillTell);
+ sz.syncAsByte(_enterCatacombsFromLustiesRoom);
+ sz.syncAsByte(_teetotal);
+ sz.syncAsByte(_malagauche);
+ sz.syncAsByte(_drinking);
+ sz.syncAsByte(_enteredLustiesRoomAsMonk);
+ sz.syncAsByte(_catacombX);
+ sz.syncAsByte(_catacombY);
+ sz.syncAsByte(_avvysInTheCupboard);
+ sz.syncAsByte(_geidaFollows);
+ sz.syncAsByte(_givenPotionToGeida);
+ sz.syncAsByte(_lustieIsAsleep);
+ sz.syncAsByte(_beenTiedUp);
+ sz.syncAsByte(_sittingInPub);
+ sz.syncAsByte(_spurgeTalkCount);
+ sz.syncAsByte(_metAvaroid);
+ sz.syncAsByte(_takenMushroom);
+ sz.syncAsByte(_givenPenToAyles);
+ sz.syncAsByte(_askedDogfoodAboutNim);
+
+ for (int i = 0; i < 7; i++) {
+ sz.syncAsSint32LE(_timer->_times[i]._timeLeft);
+ sz.syncAsByte(_timer->_times[i]._action);
+ sz.syncAsByte(_timer->_times[i]._reason);
+ }
+
+}
+
+bool AvalancheEngine::canSaveGameStateCurrently() { // TODO: Refine these!!!
+ return (!_seeScroll && _alive);
+}
+
+Common::Error AvalancheEngine::saveGameState(int slot, const Common::String &desc) {
+ return (saveGame(slot, desc) ? Common::kNoError : Common::kWritingFailed);
+}
+
+bool AvalancheEngine::saveGame(const int16 slot, const Common::String &desc) {
+ Common::String fileName = getSaveFileName(slot);
+ Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(fileName);
+ if (!f) {
+ warning("Can't create file '%s', game not saved.", fileName.c_str());
+ return false;
+ }
+
+ f->writeUint32LE(MKTAG('A', 'V', 'A', 'L'));
+
+ // Write version. We can't restore from obsolete versions.
+ f->writeByte(kSavegameVersion);
+
+ f->writeUint32LE(desc.size());
+ f->write(desc.c_str(), desc.size());
+ Graphics::saveThumbnail(*f);
+
+ TimeDate t;
+ _system->getTimeAndDate(t);
+ f->writeSint16LE(t.tm_mday);
+ f->writeSint16LE(t.tm_mon);
+ f->writeSint16LE(t.tm_year);
+
+ _totalTime += getTimeInSeconds() - _startTime;
+
+ Common::Serializer sz(NULL, f);
+ synchronize(sz);
+ f->finalize();
+ delete f;
+
+ return true;
+}
+
+Common::String AvalancheEngine::getSaveFileName(const int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+bool AvalancheEngine::canLoadGameStateCurrently() { // TODO: Refine these!!!
+ return (!_seeScroll);
+}
+
+Common::Error AvalancheEngine::loadGameState(int slot) {
+ return (loadGame(slot) ? Common::kNoError : Common::kReadingFailed);
+}
+
+bool AvalancheEngine::loadGame(const int16 slot) {
+ Common::String fileName = getSaveFileName(slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+ if (!f)
+ return false;
+
+ uint32 signature = f->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L'))
+ return false;
+
+ // Check version. We can't restore from obsolete versions.
+ byte saveVersion = f->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of incompatible version!");
+ delete f;
+ return false;
+ }
+
+ // Read the description.
+ uint32 descSize = f->readUint32LE();
+ Common::String description;
+ for (uint32 i = 0; i < descSize; i++) {
+ char actChar = f->readByte();
+ description += actChar;
+ }
+
+ description.toUppercase();
+ Graphics::skipThumbnail(*f);
+
+ // Read the time the game was saved.
+ TimeDate t;
+ t.tm_mday = f->readSint16LE();
+ t.tm_mon = f->readSint16LE();
+ t.tm_year = f->readSint16LE();
+
+ resetVariables();
+
+ Common::Serializer sz(f, NULL);
+ synchronize(sz);
+ delete f;
+
+ _isLoaded = true;
+
+ _seeScroll = true; // This prevents display of the new sprites before the new picture is loaded.
+
+ if (_holdTheDawn) {
+ _holdTheDawn = false;
+ fadeIn();
+ }
+
+ _background->release();
+ minorRedraw();
+ _menu->setup();
+ setRoom(kPeopleAvalot, _room);
+ _alive = true;
+ refreshObjectList();
+ _animation->updateSpeed();
+ drawDirection();
+ _animation->animLink();
+ _background->update();
+
+ Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.",
+ kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine,
+ kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine,
+ expandDate(t.tm_mday, t.tm_mon, t.tm_year).c_str());
+ _dialogs->displayText(tmpStr);
+
+ AnimationType *avvy = _animation->_sprites[0];
+ if (avvy->_quick && avvy->_visible)
+ _animation->setMoveSpeed(0, _animation->getDirection()); // We push Avvy in the right direction is he was moving.
+
+ return true;
+}
+
+Common::String AvalancheEngine::expandDate(int d, int m, int y) {
+ static const char months[12][10] = {
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+ };
+
+ Common::String month = Common::String(months[m]);
+ Common::String day = intToStr(d);
+
+ if (((1 <= d) && (d <= 9)) || ((21 <= d) && (d <= 31)))
+ switch (d % 10) {
+ case 1:
+ day += "st";
+ break;
+ case 2:
+ day += "nd";
+ break;
+ case 3:
+ day += "rd";
+ break;
+ default:
+ day += "th";
+ }
+
+ return day + ' ' + month + ' ' + intToStr(y + 1900);
+}
+
+uint32 AvalancheEngine::getTimeInSeconds() {
+ TimeDate time;
+ _system->getTimeAndDate(time);
+ return time.tm_hour * 3600 + time.tm_min * 60 + time.tm_sec;
+}
+
+void AvalancheEngine::updateEvents() {
+ Common::Event event;
+
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ _holdLeftMouse = true; // Used in checkclick() and Menu::menu_link().
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _holdLeftMouse = false; // Same as above.
+ break;
+ case Common::EVENT_KEYDOWN:
+ if ((event.kbd.keycode == Common::KEYCODE_d) && (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _console->attach();
+ _console->onFrame();
+ } else
+ handleKeyDown(event);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool AvalancheEngine::getEvent(Common::Event &event) {
+ return _eventMan->pollEvent(event);
+}
+
+Common::Point AvalancheEngine::getMousePos() {
+ return _eventMan->getMousePos();
+}
+
+Common::Error AvalancheEngine::run() {
+ Common::ErrorCode err = initialize();
+ if (err != Common::kNoError)
+ return err;
+
+ do {
+ runAvalot();
+
+#if 0
+ switch (_storage._operation) {
+ case kRunShootemup:
+ run("seu.avx", kJsb, kBflight, kNormal);
+ break;
+ case kRunDosshell:
+ dosShell();
+ break;
+ case kRunGhostroom:
+ run("g-room.avx", kJsb, kNoBflight, kNormal);
+ break;
+ case kRunGolden:
+ run("golden.avx", kJsb, kBflight, kMusical);
+ break;
+ }
+#endif
+
+ } while (!_letMeOut && !shouldQuit());
+
+ return Common::kNoError;
+}
+
+#if 0
+void AvalancheEngine::run(Common::String what, bool withJsb, bool withBflight, Elm how) {
+ // Probably there'll be no need of this function, as all *.AVX-es will become classes.
+ warning("STUB: run(%s)", what.c_str());
+}
+
+Common::String AvalancheEngine::elmToStr(Elm how) {
+ switch (how) {
+ case kNormal:
+ case kMusical:
+ return Common::String("jsb");
+ case kRegi:
+ return Common::String("REGI");
+ case kElmpoyten:
+ return Common::String("ELMPOYTEN");
+ // Useless, but silent a warning
+ default:
+ return Common::String("");
+ }
+}
+
+// Same as keypressed1().
+void AvalancheEngine::flushBuffer() {
+ warning("STUB: flushBuffer()");
+}
+
+void AvalancheEngine::dosShell() {
+ warning("STUB: dosShell()");
+}
+
+// Needed in dos_shell(). TODO: Remove later.
+Common::String AvalancheEngine::commandCom() {
+ warning("STUB: commandCom()");
+ return ("STUB: commandCom()");
+}
+
+// Needed for run_avalot()'s errors. TODO: Remove later.
+void AvalancheEngine::explain(byte error) {
+ warning("STUB: explain()");
+}
+
+// Needed later.
+void AvalancheEngine::quit() {
+ cursorOn();
+}
+
+#endif
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/avalanche.h b/engines/avalanche/avalanche.h
new file mode 100644
index 0000000000..87eb3c2158
--- /dev/null
+++ b/engines/avalanche/avalanche.h
@@ -0,0 +1,348 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_AVALANCHE_H
+#define AVALANCHE_AVALANCHE_H
+
+#include "avalanche/console.h"
+#include "avalanche/graphics.h"
+#include "avalanche/parser.h"
+#include "avalanche/avalot.h"
+#include "avalanche/pingo.h"
+#include "avalanche/dialogs.h"
+#include "avalanche/background.h"
+#include "avalanche/sequence.h"
+#include "avalanche/timer.h"
+#include "avalanche/animation.h"
+#include "avalanche/menu.h"
+#include "avalanche/closing.h"
+#include "avalanche/sound.h"
+#include "avalanche/nim.h"
+
+#include "common/serializer.h"
+
+#include "engines/engine.h"
+#include "engines/advancedDetector.h"
+
+#include "graphics/cursorman.h"
+
+namespace Common {
+class RandomSource;
+}
+
+namespace Avalanche {
+
+struct AvalancheGameDescription {
+ ADGameDescription desc;
+};
+
+static const int kSavegameVersion = 2;
+
+enum Pitch {
+ kPitchInvalid,
+ kPitchLower,
+ kPitchSame,
+ kPitchHigher
+};
+
+class AvalancheEngine : public Engine {
+public:
+ byte _saveNum; // number of times this game has been saved
+
+ Clock *_clock;
+ GraphicManager *_graphics;
+ Parser *_parser;
+ Pingo *_pingo;
+ Dialogs *_dialogs;
+ Background *_background;
+ Sequence *_sequence;
+ Timer *_timer;
+ Animation *_animation;
+ Menu *_menu;
+ Closing *_closing;
+ SoundHandler *_sound;
+ Nim *_nim;
+
+ OSystem *_system;
+
+ AvalancheEngine(OSystem *syst, const AvalancheGameDescription *gd);
+ ~AvalancheEngine();
+
+ Common::ErrorCode initialize();
+ GUI::Debugger *getDebugger();
+
+ Common::RandomSource *_rnd;
+
+ const AvalancheGameDescription *_gameDescription;
+ uint32 getFeatures() const;
+ const char *getGameId() const;
+ Common::Platform getPlatform() const;
+ bool hasFeature(EngineFeature f) const;
+ const char *getCopyrightString() const;
+
+ void synchronize(Common::Serializer &sz);
+ virtual bool canSaveGameStateCurrently();
+ Common::Error saveGameState(int slot, const Common::String &desc);
+ bool saveGame(const int16 slot, const Common::String &desc);
+ Common::String getSaveFileName(const int slot);
+ virtual bool canLoadGameStateCurrently();
+ Common::Error loadGameState(int slot);
+ bool loadGame(const int16 slot);
+ Common::String expandDate(int d, int m, int y);
+ uint32 getTimeInSeconds();
+
+ void updateEvents();
+ bool getEvent(Common::Event &event); // A wrapper around _eventMan->pollEvent(), so we can use it in Scrolls::normscroll() for example.
+ Common::Point getMousePos();
+
+protected:
+ // Engine APIs
+ Common::Error run();
+
+private:
+ AvalancheConsole *_console;
+ Common::Platform _platform;
+
+#if 0
+ struct {
+ byte _operation;
+ uint16 _skellern;
+ byte _contents[1000];
+ } _storage;
+
+ static const int16 kRunShootemup = 1, kRunDosshell = 2, kRunGhostroom = 3, kRunGolden = 4;
+ static const int16 kReset = 0;
+
+ static const bool kJsb = true, kNoJsb = false, kBflight = true, kNoBflight = false;
+
+ // From bootstrp:
+ enum Elm {kNormal, kMusical, kElmpoyten, kRegi};
+
+ Common::String _argsWithNoFilename;
+ byte _originalMode;
+ byte *_old1c;
+ Common::String _segofs;
+ int32 _soundcard, _speed, _baseaddr, _irq, _dma;
+ bool _zoomy;
+
+ void run(Common::String what, bool withJsb, bool withBflight, Elm how);
+ void bFlightOn();
+ void bFlightOff();
+ Common::String elmToStr(Elm how);
+ bool keyPressed();
+ void flushBuffer();
+ void dosShell();
+ void bFlight();
+ Common::String commandCom();
+ void explain(byte error);
+ void cursorOff();
+ void cursorOn();
+ void quit();
+#endif
+
+public:
+ // For Thinkabout:
+ static const bool kThing = true;
+ static const bool kPerson = false;
+
+ static const char kSpludwicksOrder[3];
+
+ static const uint16 kNotes[12];
+ static const TuneType kTune;
+
+ bool _holdLeftMouse;
+
+ // If this is greater than zero, the next line you type is stored in the DNA in a position dictated by the value.
+ // If a scroll comes up, or you leave the room, it's automatically set to zero.
+ byte _interrogation;
+
+ // Former DNA structure
+ byte _carryNum; // How many objects you're carrying...
+ bool _objects[kObjectNum]; // ...and which ones they are.
+ int16 _dnascore; // your score, of course
+ int32 _money; // your current amount of dosh
+ Room _room; // your current room
+ bool _wonNim; // Have you *won* Nim? (That's harder.)
+ byte _wineState; // 0=good (Notts), 1=passable(Argent) ... 3=vinegar.
+ bool _cwytalotGone; // Has Cwytalot rushed off to Jerusalem yet?
+ byte _passwordNum; // Number of the passw for this game.
+ bool _aylesIsAwake; // pretty obvious!
+ byte _drawbridgeOpen; // Between 0 (shut) and 4 (open).
+ byte _avariciusTalk; // How much Avaricius has said to you.
+ bool _rottenOnion; // And has it rotted?
+ bool _onionInVinegar; // Is the onion in the vinegar?
+ byte _givenToSpludwick; // 0 = nothing given, 1 = onion...
+ byte _brummieStairs; // Progression through the stairs trick.
+ byte _cardiffQuestionNum; // Things you get asked in Cardiff.
+ bool _avvyIsAwake; // Well? Is Avvy awake? (Screen 1 only.)
+ bool _avvyInBed; // True if Avvy's in bed, but awake.
+ bool _userMovesAvvy; // If this is false, the user has no control over Avvy's movements.
+ byte _npcFacing; // If there's an NPC in the current room which turns it's head according to Avvy's movement (keep looking at him), this variable tells which way it's facing at the moment.
+ bool _givenBadgeToIby; // Have you given the badge to Iby yet?
+ bool _friarWillTieYouUp; // If you're going to get tied up.
+ bool _tiedUp; // You ARE tied up!
+ byte _boxContent; // 0 = money (sixpence), 254 = empty, any other number implies the contents of the box.
+ bool _talkedToCrapulus; // Pretty self-explanatory.
+ byte _jacquesState; // 0=asleep, 1=awake, 2=gets up, 3=gone.
+ bool _bellsAreRinging; // Is Jacques ringing the bells?
+ bool _standingOnDais; // In room 71, inside Cardiff Castle.
+ bool _takenPen; // Have you taken the pen (in Cardiff?)
+ bool _arrowInTheDoor; // Did the arrow hit the wall?
+ Common::String _favoriteDrink, _favoriteSong, _worstPlaceOnEarth, _spareEvening; // Personalisation str's
+ uint32 _startTime; // When did you start playing this session?
+ uint32 _totalTime; // Your total time playing this game, in seconds. Updated only at saving and loading.
+ byte _jumpStatus; // Fixes how high you're jumping.
+ bool _mushroomGrowing; // Is the mushroom growing in 42?
+ bool _crapulusWillTell; // Will Crapulus tell you about Spludwick being away?
+ bool _enterCatacombsFromLustiesRoom;
+ bool _teetotal; // Are we touching any more drinks?
+ byte _malagauche; // Position of Malagauche. See Celer for more info.
+ char _drinking; // What's he getting you?
+ bool _enteredLustiesRoomAsMonk;
+ byte _catacombX, _catacombY; // XY coords in the catacombs.
+ bool _avvysInTheCupboard; // On screen 22.
+ bool _geidaFollows; // Is Geida following you?
+ bool _givenPotionToGeida; // Does Geida have the potion?
+ bool _lustieIsAsleep; // Is BDL asleep?
+ bool _beenTiedUp; // In r__Robins.
+ bool _sittingInPub; // Are you sitting down in the pub?
+ byte _spurgeTalkCount; // Count for talking to Spurge.
+ bool _metAvaroid;
+ bool _takenMushroom, _givenPenToAyles, _askedDogfoodAboutNim;
+ // End of former DNA Structure
+
+ bool _showDebugLines;
+ byte _lineNum; // Number of lines.
+ LineType _lines[50]; // For Also.
+ bool _dropsOk;
+ bool _cheat; // CHECKME: Currently unused
+ bool _letMeOut;
+ byte _thinks;
+ bool _thinkThing;
+ bool _seeScroll; // TODO: maybe this means we're interacting with the toolbar / a scroll?
+ char _objectList[10];
+ // Called .free() for them in ~Gyro().
+
+ byte _currentMouse; // current mouse-void
+ Common::String *_also[31][2];
+ PedType _peds[15];
+ MagicType _magics[15];
+ MagicType _portals[7];
+ FieldType _fields[30];
+ byte _fieldNum;
+ Common::String _listen;
+ byte _cp, _ledStatus;
+ FontType _font;
+ bool _alive;
+ byte _subjectNum; // The same thing.
+ People _him, _her;
+ byte _it;
+ uint32 _roomCycles; // Set to 0 when you enter a room, added to in every loop. Cycles since you've been in this room.
+
+ bool _doingSpriteRun; // Only set to True if we're doing a sprite_run at this moment. This stops the trippancy system from moving any of the sprites.
+ bool _soundFx;
+
+ bool _isLoaded; // Is it a loaded gamestate?
+
+ void callVerb(VerbCode id);
+ void loadRoom(byte num);
+ void thinkAbout(byte object, bool type); // Hey!!! Get it and put it!!!
+ void incScore(byte num); // Add on no. of points
+ void fxToggle();
+ void refreshObjectList();
+ void errorLed();
+ void fadeOut();
+ void fadeIn();
+ void drawDirection(); // Draws the little icon at the left end of the text input field.
+ void gameOver();
+ uint16 bearing(byte whichPed); // Returns the bearing from ped 'whichped' to Avvy, in degrees.
+
+ // There are two kinds of redraw: Major and Minor. Minor is what happens when you load a game, etc. Major redraws EVERYTHING.
+ void minorRedraw();
+ void majorRedraw();
+
+ void spriteRun();
+
+ Common::String intToStr(int32 num);
+ void newGame(); // This sets up the DNA for a completely new game.
+ bool getFlag(char x);
+ bool decreaseMoney(uint16 amount); // Called pennycheck in the original.
+
+ Common::String getName(People whose);
+ Common::String getItem(byte which); // Called get_better in the original.
+ Common::String f5Does(); // This procedure determines what f5 does.
+
+ void openDoor(Room whither, byte ped, byte magicnum); // Handles slidey-open doors.
+ void flipRoom(Room room, byte ped);
+
+ void setRoom(People persId, Room roomId);
+ Room getRoom(People persId);
+private:
+ static const int16 kMaxSprites = 2; // Current max no. of sprites.
+ static Room _whereIs[29];
+
+ // Will be used in dusk() and dawn().
+ bool _fxHidden;
+ byte _fxPal[16][16][3];
+
+ bool _spludwickAtHome; // Is Spludwick at home?
+ bool _passedCwytalotInHerts; // Have you passed Cwytalot in Herts?
+ bool _holdTheDawn; // If this is true, calling Dawn will do nothing. It's used, for example, at the start, to stop Load from dawning.
+ byte _lastRoom;
+ byte _lastRoomNotMap;
+ byte _roomCount[100]; // Add one to each every time you enter a room
+ Common::String _mouseText;
+ Common::String _flags;
+ Common::String _roomnName; // Name of actual room
+ int8 _scoreToDisplay[3];
+
+ Common::String readAlsoStringFromFile(Common::File &file);
+ void runAvalot();
+ void init();
+ void initVariables();
+ void setup();
+ void scram(Common::String &str);
+ void unScramble();
+ void handleKeyDown(Common::Event &event); // To replace Basher::keyboard_link() and Basher::typein().
+ void enterNewTown();
+ void findPeople(byte room);
+ void putGeidaAt(byte whichPed, byte ped);
+ void guideAvvy(Common::Point cursorPos);
+ void enterRoom(Room room, byte ped);
+ void exitRoom(byte x);
+ void drawToolbar();
+ void drawScore();
+ void useCompass(const Common::Point &cursorPos); // Click on the compass on the toolbar to control Avvy's movement.
+ void checkClick();
+ void fixFlashers();
+ void loadAlso(byte num);
+ void resetVariables();
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_AVALANCHE_H
diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp
new file mode 100644
index 0000000000..ec3f81e55d
--- /dev/null
+++ b/engines/avalanche/avalot.cpp
@@ -0,0 +1,1755 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+ */
+
+/* AVALOT The kernel of the program. */
+
+#include "avalanche/avalanche.h"
+
+#include "common/random.h"
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "graphics/palette.h"
+
+namespace Avalanche {
+
+// vv Stairs trap.
+
+/* Explanation: $NSEW.
+ Nibble N: North.
+ 0 = no connection,
+ 2 = (left,) middle(, right) door with left-hand handle,
+ 5 = (left,) middle(, right) door with right-hand handle,
+ 7 = arch,
+ 8 = arch and 1 north of it,
+ 9 = arch and 2 north of it,
+ D = no connection + WINDOW,
+ E = no connection + TORCH,
+ F = recessed door (to Geida's room.)
+
+ Nibble S: South.
+ 0 = no connection,
+ 1,2,3 = left, middle, right door.
+
+ Nibble E: East.
+ 0 = no connection (wall),
+ 1 = no connection (wall + window),
+ 2 = wall with door,
+ 3 = wall with door and window,
+ 6 = wall with candles,
+ 7 = wall with door and candles,
+ F = straight-through corridor.
+
+ Nibble W: West.
+ 0 = no connection (wall),
+ 1 = no connection (wall + shield),
+ 2 = wall with door,
+ 3 = wall with door and shield,
+ 4 = no connection (window),
+ 5 = wall with door and window,
+ 6 = wall with candles,
+ 7 = wall with door and candles,
+ F = straight-through corridor. */
+
+const char AvalancheEngine::kSpludwicksOrder[3] = {kObjectOnion, kObjectInk, kObjectMushroom};
+const uint16 AvalancheEngine::kNotes[12] = {196, 220, 247, 262, 294, 330, 350, 392, 440, 494, 523, 587};
+const TuneType AvalancheEngine::kTune = {
+ kPitchHigher, kPitchHigher, kPitchLower, kPitchSame, kPitchHigher, kPitchHigher, kPitchLower, kPitchHigher, kPitchHigher, kPitchHigher,
+ kPitchLower, kPitchHigher, kPitchHigher, kPitchSame, kPitchHigher, kPitchLower, kPitchLower, kPitchLower, kPitchLower, kPitchHigher,
+ kPitchHigher, kPitchLower, kPitchLower, kPitchLower, kPitchLower, kPitchSame, kPitchLower, kPitchHigher, kPitchSame, kPitchLower, kPitchHigher
+};
+
+Room AvalancheEngine::_whereIs[29] = {
+ // The Lads
+ kRoomYours, // Avvy
+ kRoomSpludwicks, // Spludwick
+ kRoomOutsideYours, // Crapulus
+ kRoomDucks, // Duck - r__DucksRoom's not defined yet.
+ kRoomArgentPub, // Malagauche
+ kRoomRobins, // Friar Tuck.
+ kRoomDummy, // Robin Hood - can't meet him at the start.
+ kRoomBrummieRoad, // Cwytalot
+ kRoomLustiesRoom, // Baron du Lustie.
+ kRoomOutsideCardiffCastle, // The Duke of Cardiff.
+ kRoomArgentPub, // Dogfood
+ kRoomOutsideDucks, // Trader
+ kRoomArgentPub, // Ibythneth
+ kRoomAylesOffice, // Ayles
+ kRoomNottsPub, // Port
+ kRoomNottsPub, // Spurge
+ kRoomMusicRoom, // Jacques
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ // The Lasses
+ kRoomYours, // Arkata
+ kRoomGeidas, // Geida
+ kRoomDummy, // nobody allocated here!
+ kRoomWiseWomans // The Wise Woman.
+};
+
+Clock::Clock(AvalancheEngine *vm) {
+ _vm = vm;
+ // Magic value to determine if we just created the instance
+ _oldHour = _oldHourAngle = _oldMinute = 17717;
+ _hour = _minute = _second = 0;
+ _hourAngle = 0;
+}
+
+void Clock::update() {
+ TimeDate t;
+ _vm->_system->getTimeAndDate(t);
+ _hour = t.tm_hour;
+ _minute = t.tm_min;
+ _second = t.tm_sec;
+
+ _hourAngle = (_hour % 12) * 30 + _minute / 2;
+
+ if (_oldHour != _hour) {
+ plotHands();
+ chime();
+ }
+
+ if (_oldMinute != _minute)
+ plotHands();
+
+ if ((_hour == 0) && (_oldHour != 0) && (_oldHour != 17717)) {
+ Common::String tmpStr = Common::String::format("Good morning!%c%cYes, it's just past " \
+ "midnight. Are you having an all-night Avvy session? Glad you like the game that much!",
+ kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ _oldHour = _hour;
+ _oldHourAngle = _hourAngle;
+ _oldMinute = _minute;
+}
+
+Common::Point Clock::calcHand(uint16 angle, uint16 length, Color color) {
+ if (angle > 900) {
+ return(Common::Point(177, 177));
+ }
+
+ return(_vm->_graphics->drawScreenArc(kCenterX, kCenterY, 449 - angle, 450 - angle, length, color));
+}
+
+void Clock::drawHand(const Common::Point &endPoint, Color color) {
+ if (endPoint.x == 177)
+ return;
+
+ _vm->_graphics->drawScreenLine(kCenterX, kCenterY, endPoint.x, endPoint.y, color);
+}
+
+void Clock::plotHands() {
+ _clockHandHour = calcHand(_oldHourAngle, 14, kColorYellow);
+ _clockHandMinute = calcHand(_oldMinute * 6, 17, kColorYellow);
+ drawHand(_clockHandHour, kColorBrown);
+ drawHand(_clockHandMinute, kColorBrown);
+
+ _clockHandHour = calcHand(_hourAngle, 14, kColorBrown);
+ _clockHandMinute = calcHand(_minute * 6, 17, kColorBrown);
+ drawHand(_clockHandHour, kColorYellow);
+ drawHand(_clockHandMinute, kColorYellow);
+}
+
+void Clock::chime() {
+ // Too high - must be first time around
+ // Mute - skip the sound generation
+ if ((_oldHour == 17717) || (!_vm->_soundFx))
+ return;
+
+ byte hour = _hour % 12;
+ if (hour == 0)
+ hour = 12;
+
+ _vm->_graphics->loadMouse(kCurWait);
+
+ for (int i = 1; i <= hour; i++) {
+ for (int j = 1; j <= 3; j++)
+ _vm->_sound->playNote((i % 3) * 64 + 140 - j * 30, 50 - j * 12);
+ if (i != hour)
+ _vm->_system->delayMillis(100);
+ }
+}
+
+void AvalancheEngine::handleKeyDown(Common::Event &event) {
+ _sound->click();
+
+ if ((Common::KEYCODE_F1 <= event.kbd.keycode) && (event.kbd.keycode <= Common::KEYCODE_F15))
+ _parser->handleFunctionKey(event);
+ else if ((32 <= event.kbd.ascii) && (event.kbd.ascii <= 128) && (event.kbd.ascii != 47))
+ _parser->handleInputText(event);
+ else
+ switch (event.kbd.keycode) { // We can control Avvy with the numpad as well.
+ case Common::KEYCODE_KP8:
+ event.kbd.keycode = Common::KEYCODE_UP;
+ break;
+ case Common::KEYCODE_KP2:
+ event.kbd.keycode = Common::KEYCODE_DOWN;
+ break;
+ case Common::KEYCODE_KP6:
+ event.kbd.keycode = Common::KEYCODE_RIGHT;
+ break;
+ case Common::KEYCODE_KP4:
+ event.kbd.keycode = Common::KEYCODE_LEFT;
+ break;
+ case Common::KEYCODE_KP9:
+ event.kbd.keycode = Common::KEYCODE_PAGEUP;
+ break;
+ case Common::KEYCODE_KP3:
+ event.kbd.keycode = Common::KEYCODE_PAGEDOWN;
+ break;
+ case Common::KEYCODE_KP7:
+ event.kbd.keycode = Common::KEYCODE_HOME;
+ break;
+ case Common::KEYCODE_KP1:
+ event.kbd.keycode = Common::KEYCODE_END;
+ break;
+ default:
+ break;
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_PAGEUP:
+ case Common::KEYCODE_PAGEDOWN:
+ case Common::KEYCODE_HOME:
+ case Common::KEYCODE_END:
+ case Common::KEYCODE_KP5:
+ if (_alive && _avvyIsAwake) {
+ _animation->handleMoveKey(event); // Fallthroughs are intended.
+ drawDirection();
+ return;
+ }
+ case Common::KEYCODE_BACKSPACE:
+ _parser->handleBackspace();
+ break;
+ case Common::KEYCODE_RETURN:
+ _parser->handleReturn();
+ break;
+ default:
+ break;
+ }
+
+ drawDirection();
+}
+
+void AvalancheEngine::setup() {
+ init();
+
+ _dialogs->reset();
+ fadeOut();
+ _graphics->loadDigits();
+
+ _parser->_inputTextPos = 0;
+ _parser->_quote = true;
+
+ _animation->resetAnims();
+
+ drawToolbar();
+ _dialogs->setReadyLight(2);
+
+ fadeIn();
+ _parser->_cursorState = false;
+ _parser->cursorOn();
+ _animation->_sprites[0]->_speedX = kWalk;
+ _animation->updateSpeed();
+
+ _menu->init();
+
+ int16 loadSlot = ConfMan.instance().getInt("save_slot");
+ if (loadSlot >= 0) {
+ _thinks = 2; // You always have money.
+ thinkAbout(kObjectMoney, kThing);
+
+ loadGame(loadSlot);
+ } else {
+ newGame();
+
+ _soundFx = !_soundFx;
+ fxToggle();
+ thinkAbout(kObjectMoney, kThing);
+
+ _dialogs->displayScrollChain('Q', 83); // Info on the game, etc.
+ }
+}
+
+void AvalancheEngine::runAvalot() {
+ setup();
+
+ do {
+ uint32 beginLoop = _system->getMillis();
+
+ updateEvents(); // The event handler.
+
+ _clock->update();
+ _menu->update();
+ _background->update();
+ _animation->animLink();
+ checkClick();
+ _timer->updateTimer();
+
+ _graphics->drawDebugLines();
+ _graphics->refreshScreen();
+
+ uint32 delay = _system->getMillis() - beginLoop;
+ if (delay <= 55)
+ _system->delayMillis(55 - delay); // Replaces slowdown(); 55 comes from 18.2 Hz (B Flight).
+ } while (!_letMeOut && !shouldQuit());
+
+ warning("STUB: run()");
+
+ _closing->exitGame();
+}
+
+void AvalancheEngine::init() {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++)
+ _also[i][j] = nullptr;
+ }
+
+#if 0
+ if (_vm->_enhanced->atbios)
+ atkey = "f1";
+ else
+ atkey = "alt-";
+#endif
+
+ _letMeOut = false;
+ _currentMouse = 177;
+ _dropsOk = true;
+ _mouseText = "";
+ _cheat = false;
+ _cp = 0;
+ _ledStatus = 177;
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = -1; // Impossible digits.
+ _holdTheDawn = false;
+
+ _graphics->loadMouse(kCurWait);
+ CursorMan.showMouse(true);
+}
+
+/**
+ * Call a given Verb
+ * @remarks Originally called 'callverb'
+ */
+void AvalancheEngine::callVerb(VerbCode id) {
+ if (id == _parser->kPardon) {
+ Common::String tmpStr = Common::String::format("The f5 key lets you do a particular action in certain " \
+ "situations. However, at the moment there is nothing assigned to it. You may press alt-A to see " \
+ "what the current setting of this key is.");
+ _dialogs->displayText(tmpStr);
+ } else
+ _parser->doVerb(id);
+}
+
+/**
+ * Check is it's possible to give something to Spludwick
+ * @remarks Originally called 'nextstring'
+ */
+Common::String AvalancheEngine::readAlsoStringFromFile(Common::File &file) {
+ Common::String str;
+ byte length = file.readByte();
+ for (int i = 0; i < length; i++)
+ str += file.readByte();
+ return str;
+}
+
+void AvalancheEngine::scram(Common::String &str) {
+ for (uint i = 0; i < str.size(); i++)
+ str.setChar(str[i] ^ 177, i);
+}
+
+void AvalancheEngine::unScramble() {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr)
+ scram(*_also[i][j]);
+ }
+ }
+ scram(_listen);
+ scram(_flags);
+}
+
+void AvalancheEngine::loadAlso(byte num) {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr) {
+ delete _also[i][j];
+ _also[i][j] = nullptr;
+ }
+ }
+ }
+ Common::String filename;
+ filename = Common::String::format("also%d.avd", num);
+ Common::File file;
+ if (!file.open(filename))
+ error("AVALANCHE: File not found: %s", filename.c_str());
+
+ file.seek(128);
+
+ byte alsoNum = file.readByte();
+ Common::String tmpStr;
+ for (int i = 0; i <= alsoNum; i++) {
+ for (int j = 0; j < 2; j++) {
+ _also[i][j] = new Common::String;
+ *_also[i][j] = readAlsoStringFromFile(file);
+ }
+ tmpStr = Common::String::format("\x9D%s\x9D", _also[i][0]->c_str());
+ *_also[i][0] = tmpStr;
+ }
+
+ memset(_lines, 0xFF, sizeof(_lines));
+
+ _lineNum = file.readByte();
+ for (int i = 0; i < _lineNum; i++) {
+ LineType *curLine = &_lines[i];
+ curLine->_x1 = file.readSint16LE();
+ curLine->_y1 = file.readSint16LE();
+ curLine->_x2 = file.readSint16LE();
+ curLine->_y2 = file.readSint16LE();
+ curLine->_color = (Color)file.readByte();
+ }
+
+ memset(_peds, 177, sizeof(_peds));
+ byte pedNum = file.readByte();
+ for (int i = 0; i < pedNum; i++) {
+ PedType *curPed = &_peds[i];
+ curPed->_x = file.readSint16LE();
+ curPed->_y = file.readSint16LE();
+ curPed->_direction = (Direction)file.readByte();
+ }
+
+ _fieldNum = file.readByte();
+ for (int i = 0; i < _fieldNum; i++) {
+ FieldType *curField = &_fields[i];
+ curField->_x1 = file.readSint16LE();
+ curField->_y1 = file.readSint16LE();
+ curField->_x2 = file.readSint16LE();
+ curField->_y2 = file.readSint16LE();
+ }
+
+ for (int i = 0; i < 15; i++) {
+ MagicType *magic = &_magics[i];
+ magic->_operation = file.readByte();
+ magic->_data = file.readUint16LE();
+ }
+
+ for (int i = 0; i < 7; i++) {
+ MagicType *portal = &_portals[i];
+ portal->_operation = file.readByte();
+ portal->_data = file.readUint16LE();
+ }
+
+ _flags.clear();
+ for (int i = 0; i < 26; i++)
+ _flags += file.readByte();
+
+ int16 size = file.readByte();
+ _listen.clear();
+ for (int i = 0; i < size; i++)
+ _listen += file.readByte();
+
+ _graphics->clearAlso();
+
+ CursorMan.showMouse(false);
+ for (int i = 0; i < _lineNum; i++) {
+ // We had to check if the lines are within the borders of the screen.
+ if ((_lines[i]._x1 >= 0) && (_lines[i]._x1 < kScreenWidth) && (_lines[i]._y1 >= 0) && (_lines[i]._y1 < kScreenHeight)
+ && (_lines[i]._x2 >= 0) && (_lines[i]._x2 < kScreenWidth) && (_lines[i]._y2 >= 0) && (_lines[i]._y2 < kScreenHeight))
+ _graphics->setAlsoLine(_lines[i]._x1, _lines[i]._y1, _lines[i]._x2, _lines[i]._y2, _lines[i]._color);
+ }
+ CursorMan.showMouse(true);
+
+ file.close();
+
+ unScramble();
+ for (int i = 0; i <= alsoNum; i++) {
+ tmpStr = Common::String::format(",%s,", _also[i][0]->c_str());
+ *_also[i][0] = tmpStr;
+ }
+}
+
+void AvalancheEngine::loadRoom(byte num) {
+ CursorMan.showMouse(false);
+
+ Common::String filename = Common::String::format("place%d.avd", num);
+ Common::File file;
+ if (!file.open(filename))
+ error("AVALANCHE: File not found: %s", filename.c_str());
+
+ file.seek(146);
+ if (!_roomnName.empty())
+ _roomnName.clear();
+ for (int i = 0; i < 30; i++) {
+ char actChar = file.readByte();
+ if ((32 <= actChar) && (actChar <= 126))
+ _roomnName += actChar;
+ }
+ // Compression method byte follows this...
+
+ file.seek(177);
+
+ _graphics->loadBackground(file);
+ _graphics->refreshBackground();
+
+ file.close();
+
+ loadAlso(num);
+ _background->load(num);
+ CursorMan.showMouse(true);
+}
+
+void AvalancheEngine::findPeople(byte room) {
+ for (int i = 1; i < 29; i++) {
+ if (_whereIs[i] == room) {
+ if (i < 25)
+ _him = (People)(150 + i);
+ else
+ _her = (People)(150 + i);
+ }
+ }
+}
+
+void AvalancheEngine::exitRoom(byte x) {
+ _sound->stopSound();
+ _background->release();
+ _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+
+ switch (x) {
+ case kRoomSpludwicks:
+ _timer->loseTimer(Timer::kReasonAvariciusTalks);
+ _avariciusTalk = 0;
+ // He doesn't HAVE to be talking for this to work. It just deletes it IF it exists.
+ break;
+ case kRoomBridge:
+ if (_drawbridgeOpen > 0) {
+ _drawbridgeOpen = 4; // Fully open.
+ _timer->loseTimer(Timer::kReasonDrawbridgeFalls);
+ }
+ break;
+ case kRoomOutsideCardiffCastle:
+ _timer->loseTimer(Timer::kReasonCardiffsurvey);
+ break;
+ case kRoomRobins:
+ _timer->loseTimer(Timer::kReasonGettingTiedUp);
+ break;
+ }
+
+ _interrogation = 0; // Leaving the room cancels all the questions automatically.
+ _seeScroll = false; // Now it can work again!
+
+ _lastRoom = _room;
+ if (_room != kRoomMap)
+ _lastRoomNotMap = _room;
+}
+
+/**
+ * Only when entering a NEW town! Not returning to the last one,
+ * but choosing another from the map.
+ * @remarks Originally called 'new_town'
+ */
+void AvalancheEngine::enterNewTown() {
+ _menu->setup();
+
+ switch (_room) {
+ case kRoomOutsideNottsPub: // Entry into Nottingham.
+ if ((_roomCount[kRoomRobins] > 0) && (_beenTiedUp) && (!_takenMushroom))
+ _mushroomGrowing = true;
+ break;
+ case kRoomWiseWomans: // Entry into Argent.
+ if (_talkedToCrapulus && (!_lustieIsAsleep)) {
+ _spludwickAtHome = !((_roomCount[kRoomWiseWomans] % 3) == 1);
+ _crapulusWillTell = !_spludwickAtHome;
+ } else {
+ _spludwickAtHome = true;
+ _crapulusWillTell = false;
+ }
+ if (_boxContent == kObjectWine)
+ _wineState = 3; // Vinegar
+ break;
+ default:
+ break;
+ }
+
+ if ((_room != kRoomOutsideDucks) && (_objects[kObjectOnion - 1]) && !(_onionInVinegar))
+ _rottenOnion = true; // You're holding the onion
+}
+
+void AvalancheEngine::putGeidaAt(byte whichPed, byte ped) {
+ if (ped == 0)
+ return;
+ AnimationType *spr1 = _animation->_sprites[1];
+
+ spr1->init(5, false); // load Geida
+ _animation->appearPed(1, whichPed);
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcGeida;
+}
+
+void AvalancheEngine::enterRoom(Room roomId, byte ped) {
+ _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+
+ findPeople(roomId);
+ _room = roomId;
+ if (ped != 0)
+ _roomCount[roomId]++;
+
+ loadRoom(roomId);
+
+ if ((_roomCount[roomId] == 0) && (!getFlag('S')))
+ incScore(1);
+
+ _whereIs[kPeopleAvalot - 150] = _room;
+
+ if (_geidaFollows)
+ _whereIs[kPeopleGeida - 150] = roomId;
+
+ _roomCycles = 0;
+
+ if ((_lastRoom == kRoomMap) && (_lastRoomNotMap != _room))
+ enterNewTown();
+
+ _animation->updateSpeed();
+
+ switch (roomId) {
+ case kRoomYours:
+ if (_avvyInBed) {
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _timer->addTimer(100, Timer::kProcArkataShouts, Timer::kReasonArkataShouts);
+ }
+ break;
+
+ case kRoomOutsideYours:
+ if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ if (!_talkedToCrapulus) {
+ _whereIs[kPeopleCrapulus - 150] = kRoomOutsideYours;
+ spr1->init(8, false); // load Crapulus
+
+ if (_roomCount[kRoomOutsideYours] == 1) {
+ _animation->appearPed(1, 3); // Start on the right-hand side of the screen.
+ spr1->walkTo(4); // Walks up to greet you.
+ } else {
+ _animation->appearPed(1, 4); // Starts where he was before.
+ spr1->_facingDir = kDirLeft;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFaceAvvy; // He always faces Avvy.
+
+ } else
+ _whereIs[kPeopleCrapulus - 150] = kRoomNowhere;
+
+ if (_crapulusWillTell) {
+ spr1->init(8, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(3);
+ _timer->addTimer(20, Timer::kProcCrapulusSpludOut, Timer::kReasonCrapulusSaysSpludwickOut);
+ _crapulusWillTell = false;
+ }
+ }
+ break;
+
+ case kRoomOutsideSpludwicks:
+ if ((_roomCount[kRoomOutsideSpludwicks] == 1) && (ped == 1)) {
+ _timer->addTimer(20, Timer::kProcBang, Timer::kReasonExplosion);
+ _spludwickAtHome = true;
+ }
+ break;
+
+ case kRoomSpludwicks:
+ if (_spludwickAtHome) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ if (ped > 0) {
+ spr1->init(2, false); // load Spludwick
+ _animation->appearPed(1, 1);
+ _whereIs[kPeopleSpludwick - 150] = kRoomSpludwicks;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcGeida;
+ } else
+ _whereIs[kPeopleSpludwick - 150] = kRoomNowhere;
+ break;
+
+ case kRoomBrummieRoad:
+ if (_geidaFollows)
+ putGeidaAt(4, ped);
+ if (_cwytalotGone) {
+ _magics[kColorLightred - 1]._operation = kMagicNothing;
+ _whereIs[kPeopleCwytalot - 150] = kRoomNowhere;
+ } else if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(4, false); // 4 = Cwytalot
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFollowAvvyY;
+ _whereIs[kPeopleCwytalot - 150] = kRoomBrummieRoad;
+
+ if (_roomCount[kRoomBrummieRoad] == 1) { // First time here...
+ _animation->appearPed(1, 1); // He appears on the right of the screen...
+ spr1->walkTo(3); // ...and he walks up...
+ } else {
+ // You've been here before.
+ _animation->appearPed(1, 3); // He's standing in your way straight away...
+ spr1->_facingDir = kDirLeft;
+ }
+ }
+ break;
+
+ case kRoomArgentRoad:
+ if ((_cwytalotGone) && (!_passedCwytalotInHerts) && (ped == 2) && (_roomCount[kRoomArgentRoad] > 3)) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(4, false); // 4 = Cwytalot again
+ _animation->appearPed(1, 0);
+ spr1->walkTo(1);
+ spr1->_vanishIfStill = true;
+ _passedCwytalotInHerts = true;
+ // whereis[#157] = r__Nowhere; // can we fit this in?
+ _timer->addTimer(20, Timer::kProcCwytalotInHerts, Timer::kReasonCwytalotInHerts);
+ }
+ break;
+
+ case kRoomBridge:
+ if (_drawbridgeOpen == 4) { // open
+ _background->draw(-1, -1, 2); // Position of drawbridge
+ _graphics->refreshBackground();
+ _magics[kColorGreen - 1]._operation = kMagicNothing; // You may enter the drawbridge.
+ }
+ if (_geidaFollows)
+ putGeidaAt(ped + 2, ped); // load Geida
+ break;
+
+ case kRoomRobins:
+ if ((ped > 0) && (!_beenTiedUp)) {
+ // A welcome party... or maybe not...
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(6, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(2);
+ _timer->addTimer(36, Timer::kProcGetTiedUp, Timer::kReasonGettingTiedUp);
+ }
+
+ if (_beenTiedUp) {
+ _whereIs[kPeopleRobinHood - 150] = kRoomNowhere;
+ _whereIs[kPeopleFriarTuck - 150] = kRoomNowhere;
+ }
+
+ if (_tiedUp)
+ _background->draw(-1, -1, 1);
+
+ if (!_mushroomGrowing)
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ break;
+
+ case kRoomOutsideCardiffCastle:
+ if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ switch (_cardiffQuestionNum) {
+ case 0 : // You've answered NONE of his questions.
+ spr1->init(9, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(2);
+ _timer->addTimer(47, Timer::kProcCardiffSurvey, Timer::kReasonCardiffsurvey);
+ break;
+ case 5 :
+ _magics[1]._operation = kMagicNothing;
+ break; // You've answered ALL his questions. => nothing happens.
+ default: // You've answered SOME of his questions.
+ spr1->init(9, false);
+ _animation->appearPed(1, 2);
+ spr1->_facingDir = kDirRight;
+ _timer->addTimer(3, Timer::kProcCardiffReturn, Timer::kReasonCardiffsurvey);
+ }
+ }
+
+ if (_cardiffQuestionNum < 5)
+ _interrogation = _cardiffQuestionNum;
+ else
+ _interrogation = 0;
+ break;
+
+ case kRoomMap:
+ // You're entering the map.
+ fadeIn();
+ if (ped > 0)
+ _graphics->zoomOut(_peds[ped - 1]._x, _peds[ped - 1]._y);
+
+ if ((_objects[kObjectWine - 1]) && (_wineState != 3)) {
+ _dialogs->displayScrollChain('Q', 9); // Don't want to waste the wine!
+ _objects[kObjectWine - 1] = false;
+ refreshObjectList();
+ }
+
+ _dialogs->displayScrollChain('Q', 69);
+ break;
+
+ case kRoomCatacombs:
+ if ((ped == 0) || (ped == 3) || (ped == 5) || (ped == 6)) {
+
+ switch (ped) {
+ case 3: // Enter from oubliette
+ _catacombX = 8;
+ _catacombY = 4;
+ break;
+ case 5: // Enter from du Lustie's
+ _catacombX = 8;
+ _catacombY = 7;
+ break;
+ case 6: // Enter from Geida's
+ _catacombX = 4;
+ _catacombY = 1;
+ break;
+ }
+
+ _enterCatacombsFromLustiesRoom = true;
+ _animation->catacombMove(ped);
+ _enterCatacombsFromLustiesRoom = false;
+ }
+ break;
+
+ case kRoomArgentPub:
+ if (_wonNim)
+ _background->draw(-1, -1, 0); // No lute by the settle.
+ _malagauche = 0; // Ready to boot Malagauche
+ if (_givenBadgeToIby) {
+ _background->draw(-1, -1, 7);
+ _background->draw(-1, -1, 8);
+ }
+ _graphics->refreshBackground();
+ break;
+
+ case kRoomLustiesRoom:
+ _npcFacing = 1; // du Lustie.
+ if (_animation->getAvvyClothes() == 0) // Avvy in his normal clothes
+ _timer->addTimer(3, Timer::kProcCallsGuards, Timer::kReasonDuLustieTalks);
+ else if (!_enteredLustiesRoomAsMonk) // already
+ // Presumably, Avvy dressed as a monk.
+ _timer->addTimer(3, Timer::kProcGreetsMonk, Timer::kReasonDuLustieTalks);
+
+ if (_geidaFollows) {
+ putGeidaAt(4, ped);
+ if (_lustieIsAsleep) {
+ _background->draw(-1, -1, 4);
+ _graphics->refreshBackground();
+ }
+ }
+ break;
+
+ case kRoomMusicRoom:
+ if (_jacquesState > 0) {
+ _jacquesState = 5;
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _background->draw(-1, -1, 3);
+ _magics[kColorBrown - 1]._operation = kMagicNothing;
+ _whereIs[kPeopleJacques - 150] = kRoomNowhere;
+ }
+ if (ped != 0) {
+ _background->draw(-1, -1, 5);
+ _graphics->refreshBackground();
+ _sequence->startMusicRoomSeq();
+ }
+ break;
+
+ case kRoomOutsideNottsPub:
+ if (ped == 2) {
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _sequence->startDuckSeq();
+ }
+ break;
+
+ case kRoomOutsideArgentPub:
+ if (ped == 2) {
+ _background->draw(-1, -1, 5);
+ _graphics->refreshBackground();
+ _sequence->startMusicRoomSeq();
+ }
+ break;
+
+ case kRoomWiseWomans: {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(11, false);
+ if ((_roomCount[kRoomWiseWomans] == 1) && (ped > 0)) {
+ _animation->appearPed(1, 1); // Start on the right-hand side of the screen.
+ spr1->walkTo(3); // Walks up to greet you.
+ } else {
+ _animation->appearPed(1, 3); // Starts where she was before.
+ spr1->_facingDir = kDirLeft;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFaceAvvy; // She always faces Avvy.
+ }
+ break;
+
+ case kRoomInsideCardiffCastle:
+ if (ped > 0) {
+ _animation->_sprites[1]->init(10, false); // Define the dart.
+ _background->draw(-1, -1, 0);
+ _graphics->refreshBackground();
+ _sequence->startCardiffSeq2();
+ } else {
+ _background->draw(-1, -1, 0);
+ if (_arrowInTheDoor)
+ _background->draw(-1, -1, 2);
+ else
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ }
+ break;
+
+ case kRoomAvvysGarden:
+ if (ped == 1) {
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _sequence->startGardenSeq();
+ }
+ break;
+
+ case kRoomEntranceHall:
+ case kRoomInsideAbbey:
+ case kRoomYourHall:
+ if (ped == 2) {
+#if 0
+ // It was the original:
+ _celer->show_one(-1, -1, 2);
+ _sequence->first_show(1);
+ _sequence->then_show(3);
+ _sequence->start_to_close();
+#endif
+
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _sequence->startGardenSeq();
+ }
+ break;
+
+ case kRoomAylesOffice:
+ if (_aylesIsAwake)
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ break; // Ayles awake.
+
+ case kRoomGeidas:
+ putGeidaAt(1, ped);
+ break; // load Geida
+
+ case kRoomEastHall:
+ case kRoomWestHall:
+ if (_geidaFollows)
+ putGeidaAt(ped + 1, ped);
+ break;
+
+ case kRoomLusties:
+ if (_geidaFollows)
+ putGeidaAt(ped + 5, ped);
+ break;
+
+ case kRoomNottsPub:
+ if (_sittingInPub)
+ _background->draw(-1, -1, 2);
+ _npcFacing = 1; // Port.
+ break;
+
+ case kRoomOutsideDucks:
+ if (ped == 2) {
+ // Shut the door
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _sequence->startDuckSeq();
+ }
+ break;
+
+ case kRoomDucks:
+ _npcFacing = 1; // Duck.
+ break;
+
+ default:
+ break;
+ }
+
+ _seeScroll = false; // Now it can work again!
+}
+
+void AvalancheEngine::thinkAbout(byte object, bool type) {
+ _thinks = object;
+ object--;
+
+ Common::String filename;
+ if (type == kThing) {
+ filename = "thinks.avd";
+ } else { // kPerson
+ filename = "folk.avd";
+
+ object -= 149;
+ if (object >= 25)
+ object -= 8;
+ if (object == 20)
+ object--; // Last time...
+ }
+
+ _graphics->loadMouse(kCurWait);
+ CursorMan.showMouse(false);
+ _graphics->drawThinkPic(filename, object);
+ CursorMan.showMouse(true);
+
+ _thinkThing = type;
+}
+
+void AvalancheEngine::drawToolbar() {
+ _graphics->drawToolbar();
+ _animation->setOldDirection(kDirNone);
+ drawDirection();
+}
+
+void AvalancheEngine::drawScore() {
+ uint16 score = _dnascore;
+ int8 numbers[3] = {0, 0, 0};
+ for (int i = 0; i < 2; i++) {
+ byte divisor = 1;
+ for (int j = 0; j < (2 - i); j++)
+ divisor *= 10;
+ numbers[i] = score / divisor;
+ score -= numbers[i] * divisor;
+ }
+ numbers[2] = score;
+
+ CursorMan.showMouse(false);
+
+ for (int i = 0; i < 3; i++) {
+ if (_scoreToDisplay[i] != numbers[i])
+ _graphics->drawDigit(numbers[i], 250 + (i + 1) * 15, 177);
+ }
+
+ CursorMan.showMouse(true);
+
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = numbers[i];
+}
+
+void AvalancheEngine::incScore(byte num) {
+ for (int i = 1; i <= num; i++) {
+ _dnascore++;
+
+ if (_soundFx) {
+ for (int j = 1; j <= 97; j++)
+ // Length os 2 is a guess, the original doesn't have a delay specified
+ _sound->playNote(177 + _dnascore * 3, 2);
+ }
+ }
+ warning("STUB: points()");
+
+ drawScore();
+}
+
+void AvalancheEngine::useCompass(const Common::Point &cursorPos) {
+ byte color = _graphics->getScreenColor(cursorPos);
+
+ switch (color) {
+ case kColorGreen:
+ _animation->setDirection(kDirUp);
+ _animation->setMoveSpeed(0, kDirUp);
+ drawDirection();
+ break;
+ case kColorBrown:
+ _animation->setDirection(kDirDown);
+ _animation->setMoveSpeed(0, kDirDown);
+ drawDirection();
+ break;
+ case kColorCyan:
+ _animation->setDirection(kDirLeft);
+ _animation->setMoveSpeed(0, kDirLeft);
+ drawDirection();
+ break;
+ case kColorLightmagenta:
+ _animation->setDirection(kDirRight);
+ _animation->setMoveSpeed(0, kDirRight);
+ drawDirection();
+ break;
+ case kColorRed:
+ case kColorWhite:
+ case kColorLightcyan:
+ case kColorYellow: // Fall-throughs are intended.
+ _animation->stopWalking();
+ drawDirection();
+ break;
+ }
+}
+
+void AvalancheEngine::fxToggle() {
+ warning("STUB: fxtoggle()");
+}
+
+void AvalancheEngine::refreshObjectList() {
+ _carryNum = 0;
+ if (_thinkThing && !_objects[_thinks - 1])
+ thinkAbout(kObjectMoney, kThing); // you always have money
+
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_objects[i]) {
+ _objectList[_carryNum] = i + 1;
+ _carryNum++;
+ }
+ }
+}
+
+/**
+ * @remarks Originally called 'verte'
+ */
+void AvalancheEngine::guideAvvy(Common::Point cursorPos) {
+ if (!_userMovesAvvy)
+ return;
+
+ cursorPos.y /= 2;
+ byte what;
+
+ // _animation->tr[0] is Avalot.)
+ AnimationType *avvy = _animation->_sprites[0];
+ if (cursorPos.x < avvy->_x)
+ what = 1;
+ else if (cursorPos.x > (avvy->_x + avvy->_xLength))
+ what = 2;
+ else
+ what = 0; // On top
+
+ if (cursorPos.y < avvy->_y)
+ what += 3;
+ else if (cursorPos.y > (avvy->_y + avvy->_yLength))
+ what += 6;
+
+ switch (what) {
+ case 0:
+ _animation->stopWalking();
+ break; // Clicked on Avvy: no movement.
+ case 1:
+ _animation->setMoveSpeed(0, kDirLeft);
+ break;
+ case 2:
+ _animation->setMoveSpeed(0, kDirRight);
+ break;
+ case 3:
+ _animation->setMoveSpeed(0, kDirUp);
+ break;
+ case 4:
+ _animation->setMoveSpeed(0, kDirUpLeft);
+ break;
+ case 5:
+ _animation->setMoveSpeed(0, kDirUpRight);
+ break;
+ case 6:
+ _animation->setMoveSpeed(0, kDirDown);
+ break;
+ case 7:
+ _animation->setMoveSpeed(0, kDirDownLeft);
+ break;
+ case 8:
+ _animation->setMoveSpeed(0, kDirDownRight);
+ break;
+ } // No other values are possible.
+
+ drawDirection();
+}
+
+void AvalancheEngine::checkClick() {
+ Common::Point cursorPos = getMousePos();
+
+ /*if (mrelease > 0)
+ after_the_scroll = false;*/
+
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21))
+ _graphics->loadMouse(kCurUpArrow); // up arrow
+ else if ((317 <= cursorPos.y) && (cursorPos.y <= 339))
+ _graphics->loadMouse(kCurIBeam); //I-beam
+ else if ((340 <= cursorPos.y) && (cursorPos.y <= 399))
+ _graphics->loadMouse(kCurScrewDriver); // screwdriver
+ else if (!_menu->isActive()) { // Dropdown can handle its own pointers.
+ if (_holdLeftMouse) {
+ _graphics->loadMouse(kCurCrosshair); // Mark's crosshairs
+ guideAvvy(cursorPos); // Normally, if you click on the picture, you're guiding Avvy around.
+ } else
+ _graphics->loadMouse(kCurFletch); // fletch
+ }
+
+ if (_holdLeftMouse) {
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21)) { // Click on the dropdown menu.
+ if (_dropsOk)
+ _menu->update();
+ } else if ((317 <= cursorPos.y) && (cursorPos.y <= 339)) { // Click on the command line.
+ _parser->_inputTextPos = (cursorPos.x - 23) / 8;
+ if (_parser->_inputTextPos > _parser->_inputText.size() + 1)
+ _parser->_inputTextPos = _parser->_inputText.size() + 1;
+ if (_parser->_inputTextPos < 1)
+ _parser->_inputTextPos = 1;
+ _parser->_inputTextPos--;
+ _parser->plotText();
+ } else if ((340 <= cursorPos.y) && (cursorPos.y <= 399)) { // Check the toolbar.
+ if ((137 <= cursorPos.x) && (cursorPos.x <= 207)) { // Control Avvy with the compass.
+ if (_alive && _avvyIsAwake)
+ useCompass(cursorPos);
+ } else if ((208 <= cursorPos.x) && (cursorPos.x <= 260)) { // Examine the _thing.
+ do {
+ updateEvents();
+ } while (_holdLeftMouse);
+
+ if (_thinkThing) {
+ _parser->_thing = _thinks;
+ _parser->_thing += 49;
+ _parser->_person = kPeoplePardon;
+ } else {
+ _parser->_person = (People)_thinks;
+ _parser->_thing = _parser->kPardon;
+ }
+ callVerb(kVerbCodeExam);
+ } else if ((261 <= cursorPos.x) && (cursorPos.x <= 319)) { // Display the score.
+ do {
+ updateEvents();
+ } while (_holdLeftMouse);
+
+ callVerb(kVerbCodeScore);
+ } else if ((320 <= cursorPos.x) && (cursorPos.x <= 357)) { // Change speed.
+ _animation->_sprites[0]->_speedX = kWalk;
+ _animation->updateSpeed();
+ } else if ((358 <= cursorPos.x) && (cursorPos.x <= 395)) { // Change speed.
+ _animation->_sprites[0]->_speedX = kRun;
+ _animation->updateSpeed();
+ } else if ((396 <= cursorPos.x) && (cursorPos.x <= 483))
+ fxToggle();
+ else if ((535 <= cursorPos.x) && (cursorPos.x <= 640))
+ _mouseText.insertChar(kControlNewLine, 0);
+ } else if (!_dropsOk)
+ _mouseText = Common::String(13) + _mouseText;
+ }
+}
+
+void AvalancheEngine::errorLed() {
+ warning("STUB: errorled()");
+}
+
+/**
+ * Displays a fade out, full screen.
+ * This version is different to the one in the original, which was fading in 3 steps.
+ * @remarks Originally called 'dusk'
+ */
+void AvalancheEngine::fadeOut() {
+ byte pal[3], tmpPal[3];
+
+ _graphics->setBackgroundColor(kColorBlack);
+ if (_fxHidden)
+ return;
+ _fxHidden = true;
+
+ for (int i = 0; i < 16; i++) {
+ for (int j = 0; j < 16; j++) {
+ g_system->getPaletteManager()->grabPalette((byte *)tmpPal, j, 1);
+ _fxPal[i][j][0] = tmpPal[0];
+ _fxPal[i][j][1] = tmpPal[1];
+ _fxPal[i][j][2] = tmpPal[2];
+ if (tmpPal[0] >= 16)
+ pal[0] = tmpPal[0] - 16;
+ else
+ pal[0] = 0;
+
+ if (tmpPal[1] >= 16)
+ pal[1] = tmpPal[1] - 16;
+ else
+ pal[1] = 0;
+
+ if (tmpPal[2] >= 16)
+ pal[2] = tmpPal[2] - 16;
+ else
+ pal[2] = 0;
+
+ g_system->getPaletteManager()->setPalette(pal, j, 1);
+ }
+ _system->delayMillis(10);
+ _graphics->refreshScreen();
+ }
+}
+
+/**
+ * Displays a fade in, full screen.
+ * This version is different to the one in the original, which was fading in 3 steps.
+ * @remarks Originally called 'dawn'
+ */
+void AvalancheEngine::fadeIn() {
+ if (_holdTheDawn || !_fxHidden)
+ return;
+
+ _fxHidden = false;
+
+ byte pal[3];
+ for (int i = 15; i >= 0; i--) {
+ for (int j = 0; j < 16; j++) {
+ pal[0] = _fxPal[i][j][0];
+ pal[1] = _fxPal[i][j][1];
+ pal[2] = _fxPal[i][j][2];
+ g_system->getPaletteManager()->setPalette(pal, j, 1);
+ }
+ _system->delayMillis(10);
+ _graphics->refreshScreen();
+ }
+
+ if ((_room == kRoomYours) && _avvyInBed && _teetotal)
+ _graphics->setBackgroundColor(kColorYellow);
+}
+
+void AvalancheEngine::drawDirection() { // It's data is loaded in load_digits().
+ if (_animation->getOldDirection() == _animation->getDirection())
+ return;
+
+ _animation->setOldDirection(_animation->getDirection());
+
+ CursorMan.showMouse(false);
+ _graphics->drawDirection(_animation->getDirection(), 0, 161);
+ CursorMan.showMouse(true);
+}
+
+void AvalancheEngine::gameOver() {
+ _userMovesAvvy = false;
+
+ AnimationType *avvy = _animation->_sprites[0];
+ int16 sx = avvy->_x;
+ int16 sy = avvy->_y;
+
+ avvy->remove();
+ avvy->init(12, true); // 12 = Avalot falls
+ avvy->_stepNum = 0;
+ avvy->appear(sx, sy, kDirUp);
+
+ _timer->addTimer(3, Timer::kProcAvalotFalls, Timer::kReasonFallingOver);
+ _alive = false;
+}
+
+void AvalancheEngine::minorRedraw() {
+ fadeOut();
+
+ enterRoom(_room, 0); // Ped unknown or non-existant.
+
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = -1; // impossible digits
+ drawScore();
+
+ fadeIn();
+}
+
+void AvalancheEngine::majorRedraw() {
+ warning("STUB: major_redraw()");
+}
+
+uint16 AvalancheEngine::bearing(byte whichPed) {
+ AnimationType *avvy = _animation->_sprites[0];
+ PedType *curPed = &_peds[whichPed];
+
+ if (avvy->_x == curPed->_x)
+ return 0;
+
+ int16 deltaX = avvy->_x - curPed->_x;
+ int16 deltaY = avvy->_y - curPed->_y;
+ uint16 result = (uint16)(atan((float)(deltaY / deltaX)) * 180 / M_PI);
+ if (avvy->_x < curPed->_x) {
+ return result + 90;
+ } else {
+ return result + 270;
+ }
+}
+
+/**
+ * @remarks Originally called 'sprite_run'
+ */
+void AvalancheEngine::spriteRun() {
+ _doingSpriteRun = true;
+ _animation->animLink();
+ _doingSpriteRun = false;
+}
+
+// CHECKME: Unused function
+void AvalancheEngine::fixFlashers() {
+ _ledStatus = 177;
+ _animation->setOldDirection(kDirNone);
+ _dialogs->setReadyLight(2);
+ drawDirection();
+}
+
+Common::String AvalancheEngine::intToStr(int32 num) {
+ return Common::String::format("%d", num);
+}
+
+void AvalancheEngine::resetVariables() {
+ _animation->setDirection(kDirUp);
+ _carryNum = 0;
+ for (int i = 0; i < kObjectNum; i++)
+ _objects[i] = false;
+
+ _dnascore = 0;
+ _money = 0;
+ _room = kRoomNowhere;
+ _saveNum = 0;
+ for (int i = 0; i < 100; i++)
+ _roomCount[i] = 0;
+
+ _wonNim = false;
+ _wineState = 0;
+ _cwytalotGone = false;
+ _passwordNum = 0;
+ _aylesIsAwake = false;
+ _drawbridgeOpen = 0;
+ _avariciusTalk = 0;
+ _rottenOnion = false;
+ _onionInVinegar = false;
+ _givenToSpludwick = 0;
+ _brummieStairs = 0;
+ _cardiffQuestionNum = 0;
+ _passedCwytalotInHerts = false;
+ _avvyIsAwake = false;
+ _avvyInBed = false;
+ _userMovesAvvy = false;
+ _npcFacing = 0;
+ _givenBadgeToIby = false;
+ _friarWillTieYouUp = false;
+ _tiedUp = false;
+ _boxContent = 0;
+ _talkedToCrapulus = false;
+ _jacquesState = 0;
+ _bellsAreRinging = false;
+ _standingOnDais = false;
+ _takenPen = false;
+ _arrowInTheDoor = false;
+ _favoriteDrink = "";
+ _favoriteSong = "";
+ _worstPlaceOnEarth = "";
+ _spareEvening = "";
+ _totalTime = 0;
+ _jumpStatus = 0;
+ _mushroomGrowing = false;
+ _spludwickAtHome = false;
+ _lastRoom = kRoomDummy;
+ _lastRoomNotMap = kRoomDummy;
+ _crapulusWillTell = false;
+ _enterCatacombsFromLustiesRoom = false;
+ _teetotal = false;
+ _malagauche = 0;
+ _drinking = 0;
+ _enteredLustiesRoomAsMonk = false;
+ _catacombX = 0;
+ _catacombY = 0;
+ _avvysInTheCupboard = false;
+ _geidaFollows = false;
+ _givenPotionToGeida = false;
+ _lustieIsAsleep = false;
+ _beenTiedUp = false;
+ _sittingInPub = false;
+ _spurgeTalkCount = 0;
+ _metAvaroid = false;
+ _takenMushroom = false;
+ _givenPenToAyles = false;
+ _askedDogfoodAboutNim = false;
+ _startTime = getTimeInSeconds();
+
+ _parser->resetVariables();
+ _nim->resetVariables();
+ _animation->resetVariables();
+ _sequence->resetVariables();
+ _background->resetVariables();
+ _menu->resetVariables();
+ _timer->resetVariables();
+}
+
+void AvalancheEngine::newGame() {
+ for (int i = 0; i < kMaxSprites; i++) {
+ AnimationType *spr = _animation->_sprites[i];
+ if (spr->_quick)
+ spr->remove();
+ }
+ // Deallocate sprite. Sorry, beta testers!
+
+ AnimationType *avvy = _animation->_sprites[0];
+ avvy->init(0, true);
+
+ _alive = true;
+ resetVariables();
+
+ _dialogs->setBubbleStateNatural();
+
+ _spareEvening = "answer a questionnaire";
+ _favoriteDrink = "beer";
+ _money = 30; // 2/6
+ _animation->setDirection(kDirStopped);
+ _parser->_wearing = kObjectClothes;
+ _objects[kObjectMoney - 1] = true;
+ _objects[kObjectBodkin - 1] = true;
+ _objects[kObjectBell - 1] = true;
+ _objects[kObjectClothes - 1] = true;
+
+ _thinkThing = true;
+ _thinks = 2;
+ refreshObjectList();
+ _seeScroll = false;
+
+ avvy->appear(300, 117, kDirRight); // Needed to initialize Avalot.
+ //for (gd = 0; gd <= 30; gd++) for (gm = 0; gm <= 1; gm++) also[gd][gm] = nil;
+ // fillchar(previous^,sizeof(previous^),#0); { blank out array }
+ _him = kPeoplePardon;
+ _her = kPeoplePardon;
+ _it = Parser::kPardon;
+ _passwordNum = _rnd->getRandomNumber(29) + 1; //Random(30) + 1;
+ _userMovesAvvy = false;
+ _doingSpriteRun = false;
+ _avvyInBed = true;
+
+ _isLoaded = false;
+
+ enterRoom(kRoomYours, 1);
+ avvy->_visible = false;
+ drawScore();
+ _menu->setup();
+ _clock->update();
+ spriteRun();
+}
+
+bool AvalancheEngine::getFlag(char x) {
+ for (uint16 i = 0; i < _flags.size(); i++) {
+ if (_flags[i] == x)
+ return true;
+ }
+
+ return false;
+}
+
+bool AvalancheEngine::decreaseMoney(uint16 amount) {
+ _money -= amount;
+ if (_money < 0) {
+ _dialogs->displayScrollChain('Q', 2); // "You are now denariusless!"
+ gameOver();
+ return false;
+ } else
+ return true;
+}
+
+Common::String AvalancheEngine::getName(People whose) {
+ static const char lads[17][20] = {
+ "Avalot", "Spludwick", "Crapulus", "Dr. Duck", "Malagauche",
+ "Friar Tuck", "Robin Hood", "Cwytalot", "du Lustie", "the Duke of Cardiff",
+ "Dogfood", "A trader", "Ibythneth", "Ayles", "Port",
+ "Spurge", "Jacques"
+ };
+
+ static const char lasses[4][15] = {"Arkata", "Geida", "\0xB1", "the Wise Woman"};
+
+ if (whose <= kPeopleJacques)
+ return Common::String(lads[whose - kPeopleAvalot]);
+ else if ((whose >= kPeopleArkata) && (whose <= kPeopleWisewoman))
+ return Common::String(lasses[whose - kPeopleArkata]);
+ else
+ error("getName() - Unexpected character id %d", (byte) whose);
+}
+
+Common::String AvalancheEngine::getItem(byte which) {
+ static const char items[kObjectNum][18] = {
+ "some wine", "your money-bag", "your bodkin", "a potion", "a chastity belt",
+ "a crossbow bolt", "a crossbow", "a lute", "a pilgrim's badge", "a mushroom",
+ "a key", "a bell", "a scroll", "a pen", "some ink",
+ "your clothes", "a habit", "an onion"
+ };
+
+ Common::String result;
+ if (which > 150)
+ which -= 149;
+
+ switch (which) {
+ case kObjectWine:
+ switch (_wineState) {
+ case 0:
+ case 1:
+ case 4:
+ result = Common::String(items[which - 1]);
+ break;
+ case 3:
+ result = "some vinegar";
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_rottenOnion)
+ result = "a rotten onion";
+ else if (_onionInVinegar)
+ result = "a pickled onion (in the vinegar)";
+ else
+ result = Common::String(items[which - 1]);
+ break;
+ default:
+ if ((which < kObjectNum) && (which > 0))
+ result = Common::String(items[which - 1]);
+ else
+ result = "";
+ }
+ return result;
+}
+
+Common::String AvalancheEngine::f5Does() {
+ switch (_room) {
+ case kRoomYours:
+ if (!_avvyIsAwake)
+ return Common::String::format("%cWWake up", kVerbCodeWake);
+ else if (_avvyInBed)
+ return Common::String::format("%cGGet up", kVerbCodeStand);
+ break;
+ case kRoomInsideCardiffCastle:
+ if (_standingOnDais)
+ return Common::String::format("%cCClimb down", kVerbCodeClimb);
+ else
+ return Common::String::format("%cCClimb up", kVerbCodeClimb);
+ break;
+ case kRoomNottsPub:
+ if (_sittingInPub)
+ return Common::String::format("%cSStand up", kVerbCodeStand);
+ else
+ return Common::String::format("%cSSit down", kVerbCodeSit);
+ break;
+ case kRoomMusicRoom:
+ if (_animation->inField(5))
+ return Common::String::format("%cPPlay the harp", kVerbCodePlay);
+ break;
+ default:
+ break;
+ }
+
+ return Common::String::format("%c", kVerbCodePardon); // If all else fails...
+}
+
+void AvalancheEngine::flipRoom(Room room, byte ped) {
+ assert((ped > 0) && (ped < 15));
+ if (!_alive) {
+ // You can't leave the room if you're dead.
+ _animation->_sprites[0]->_moveX = 0;
+ _animation->_sprites[0]->_moveY = 0; // Stop him from moving.
+ return;
+ }
+
+ if ((room == kRoomDummy) && (_room == kRoomLusties)) {
+ _animation->hideInCupboard();
+ return;
+ }
+
+ if ((_jumpStatus > 0) && (_room == kRoomInsideCardiffCastle)) {
+ // You can't *jump* out of Cardiff Castle!
+ _animation->_sprites[0]->_moveX = 0;
+ return;
+ }
+
+ exitRoom(_room);
+ fadeOut();
+
+ for (int16 i = 1; i < _animation->kSpriteNumbMax; i++) {
+ if (_animation->_sprites[i]->_quick)
+ _animation->_sprites[i]->remove();
+ } // Deallocate sprite
+
+ if (_room == kRoomLustiesRoom)
+ _enterCatacombsFromLustiesRoom = true;
+
+ if (room > kRoomMap)
+ return;
+
+ enterRoom(room, ped);
+ _animation->appearPed(0, ped - 1);
+ _enterCatacombsFromLustiesRoom = false;
+ _animation->setOldDirection(_animation->getDirection());
+ _animation->setDirection(_animation->_sprites[0]->_facingDir);
+ drawDirection();
+
+ fadeIn();
+}
+
+/**
+ * Open the Door.
+ * This slides the door open. The data really ought to be saved in
+ * the Also file, and will be next time. However, for now, they're
+ * here.
+ * @remarks Originally called 'open_the_door'
+ */
+void AvalancheEngine::openDoor(Room whither, byte ped, byte magicnum) {
+ switch (_room) {
+ case kRoomOutsideYours:
+ case kRoomOutsideNottsPub:
+ case kRoomOutsideDucks:
+ _sequence->startOutsideSeq(whither, ped);
+ break;
+ case kRoomInsideCardiffCastle:
+ _sequence->startCardiffSeq(whither, ped);
+ break;
+ case kRoomAvvysGarden:
+ case kRoomEntranceHall:
+ case kRoomInsideAbbey:
+ case kRoomYourHall:
+ _sequence->startHallSeq(whither, ped);
+ break;
+ case kRoomMusicRoom:
+ case kRoomOutsideArgentPub:
+ _sequence->startMusicRoomSeq2(whither, ped);
+ break;
+ case kRoomLusties:
+ switch (magicnum) {
+ case 14:
+ if (_avvysInTheCupboard) {
+ _animation->hideInCupboard();
+ _sequence->startCupboardSeq();
+ return;
+ } else {
+ _animation->appearPed(0, 5);
+ _animation->_sprites[0]->_facingDir = kDirRight;
+ _sequence->startLustiesSeq2(whither, ped);
+ }
+ break;
+ case 12:
+ _sequence->startLustiesSeq3(whither, ped);
+ break;
+ }
+ break;
+ default:
+ _sequence->startDummySeq(whither, ped);
+ }
+}
+
+void AvalancheEngine::setRoom(People persId, Room roomId) {
+ _whereIs[persId - kPeopleAvalot] = roomId;
+}
+
+Room AvalancheEngine::getRoom(People persId) {
+ return _whereIs[persId - kPeopleAvalot];
+}
+} // End of namespace Avalanche
diff --git a/engines/avalanche/avalot.h b/engines/avalanche/avalot.h
new file mode 100644
index 0000000000..f50ad28bc4
--- /dev/null
+++ b/engines/avalanche/avalot.h
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* AVALOT The kernel of the program. */
+
+#ifndef AVALANCHE_AVALOT_H
+#define AVALANCHE_AVALOT_H
+
+#include "avalanche/animation.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Clock {
+public:
+ Clock(AvalancheEngine *vm);
+
+ void update();
+
+private:
+ static const int kCenterX = 510;
+ static const int kCenterY = 183;
+
+ AvalancheEngine *_vm;
+
+ uint16 _hour, _minute, _second, _hourAngle, _oldHour, _oldMinute, _oldHourAngle;
+ Common::Point _clockHandHour, _clockHandMinute;
+
+ Common::Point calcHand(uint16 angle, uint16 length, Color color);
+ void drawHand(const Common::Point &endPoint, Color color);
+ void plotHands();
+ void chime();
+};
+
+static const byte kObjectNum = 18; // always preface with a #
+static const int16 kCarryLimit = 12; // carry limit
+
+static const int16 kNumlockCode = 32; // Code for Num Lock
+static const int16 kMouseSize = 134;
+
+struct PedType {
+ int16 _x, _y;
+ Direction _direction;
+};
+
+struct MagicType {
+ byte _operation; // one of the operations
+ uint16 _data; // data for them
+};
+
+struct FieldType {
+ int16 _x1, _y1, _x2, _y2;
+};
+
+struct LineType : public FieldType {
+ Color _color;
+};
+
+typedef int8 TuneType[31];
+
+struct QuasipedType {
+ byte _whichPed;
+ Color _textColor;
+ Room _room;
+ Color _backgroundColor;
+ People _who;
+};
+
+#if 0
+struct Sundry { // Things which must be saved over a backtobootstrap, outside DNA.
+ Common::String _qEnidFilename;
+ bool _qSoundFx;
+ byte _qThinks;
+ bool _qThinkThing;
+};
+#endif
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_AVALOT_H
diff --git a/engines/avalanche/background.cpp b/engines/avalanche/background.cpp
new file mode 100644
index 0000000000..5d168a20af
--- /dev/null
+++ b/engines/avalanche/background.cpp
@@ -0,0 +1,370 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: CELER The unit for updating the screen pics. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/background.h"
+
+namespace Avalanche {
+
+const int16 Background::kOnDisk = -1;
+
+Background::Background(AvalancheEngine *vm) {
+ _vm = vm;
+ _spriteNum = 0;
+ _nextBell = 0;
+}
+
+Background::~Background() {
+ release();
+}
+
+/**
+ * @remarks Originally called 'pics_link'
+ */
+void Background::update() {
+ if (_vm->_menu->isActive())
+ return; // No animation when the menus are up.
+
+ switch (_vm->_room) {
+ case kRoomOutsideArgentPub:
+ if ((_vm->_roomCycles % 12) == 0)
+ draw(-1, -1, (_vm->_roomCycles / 12) % 4);
+ break;
+ case kRoomBrummieRoad:
+ if ((_vm->_roomCycles % 2) == 0)
+ draw(-1, -1, (_vm->_roomCycles / 2) % 4);
+ break;
+ case kRoomBridge:
+ if ((_vm->_roomCycles % 2) == 0)
+ draw(-1, -1, 3 + (_vm->_roomCycles / 2) % 4);
+ break;
+ case kRoomYours:
+ if ((!_vm->_avvyIsAwake) && ((_vm->_roomCycles % 4) == 0))
+ draw(-1, -1, (_vm->_roomCycles / 12) % 2);
+ break;
+ case kRoomArgentPub:
+ if (((_vm->_roomCycles % 7) == 1) && (_vm->_malagauche != 177)) {
+ // Malagauche cycle.
+ _vm->_malagauche++;
+ switch (_vm->_malagauche) {
+ case 1:
+ case 11:
+ case 21:
+ draw(-1, -1, 11); // Looks forwards.
+ break;
+ case 8:
+ case 18:
+ case 28:
+ case 32:
+ draw(-1, -1, 10); // Looks at you.
+ break;
+ case 30:
+ draw(-1, -1, 12); // Winks.
+ break;
+ case 33:
+ _vm->_malagauche = 0;
+ break;
+ }
+ }
+
+ switch (_vm->_roomCycles % 200) {
+ case 179:
+ case 197:
+ draw(-1, -1, 4); // Dogfood's drinking cycle.
+ break;
+ case 182:
+ case 194:
+ draw(-1, -1, 5);
+ break;
+ case 185:
+ draw(-1, -1, 6);
+ break;
+ case 199:
+ _vm->_npcFacing = 177; // Impossible value for this.
+ break;
+ default:
+ if (_vm->_roomCycles % 200 <= 178) { // Normally.
+ byte direction = 1;
+ uint16 angle = _vm->bearing(1);
+ if (((angle >= 1) && (angle <= 90)) || ((angle >= 358) && (angle <= 360)))
+ direction = 3;
+ else if ((angle >= 293) && (angle <= 357))
+ direction = 2;
+ else if ((angle >= 270) && (angle <= 292))
+ direction = 4;
+
+ if (direction != _vm->_npcFacing) { // Dogfood.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ }
+ }
+ break;
+ case kRoomWestHall:
+ if ((_vm->_roomCycles % 3) == 0) {
+ switch ((_vm->_roomCycles / 3) % 6) {
+ case 4:
+ draw(-1, -1, 0);
+ break;
+ case 1:
+ case 3:
+ case 5:
+ draw(-1, -1, 1);
+ break;
+ case 0:
+ case 2:
+ draw(-1, -1, 2);
+ break;
+ }
+ }
+ break;
+ case kRoomLustiesRoom:
+ if (!(_vm->_lustieIsAsleep)) {
+ byte direction = 0;
+ uint16 angle = _vm->bearing(1);
+ if ((_vm->_roomCycles % 45) > 42)
+ direction = 4; // du Lustie blinks.
+ // Bearing of Avvy from du Lustie.
+ else if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 1; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 2; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 3; // Right.
+
+ if (direction != _vm->_npcFacing) { // du Lustie.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ }
+ break;
+ case kRoomAylesOffice:
+ if ((!_vm->_aylesIsAwake) && (_vm->_roomCycles % 14 == 0)) {
+ switch ((_vm->_roomCycles / 14) % 2) {
+ case 0:
+ draw(-1, -1, 0); // Frame 2: EGA.
+ break;
+ case 1:
+ draw(-1, -1, 2); // Frame 1: Natural.
+ break;
+ }
+ }
+ break;
+ case kRoomRobins:
+ if (_vm->_tiedUp) {
+ switch (_vm->_roomCycles % 54) {
+ case 20:
+ draw(-1, -1, 3); // Frame 4: Avalot blinks.
+ break;
+ case 23:
+ draw(-1, -1, 1); // Frame 1: Back to normal.
+ break;
+ }
+ }
+ break;
+ case kRoomNottsPub: {
+ // Bearing of Avvy from Port.
+ byte direction = 0;
+ uint16 angle = _vm->bearing(4);
+ if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 2; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 6; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 8; // Right.
+
+ if ((_vm->_roomCycles % 60) > 57)
+ direction--; // Blinks.
+
+ if (direction != _vm->_npcFacing) { // Port.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+
+ switch (_vm->_roomCycles % 50) {
+ case 45 :
+ draw(-1, -1, 8); // Spurge blinks.
+ break;
+ case 49 :
+ draw(-1, -1, 9);
+ break;
+ }
+ break;
+ }
+ case kRoomDucks: {
+ if ((_vm->_roomCycles % 3) == 0) // The fire flickers.
+ draw(-1, -1, (_vm->_roomCycles / 3) % 3);
+
+ // Bearing of Avvy from Duck.
+ byte direction = 0;
+ uint16 angle = _vm->bearing(1);
+ if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 4; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 6; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 8; // Right.
+
+ if ((_vm->_roomCycles % 45) > 42)
+ direction++; // Duck blinks.
+
+ if (direction != _vm->_npcFacing) { // Duck.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if ((_vm->_bellsAreRinging) && (_vm->getFlag('B'))) {
+ // They're ringing the bells.
+ switch (_vm->_roomCycles % 4) {
+ case 1:
+ if (_nextBell < 5)
+ _nextBell = 12;
+ _nextBell--;
+ // CHECKME: 2 is a guess. No length in the original?
+ _vm->_sound->playNote(_vm->kNotes[_nextBell], 2);
+ break;
+ case 2:
+ _vm->_sound->stopSound();
+ break;
+ }
+ }
+}
+
+void Background::load(byte number) {
+ Common::File f;
+ _filename = _filename.format("chunk%d.avd", number);
+ if (!f.open(_filename))
+ return; // We skip because some rooms don't have sprites in the background.
+
+ f.seek(44);
+ _spriteNum = f.readByte();
+ for (int i = 0; i < _spriteNum; i++)
+ _offsets[i] = f.readSint32LE();
+
+ for (int i = 0; i < _spriteNum; i++) {
+ f.seek(_offsets[i]);
+
+ SpriteType sprite;
+ sprite._type = (PictureType)(f.readByte());
+ sprite._x = f.readSint16LE();
+ sprite._y = f.readSint16LE();
+ sprite._xl = f.readSint16LE();
+ sprite._yl = f.readSint16LE();
+ sprite._size = f.readSint32LE();
+ bool natural = f.readByte();
+ bool memorize = f.readByte();
+
+ if (memorize) {
+ _sprites[i]._x = sprite._x;
+ _sprites[i]._xl = sprite._xl;
+ _sprites[i]._y = sprite._y;
+ _sprites[i]._yl = sprite._yl;
+ _sprites[i]._type = sprite._type;
+
+ if (natural)
+ _vm->_graphics->getNaturalPicture(_sprites[i]);
+ else {
+ _sprites[i]._size = sprite._size;
+ _sprites[i]._picture = _vm->_graphics->loadPictureRaw(f, _sprites[i]._xl * 8, _sprites[i]._yl + 1);
+ }
+ } else
+ _sprites[i]._x = kOnDisk;
+ }
+ f.close();
+}
+
+void Background::release() {
+ for (int i = 0; i < _spriteNum; i++) {
+ if (_sprites[i]._x > kOnDisk)
+ _sprites[i]._picture.free();
+ }
+}
+
+/**
+ * Draw background animation
+ * @remarks Originally called 'show_one'
+ */
+void Background::draw(int16 destX, int16 destY, byte sprId) {
+ assert(sprId < 40);
+
+ if (_sprites[sprId]._x > kOnDisk) {
+ if (destX < 0) {
+ destX = _sprites[sprId]._x * 8;
+ destY = _sprites[sprId]._y;
+ }
+ drawSprite(destX, destY, _sprites[sprId]);
+ } else {
+ Common::File f;
+ if (!f.open(_filename)) // Filename was set in loadBackgroundSprites().
+ return; // We skip because some rooms don't have sprites in the background.
+
+ f.seek(_offsets[sprId]);
+
+ SpriteType sprite;
+ sprite._type = (PictureType)(f.readByte());
+ sprite._x = f.readSint16LE();
+ sprite._y = f.readSint16LE();
+ sprite._xl = f.readSint16LE();
+ sprite._yl = f.readSint16LE();
+ sprite._size = f.readSint32LE();
+ f.skip(2); // Natural and Memorize are used in Load()
+ sprite._picture = _vm->_graphics->loadPictureRaw(f, sprite._xl * 8, sprite._yl + 1);
+
+ if (destX < 0) {
+ destX = sprite._x * 8;
+ destY = sprite._y;
+ }
+ drawSprite(destX, destY, sprite);
+
+ sprite._picture.free();
+ f.close();
+ }
+}
+
+/**
+ * @remarks Originally called 'display_it'
+ */
+void Background::drawSprite(int16 x, int16 y, SpriteType &sprite) {
+ // These pictures are practically parts of the background. -10 is for the drop-down menu.
+ _vm->_graphics->drawBackgroundSprite(x, y - 10, sprite);
+}
+
+void Background::resetVariables() {
+ _nextBell = 0;
+}
+
+void Background::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_nextBell);
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/background.h b/engines/avalanche/background.h
new file mode 100644
index 0000000000..34d7a9a2cc
--- /dev/null
+++ b/engines/avalanche/background.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: CELER The unit for updating the screen pics. */
+
+#ifndef AVALANCHE_BACKGROUND_H
+#define AVALANCHE_BACKGROUND_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+enum PictureType {kEga, kBgi, kNaturalImage};
+
+struct SpriteType {
+ PictureType _type;
+ int16 _x, _y;
+ int16 _xl, _yl;
+ int32 _size;
+ Graphics::Surface _picture;
+};
+
+class Background {
+public:
+ Background(AvalancheEngine *vm);
+ ~Background();
+
+ void update();
+ void load(byte number);
+ void release();
+
+ // Setting the destination to negative coordinates means the picture should be drawn to it's original position.
+ // If you give it positive values, the picture will be plotted to the desired coordinates on the screen.
+ // By that we get rid of show_one_at(), which would be almost identical and cause a lot of code duplication.
+ void draw(int16 destX, int16 destY, byte sprId);
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+
+private:
+ AvalancheEngine *_vm;
+
+ byte _nextBell; // For the ringing.
+ int32 _offsets[40];
+ byte _spriteNum;
+ SpriteType _sprites[40];
+ Common::String _filename;
+ static const int16 kOnDisk; // Value of _sprites[fv]._x when it's not in memory.
+
+ void drawSprite(int16 x, int16 y, SpriteType &sprite);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_BACKGROUND_H
diff --git a/engines/avalanche/closing.cpp b/engines/avalanche/closing.cpp
new file mode 100644
index 0000000000..1cb2e84218
--- /dev/null
+++ b/engines/avalanche/closing.cpp
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* CLOSING The closing screen and error handler. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/closing.h"
+
+#include "common/random.h"
+
+namespace Avalanche {
+
+Closing::Closing(AvalancheEngine *vm) {
+ _vm = vm;
+ warning("STUB: Closing::Closing()");
+}
+
+void Closing::getScreen(ScreenType which) {
+ warning("STUB: Closing::getScreen()");
+}
+
+void Closing::showScreen() {
+ warning("STUB: Closing::showScreen()");
+}
+
+void Closing::putIn(Common::String str, uint16 where) {
+ warning("STUB: Closing::putIn()");
+}
+
+void Closing::exitGame() {
+ static const char nouns[12][14] = {
+ "sackbut", "harpsichord", "camel", "conscience", "ice-cream", "serf",
+ "abacus", "castle", "carrots", "megaphone", "manticore", "drawbridge"
+ };
+
+ static const char verbs[12][12] = {
+ "haunt", "daunt", "tickle", "gobble", "erase", "provoke",
+ "surprise", "ignore", "stare at", "shriek at", "frighten", "quieten"
+ };
+
+ _vm->_sound->stopSound();
+
+ getScreen(kScreenNagScreen);
+ byte nounId = _vm->_rnd->getRandomNumber(11);
+ byte verbId = _vm->_rnd->getRandomNumber(11);
+ Common::String result = Common::String::format("%s will %s you", nouns[nounId], verbs[verbId]);
+ putIn(result, 1628);
+ showScreen(); // No halt- it's already set up.
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/closing.h b/engines/avalanche/closing.h
new file mode 100644
index 0000000000..25217e347e
--- /dev/null
+++ b/engines/avalanche/closing.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* CLOSING The closing screen and error handler. */
+
+#ifndef AVALANCHE_CLOSING_H
+#define AVALANCHE_CLOSING_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Closing {
+public:
+ Closing(AvalancheEngine *vm);
+ void exitGame();
+
+private:
+ // Will be needed during implementation of Closing.
+ enum ScreenType {
+ kScreenBugAlert = 1,
+ kScreenRamCram = 2,
+ kScreenNagScreen = 3,
+ kScreenTwoCopies = 5
+ };
+
+ AvalancheEngine *_vm;
+
+ void getScreen(ScreenType which);
+ void showScreen();
+ void putIn(Common::String str, uint16 where);
+
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_CLOSING_H
diff --git a/engines/avalanche/configure.engine b/engines/avalanche/configure.engine
new file mode 100644
index 0000000000..28d6a558db
--- /dev/null
+++ b/engines/avalanche/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine avalanche "Lord Avalot d'Argent" no
diff --git a/engines/avalanche/console.cpp b/engines/avalanche/console.cpp
new file mode 100644
index 0000000000..e4b52116e4
--- /dev/null
+++ b/engines/avalanche/console.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/console.h"
+#include "avalanche/avalanche.h"
+
+namespace Avalanche {
+
+AvalancheConsole::AvalancheConsole(AvalancheEngine *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("magic_lines", WRAP_METHOD(AvalancheConsole, Cmd_MagicLines));
+}
+
+AvalancheConsole::~AvalancheConsole() {
+}
+
+/**
+ * This command loads up the specified new scene number
+ */
+bool AvalancheConsole::Cmd_MagicLines(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ _vm->_showDebugLines = !_vm->_showDebugLines;
+ return false;
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/console.h b/engines/avalanche/console.h
new file mode 100644
index 0000000000..166515d913
--- /dev/null
+++ b/engines/avalanche/console.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_CONSOLE_H
+#define AVALANCHE_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Avalanche {
+
+class AvalancheEngine;
+
+class AvalancheConsole : public GUI::Debugger {
+public:
+ AvalancheConsole(AvalancheEngine *vm);
+ virtual ~AvalancheConsole(void);
+
+protected:
+ bool Cmd_MagicLines(int argc, const char **argv);
+
+private:
+ AvalancheEngine *_vm;
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_CONSOLE_H
diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp
new file mode 100644
index 0000000000..5f4f03a78b
--- /dev/null
+++ b/engines/avalanche/detection.cpp
@@ -0,0 +1,209 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+
+#include "engines/advancedDetector.h"
+#include "graphics/thumbnail.h"
+
+namespace Avalanche {
+
+uint32 AvalancheEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+const char *AvalancheEngine::getGameId() const {
+ return _gameDescription->desc.gameid;
+}
+
+static const PlainGameDescriptor avalancheGames[] = {
+ {"avalanche", "Lord Avalot d'Argent"},
+ {0, 0}
+};
+
+static const ADGameDescription gameDescriptions[] = {
+ {
+ "avalanche", 0,
+ {
+ {"avalot.sez", 0, "de10eb353228013da3d3297784f81ff9", 48763},
+ {"mainmenu.avd", 0, "89f31211af579a872045b175cc264298", 18880},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+class AvalancheMetaEngine : public AdvancedMetaEngine {
+public:
+ AvalancheMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AvalancheGameDescription), avalancheGames) {
+ }
+
+ const char *getName() const {
+ return "Avalanche";
+ }
+
+ const char *getOriginalCopyright() const {
+ return "Avalanche Engine Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.";
+ }
+
+ bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
+ bool hasFeature(MetaEngineFeature f) const;
+
+ int getMaximumSaveSlot() const { return 99; }
+ SaveStateList listSaves(const char *target) const;
+ void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool AvalancheMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
+ if (gd)
+ *engine = new AvalancheEngine(syst, (const AvalancheGameDescription *)gd);
+ return gd != 0;
+}
+
+bool AvalancheMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+SaveStateList AvalancheMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern.toUppercase();
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
+ const Common::String &fname = *filename;
+ int slotNum = atoi(fname.c_str() + fname.size() - 3);
+ if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+ Common::InSaveFile *file = saveFileMan->openForLoading(fname);
+ if (file) {
+ // Check for our signature.
+ uint32 signature = file->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L')) {
+ warning("Savegame of incompatible type!");
+ delete file;
+ continue;
+ }
+
+ // Check version.
+ byte saveVersion = file->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of incompatible version!");
+ delete file;
+ continue;
+ }
+
+ // Read name.
+ uint32 nameSize = file->readUint32LE();
+ if (nameSize >= 255) {
+ delete file;
+ continue;
+ }
+ char *name = new char[nameSize + 1];
+ file->read(name, nameSize);
+ name[nameSize] = 0;
+
+ saveList.push_back(SaveStateDescriptor(slotNum, name));
+ delete[] name;
+ delete file;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+void AvalancheMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
+SaveStateDescriptor AvalancheMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+
+ if (f) {
+ // Check for our signature.
+ uint32 signature = f->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L')) {
+ warning("Savegame of incompatible type!");
+ delete f;
+ return SaveStateDescriptor();
+ }
+
+ // Check version.
+ byte saveVersion = f->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of a too recent version!");
+ delete f;
+ return SaveStateDescriptor();
+ }
+
+ // Read the description.
+ uint32 descSize = f->readUint32LE();
+ Common::String description;
+ for (uint32 i = 0; i < descSize; i++) {
+ char actChar = f->readByte();
+ description += actChar;
+ }
+
+ SaveStateDescriptor desc(slot, description);
+
+ Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f);
+ desc.setThumbnail(thumbnail);
+
+ delete f;
+ return desc;
+ }
+ return SaveStateDescriptor();
+}
+
+} // End of namespace Avalanche
+
+#if PLUGIN_ENABLED_DYNAMIC(AVALANCHE)
+ REGISTER_PLUGIN_DYNAMIC(AVALANCHE, PLUGIN_TYPE_ENGINE, Avalanche::AvalancheMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(AVALANCHE, PLUGIN_TYPE_ENGINE, Avalanche::AvalancheMetaEngine);
+#endif
diff --git a/engines/avalanche/dialogs.cpp b/engines/avalanche/dialogs.cpp
new file mode 100644
index 0000000000..271c0b8288
--- /dev/null
+++ b/engines/avalanche/dialogs.cpp
@@ -0,0 +1,1212 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+ /* SCROLLS The scroll driver. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/dialogs.h"
+
+#include "common/random.h"
+
+namespace Avalanche {
+
+// A quasiped defines how people who aren't sprites talk. For example, quasiped
+// "A" is Dogfood. The rooms aren't stored because I'm leaving that to context.
+const QuasipedType Dialogs::kQuasipeds[16] = {
+ //_whichPed, _foregroundColor, _room, _backgroundColor, _who
+ {1, kColorLightgray, kRoomArgentPub, kColorBrown, kPeopleDogfood}, // A: Dogfood (screen 19).
+ {2, kColorGreen, kRoomArgentPub, kColorWhite, kPeopleIbythneth}, // B: Ibythneth (screen 19).
+ {2, kColorWhite, kRoomYours, kColorMagenta, kPeopleArkata}, // C: Arkata (screen 1).
+ {2, kColorBlack, kRoomLustiesRoom, kColorRed, kPeopleInvisible}, // D: Hawk (screen 23).
+ {2, kColorLightgreen, kRoomOutsideDucks, kColorBrown, kPeopleTrader}, // E: Trader (screen 50).
+ {5, kColorYellow, kRoomRobins, kColorRed, kPeopleAvalot}, // F: Avvy, tied up (scr.42)
+ {1, kColorBlue, kRoomAylesOffice, kColorWhite, kPeopleAyles}, // G: Ayles (screen 16).
+ {1, kColorBrown, kRoomMusicRoom, kColorWhite, kPeopleJacques}, // H: Jacques (screen 7).
+ {1, kColorLightgreen, kRoomNottsPub, kColorGreen, kPeopleSpurge}, // I: Spurge (screen 47).
+ {2, kColorYellow, kRoomNottsPub, kColorRed, kPeopleAvalot}, // J: Avalot (screen 47).
+ {1, kColorLightgray, kRoomLustiesRoom, kColorBlack, kPeopleDuLustie}, // K: du Lustie (screen 23).
+ {1, kColorYellow, kRoomOubliette, kColorRed, kPeopleAvalot}, // L: Avalot (screen 27).
+ {2, kColorWhite, kRoomOubliette, kColorRed, kPeopleInvisible}, // M: Avaroid (screen 27).
+ {3, kColorLightgray, kRoomArgentPub, kColorDarkgray, kPeopleMalagauche},// N: Malagauche (screen 19).
+ {4, kColorLightmagenta, kRoomNottsPub, kColorRed, kPeoplePort}, // O: Port (screen 47).
+ {1, kColorLightgreen, kRoomDucks, kColorDarkgray, kPeopleDrDuck} // P: Duck (screen 51).
+};
+
+Dialogs::Dialogs(AvalancheEngine *vm) {
+ _vm = vm;
+ _noError = true;
+
+ _aboutBox = false;
+ _talkX = 0;
+ _talkY = 0;
+ _maxLineNum = 0;
+ _scReturn = false;
+ _currentFont = kFontStyleRoman;
+ _param = 0;
+ _useIcon = 0;
+ _scrollBells = 0;
+ _underScroll = 0;
+ _shadowBoxX = 0;
+ _shadowBoxY = 0;
+}
+
+void Dialogs::init() {
+ loadFont();
+ resetScrollDriver();
+}
+
+/**
+ * Determine the color of the ready light and draw it
+ * @remarks Originally called 'state'
+ */
+void Dialogs::setReadyLight(byte state) {
+ if (_vm->_ledStatus == state)
+ return; // Already like that!
+
+ Color color = kColorBlack;
+ switch (state) {
+ case 0:
+ color = kColorBlack;
+ break; // Off
+ case 1:
+ case 2:
+ case 3:
+ color = kColorGreen;
+ break; // Hit a key
+ }
+ warning("STUB: Dialogs::setReadyLight()");
+
+ CursorMan.showMouse(false);
+ _vm->_graphics->drawReadyLight(color);
+ CursorMan.showMouse(true);
+ _vm->_ledStatus = state;
+}
+
+void Dialogs::easterEgg() {
+ warning("STUB: Scrolls::easterEgg()");
+}
+
+void Dialogs::say(int16 x, int16 y, Common::String z) {
+ FontType itw;
+ byte lz = z.size();
+
+ bool offset = x % 8 == 4;
+ x /= 8;
+ y++;
+ int16 i = 0;
+ for (int xx = 0; xx < lz; xx++) {
+ switch (z[xx]) {
+ case kControlRoman:
+ _currentFont = kFontStyleRoman;
+ break;
+ case kControlItalic:
+ _currentFont = kFontStyleItalic;
+ break;
+ default: {
+ for (int yy = 0; yy < 12; yy++)
+ itw[(byte)z[xx]][yy] = _fonts[_currentFont][(byte)z[xx]][yy + 2];
+
+ // We have to draw the characters one-by-one because of the accidental font changes.
+ i++;
+ Common::String chr(z[xx]);
+ _vm->_graphics->drawScrollText(chr, itw, 12, (x - 1) * 8 + offset * 4 + i * 8, y, kColorBlack);
+ }
+ }
+ }
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * @remarks Originally called 'normscroll'
+ */
+void Dialogs::scrollModeNormal() {
+ // Original code is:
+ // egg : array[1..8] of char = ^P^L^U^G^H+'***';
+ // this is not using kControl characters: it's the secret code to be entered to trigger the easter egg
+ // TODO: To be fixed when the Easter egg code is implemented
+ Common::String egg = Common::String::format("%c%c%c%c%c***", kControlParagraph, kControlLeftJustified, kControlNegative, kControlBell, kControlBackspace);
+ Common::String e = "(c) 1994";
+
+ setReadyLight(3);
+ _vm->_seeScroll = true;
+ _vm->_graphics->loadMouse(kCurFletch);
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ bool escape = false;
+ while (!_vm->shouldQuit() && !escape) {
+ _vm->_graphics->refreshScreen();
+ while (_vm->getEvent(event)) {
+ if ((event.type == Common::EVENT_LBUTTONUP) ||
+ ((event.type == Common::EVENT_KEYDOWN) && ((event.kbd.keycode == Common::KEYCODE_ESCAPE) ||
+ (event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_HASH) ||
+ (event.kbd.keycode == Common::KEYCODE_PLUS)))) {
+ escape = true;
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ warning("STUB: scrollModeNormal() - Check Easter Egg trigger");
+#if 0
+ char r;
+ bool oktoexit;
+ do {
+ do {
+ _vm->check(); // was "checkclick;"
+
+//#ifdef RECORD slowdown(); basher::count++; #endif
+
+ if (_vm->_enhanced->keypressede())
+ break;
+ } while (!((mrelease > 0) || (buttona1()) || (buttonb1())));
+
+ if (mrelease == 0) {
+ inkey();
+ if (aboutscroll) {
+ move(e[2 - 1], e[1 - 1], 7);
+ e[8 - 1] = inchar;
+ if (egg == e)
+ easteregg();
+ }
+ oktoexit = set::of('\15', '\33', '+', '#', eos).has(inchar);
+ if (!oktoexit) errorled();
+ }
+
+ } while (!((oktoexit) || (mrelease > 0)));
+
+//#ifdef RECORD record_one(); #endif
+
+ _vm->screturn = r == '#'; // "back door"
+#endif
+
+ setReadyLight(0);
+ _vm->_seeScroll = false;
+ _vm->_holdLeftMouse = false; // Used in Lucerna::checkclick().
+
+ warning("STUB: Scrolls::scrollModeNormal()");
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * The "asking" scroll. Used indirectly in diplayQuestion().
+ * @remarks Originally called 'dialogue'
+ */
+void Dialogs::scrollModeDialogue() {
+ _vm->_graphics->loadMouse(kCurHand);
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ while (!_vm->shouldQuit()) {
+ _vm->_graphics->refreshScreen();
+
+ _vm->getEvent(event);
+
+ Common::Point cursorPos = _vm->getMousePos();
+ cursorPos.y /= 2;
+
+ char inChar = 0;
+ if ((event.type == Common::EVENT_KEYDOWN) && (event.kbd.ascii <= 122) && (event.kbd.ascii >= 97)) {
+ inChar = (char)event.kbd.ascii;
+ Common::String temp(inChar);
+ temp.toUppercase();
+ inChar = temp[0];
+ }
+
+ if (_vm->shouldQuit() || (event.type == Common::EVENT_LBUTTONUP) || (event.type == Common::EVENT_KEYDOWN)) {
+ if (((cursorPos.x >= _shadowBoxX - 65) && (cursorPos.y >= _shadowBoxY - 24) && (cursorPos.x <= _shadowBoxX - 5) && (cursorPos.y <= _shadowBoxY - 10))
+ || (inChar == 'Y') || (inChar == 'J') || (inChar == 'O')) { // Yes, Ja, Oui
+ _scReturn = true;
+ break;
+ } else if (((cursorPos.x >= _shadowBoxX + 5) && (cursorPos.y >= _shadowBoxY - 24) && (cursorPos.x <= _shadowBoxX + 65) && (cursorPos.y <= _shadowBoxY - 10))
+ || (inChar == 'N')){ // No, Non, Nein
+ _scReturn = false;
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+}
+
+void Dialogs::store(byte what, TuneType &played) {
+ memcpy(played, played + 1, sizeof(played) - 1);
+ played[30] = what;
+}
+
+bool Dialogs::theyMatch(TuneType &played) {
+ byte mistakes = 0;
+
+ for (unsigned int i = 0; i < sizeof(played); i++) {
+ if (played[i] != _vm->kTune[i])
+ mistakes++;
+ }
+
+ return mistakes < 5;
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * Part of the harp mini-game.
+ * @remarks Originally called 'music_Scroll'
+ */
+void Dialogs::scrollModeMusic() {
+ setReadyLight(3);
+ _vm->_seeScroll = true;
+ CursorMan.showMouse(false);
+ _vm->_graphics->loadMouse(kCurFletch);
+
+ TuneType played;
+ for (unsigned int i = 0; i < sizeof(played); i++)
+ played[i] = kPitchInvalid;
+ int8 lastOne = -1, thisOne = -1; // Invalid values.
+
+ _vm->_seeScroll = true;
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ while (!_vm->shouldQuit()) {
+ _vm->_graphics->refreshScreen();
+
+ _vm->getEvent(event);
+
+ // When we stop playing?
+ if ((event.type == Common::EVENT_LBUTTONDOWN) ||
+ ((event.type == Common::EVENT_KEYDOWN) && ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)))) {
+ break;
+ }
+
+ // When we DO play:
+ if ((event.type == Common::EVENT_KEYDOWN)
+ && ((event.kbd.keycode == Common::KEYCODE_q) || (event.kbd.keycode == Common::KEYCODE_w)
+ || (event.kbd.keycode == Common::KEYCODE_e) || (event.kbd.keycode == Common::KEYCODE_r)
+ || (event.kbd.keycode == Common::KEYCODE_t) || (event.kbd.keycode == Common::KEYCODE_y)
+ || (event.kbd.keycode == Common::KEYCODE_u) || (event.kbd.keycode == Common::KEYCODE_i)
+ || (event.kbd.keycode == Common::KEYCODE_o) || (event.kbd.keycode == Common::KEYCODE_p)
+ || (event.kbd.keycode == Common::KEYCODE_LEFTBRACKET) || (event.kbd.keycode == Common::KEYCODE_RIGHTBRACKET))) {
+ byte value;
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_q:
+ value = 0;
+ break;
+ case Common::KEYCODE_w:
+ value = 1;
+ break;
+ case Common::KEYCODE_e:
+ value = 2;
+ break;
+ case Common::KEYCODE_r:
+ value = 3;
+ break;
+ case Common::KEYCODE_t:
+ value = 4;
+ break;
+ case Common::KEYCODE_y:
+ value = 5;
+ break;
+ case Common::KEYCODE_u:
+ value = 6;
+ break;
+ case Common::KEYCODE_i:
+ value = 7;
+ break;
+ case Common::KEYCODE_o:
+ value = 8;
+ break;
+ case Common::KEYCODE_p:
+ value = 9;
+ break;
+ case Common::KEYCODE_LEFTBRACKET:
+ value = 10;
+ break;
+ case Common::KEYCODE_RIGHTBRACKET:
+ value = 11;
+ break;
+ default:
+ break;
+ }
+
+ lastOne = thisOne;
+ thisOne = value;
+
+ _vm->_sound->playNote(_vm->kNotes[thisOne], 100);
+ _vm->_system->delayMillis(200);
+
+ if (!_vm->_bellsAreRinging) { // These handle playing the right tune.
+ if (thisOne < lastOne)
+ store(kPitchLower, played);
+ else if (thisOne == lastOne)
+ store(kPitchSame, played);
+ else
+ store(kPitchHigher, played);
+ }
+
+ if (theyMatch(played)) {
+ setReadyLight(0);
+ _vm->_timer->addTimer(8, Timer::kProcJacquesWakesUp, Timer::kReasonJacquesWakingUp);
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ _vm->_seeScroll = false;
+ CursorMan.showMouse(true);
+}
+
+void Dialogs::resetScrollDriver() {
+ _scrollBells = 0;
+ _currentFont = kFontStyleRoman;
+ _useIcon = 0;
+ _vm->_interrogation = 0; // Always reset after a scroll comes up.
+}
+
+/**
+ * Rings the bell x times
+ * @remarks Originally called 'dingdongbell'
+ */
+void Dialogs::ringBell() {
+ for (int i = 0; i < _scrollBells; i++)
+ _vm->errorLed(); // Ring the bell "_scrollBells" times.
+}
+
+/**
+ * This moves the mouse pointer off the scroll so that you can read it.
+ * @remarks Originally called 'dodgem'
+ */
+void Dialogs::dodgem() {
+ _dodgeCoord = _vm->getMousePos();
+ g_system->warpMouse(_dodgeCoord.x, _underScroll); // Move the pointer off the scroll.
+}
+
+/**
+ * This is the opposite of Dodgem.
+ * It moves the mouse pointer back, IF you haven't moved it in the meantime.
+ * @remarks Originally called 'undodgem'
+ */
+void Dialogs::unDodgem() {
+ Common::Point actCoord = _vm->getMousePos();
+ if ((actCoord.x == _dodgeCoord.x) && (actCoord.y == _underScroll))
+ g_system->warpMouse(_dodgeCoord.x, _dodgeCoord.y); // No change, so restore the pointer's original position.
+}
+
+void Dialogs::drawScroll(DialogFunctionType modeFunc) {
+ int16 lx = 0;
+ int16 ly = (_maxLineNum + 1) * 6;
+ int16 ex;
+ for (int i = 0; i <= _maxLineNum; i++) {
+ ex = _scroll[i].size() * 8;
+ if (lx < ex)
+ lx = ex;
+ }
+ int16 mx = 320;
+ int16 my = 100; // Getmaxx & getmaxy div 2, both.
+ lx /= 2;
+ ly -= 2;
+
+ if ((1 <= _useIcon) && (_useIcon <= 34))
+ lx += kHalfIconWidth;
+
+ CursorMan.showMouse(false);
+ _vm->_graphics->drawScroll(mx, lx, my, ly);
+
+ mx -= lx;
+ my -= ly + 2;
+
+ bool centre = false;
+
+ byte iconIndent = 0;
+ switch (_useIcon) {
+ case 0:
+ iconIndent = 0;
+ break; // No icon.
+ case 34:
+ _vm->_graphics->drawSign("about", 28, 76, 15);
+ iconIndent = 0;
+ break;
+ case 35:
+ _vm->_graphics->drawSign("gameover", 52, 59, 71);
+ iconIndent = 0;
+ break;
+ }
+
+ if ((1 <= _useIcon) && (_useIcon <= 33)) { // Standard icon.
+ _vm->_graphics->drawIcon(mx, my + ly / 2, _useIcon);
+ iconIndent = 53;
+ }
+
+ for (int i = 0; i <= _maxLineNum; i++) {
+ if (!_scroll[i].empty())
+ switch (_scroll[i][_scroll[i].size() - 1]) {
+ case kControlCenter:
+ centre = true;
+ _scroll[i].deleteLastChar();
+ break;
+ case kControlLeftJustified:
+ centre = false;
+ _scroll[i].deleteLastChar();
+ break;
+ case kControlQuestion:
+ _shadowBoxX = mx + lx;
+ _shadowBoxY = my + ly;
+ _scroll[i].setChar(' ', 0);
+ _vm->_graphics->drawShadowBox(_shadowBoxX - 65, _shadowBoxY - 24, _shadowBoxX - 5, _shadowBoxY - 10, "Yes.");
+ _vm->_graphics->drawShadowBox(_shadowBoxX + 5, _shadowBoxY - 24, _shadowBoxX + 65, _shadowBoxY - 10, "No.");
+ break;
+ }
+
+ if (centre)
+ say(320 - _scroll[i].size() * 4 + iconIndent, my, _scroll[i]);
+ else
+ say(mx + iconIndent, my, _scroll[i]);
+
+ my += 12;
+ }
+
+ _underScroll = (my + 3) * 2; // Multiplying because of the doubled screen height.
+ ringBell();
+
+ _vm->_dropsOk = false;
+ dodgem();
+
+ (this->*modeFunc)();
+
+ unDodgem();
+ _vm->_dropsOk = true;
+
+ resetScrollDriver();
+}
+
+void Dialogs::drawBubble(DialogFunctionType modeFunc) {
+ Common::Point points[3];
+
+ CursorMan.showMouse(false);
+ int16 xl = 0;
+ int16 yl = (_maxLineNum + 1) * 5;
+ for (int i = 0; i <= _maxLineNum; i++) {
+ uint16 textWidth = _scroll[i].size() * 8;
+ if (textWidth > xl)
+ xl = textWidth;
+ }
+ xl /= 2;
+
+ int16 xw = xl + 18;
+ int16 yw = yl + 7;
+ int16 my = yw * 2 - 2;
+ int16 xc = 0;
+
+ if (_talkX - xw < 0)
+ xc = -(_talkX - xw);
+ if (_talkX + xw > 639)
+ xc = 639 - (_talkX + xw);
+
+ // Compute triangle coords for the tail of the bubble
+ points[0].x = _talkX - 10;
+ points[0].y = yw;
+ points[1].x = _talkX + 10;
+ points[1].y = yw;
+ points[2].x = _talkX;
+ points[2].y = _talkY;
+
+ _vm->_graphics->prepareBubble(xc, xw, my, points);
+
+ // Draw the text of the bubble. The centering of the text was improved here compared to Pascal's settextjustify().
+ // The font is not the same that outtextxy() uses in Pascal. I don't have that, so I used characters instead.
+ // It's almost the same, only notable differences are '?', '!', etc.
+ for (int i = 0; i <= _maxLineNum; i++) {
+ int16 x = xc + _talkX - _scroll[i].size() / 2 * 8;
+ bool offset = _scroll[i].size() % 2;
+ _vm->_graphics->drawScrollText(_scroll[i], _vm->_font, 8, x - offset * 4, (i * 10) + 12, _vm->_graphics->_talkFontColor);
+ }
+
+ ringBell();
+ CursorMan.showMouse(false);
+ _vm->_dropsOk = false;
+
+ // This does the actual drawing to the screen.
+ (this->*modeFunc)();
+
+ _vm->_dropsOk = true;
+ CursorMan.showMouse(true); // sink;
+ resetScrollDriver();
+}
+
+void Dialogs::reset() {
+ _maxLineNum = 0;
+ for (int i = 0; i < 15; i++) {
+ if (!_scroll[i].empty())
+ _scroll[i].clear();
+ }
+}
+
+/**
+ * Natural state of bubbles
+ * @remarks Originally called 'natural'
+ */
+void Dialogs::setBubbleStateNatural() {
+ _talkX = 320;
+ _talkY = 200;
+ _vm->_graphics->setDialogColor(kColorDarkgray, kColorWhite);
+}
+
+Common::String Dialogs::displayMoney() {
+ Common::String result;
+
+ if (_vm->_money < 12) { // just pence
+ result = Common::String::format("%dd", _vm->_money);
+ } else if (_vm->_money < 240) { // shillings & pence
+ if ((_vm->_money % 12) == 0)
+ result = Common::String::format("%d/-", _vm->_money / 12);
+ else
+ result = Common::String::format("%d/%d", _vm->_money / 12, _vm->_money % 12);
+ } else { // L, s & d
+ result = Common::String::format("\x9C%d.%d.%d", _vm->_money / 240, (_vm->_money / 12) % 20,
+ _vm->_money % 12);
+ }
+ if (_vm->_money > 12) {
+ Common::String extraStr = Common::String::format(" (that's %dd)", _vm->_money);
+ result += extraStr;
+ }
+
+ return result;
+}
+
+/**
+ * Strip trailing character in a string
+ * @remarks Originally called 'strip'
+ */
+void Dialogs::stripTrailingSpaces(Common::String &str) {
+ while (str.lastChar() == ' ')
+ str.deleteLastChar();
+ // We don't use String::trim() here because we need the leading whitespaces.
+}
+
+/**
+ * Does the word wrapping.
+ */
+void Dialogs::solidify(byte n) {
+ if (!_scroll[n].contains(' '))
+ return; // No spaces.
+
+ // So there MUST be a space there, somewhere...
+ do {
+ _scroll[n + 1] = _scroll[n][_scroll[n].size() - 1] + _scroll[n + 1];
+ _scroll[n].deleteLastChar();
+ } while (_scroll[n][_scroll[n].size() - 1] != ' ');
+
+ stripTrailingSpaces(_scroll[n]);
+}
+
+/**
+ * @remarks Originally called 'calldriver'
+ * Display text by calling the dialog driver. It unifies the function of the original
+ * 'calldriver' and 'display' by using Common::String instead of a private buffer.
+ */
+void Dialogs::displayText(Common::String text) {
+// bool was_virtual; // Was the mouse cursor virtual on entry to this proc?
+ warning("STUB: Scrolls::calldrivers()");
+
+ _vm->_sound->stopSound();
+
+ setReadyLight(0);
+ _scReturn = false;
+ bool mouthnext = false;
+ bool callSpriteRun = true; // Only call sprite_run the FIRST time.
+
+ switch (text.lastChar()) {
+ case kControlToBuffer:
+ text.deleteLastChar();
+ break; // ^D = (D)on't include pagebreak
+ case kControlSpeechBubble:
+ case kControlQuestion:
+ break; // ^B = speech (B)ubble, ^Q = (Q)uestion in dialogue box
+ default:
+ text.insertChar(kControlParagraph, text.size());
+ }
+
+ for (uint16 i = 0; i < text.size(); i++) {
+ if (mouthnext) {
+ if (text[i] == kControlRegister)
+ _param = 0;
+ else if (('0' <= text[i]) && (text[i] <= '9'))
+ _param = text[i] - 48;
+ else if (('A' <= text[i]) && (text[i] <= 'Z'))
+ _param = text[i] - 55;
+
+ mouthnext = false;
+ } else {
+ switch (text[i]) {
+ case kControlParagraph:
+ if ((_maxLineNum == 0) && (_scroll[0].empty()))
+ break;
+
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ drawScroll(&Avalanche::Dialogs::scrollModeNormal);
+
+ reset();
+
+ if (_scReturn)
+ return;
+ break;
+ case kControlBell:
+ _scrollBells++;
+ break;
+ case kControlSpeechBubble:
+ if ((_maxLineNum == 0) && (_scroll[0].empty()))
+ break;
+
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ if (_param == 0)
+ setBubbleStateNatural();
+ else if ((1 <= _param) && (_param <= 9)) {
+ assert(_param - 1 < _vm->_animation->kSpriteNumbMax);
+ AnimationType *spr = _vm->_animation->_sprites[_param - 1];
+ if ((_param > _vm->_animation->kSpriteNumbMax) || (!spr->_quick)) { // Not valid.
+ _vm->errorLed();
+ setBubbleStateNatural();
+ } else
+ spr->chatter(); // Normal sprite talking routine.
+ } else if ((10 <= _param) && (_param <= 36)) {
+ // Quasi-peds. (This routine performs the same
+ // thing with QPs as triptype.chatter does with the
+ // sprites.)
+ assert(_param - 10 < 16);
+ PedType *quasiPed = &_vm->_peds[kQuasipeds[_param - 10]._whichPed];
+ _talkX = quasiPed->_x;
+ _talkY = quasiPed->_y; // Position.
+
+ _vm->_graphics->setDialogColor(kQuasipeds[_param - 10]._backgroundColor, kQuasipeds[_param - 10]._textColor);
+ } else {
+ _vm->errorLed(); // Not valid.
+ setBubbleStateNatural();
+ }
+
+ drawBubble(&Avalanche::Dialogs::scrollModeNormal);
+
+ reset();
+
+ if (_scReturn)
+ return;
+ break;
+
+ // CHECME: The whole kControlNegative block seems completely unused, as the only use (the easter egg check) is a false positive
+ case kControlNegative:
+ switch (_param) {
+ case 1:
+ displayText(displayMoney() + kControlToBuffer); // Insert cash balance. (Recursion)
+ break;
+ case 2: {
+ int pwdId = _vm->_parser->kFirstPassword + _vm->_passwordNum;
+ displayText(_vm->_parser->_vocabulary[pwdId]._word + kControlToBuffer);
+ }
+ break;
+ case 3:
+ displayText(_vm->_favoriteDrink + kControlToBuffer);
+ break;
+ case 4:
+ displayText(_vm->_favoriteSong + kControlToBuffer);
+ break;
+ case 5:
+ displayText(_vm->_worstPlaceOnEarth + kControlToBuffer);
+ break;
+ case 6:
+ displayText(_vm->_spareEvening + kControlToBuffer);
+ break;
+ case 9: {
+ Common::String tmpStr = Common::String::format("%d,%d%c",_vm->_catacombX, _vm->_catacombY, kControlToBuffer);
+ displayText(tmpStr);
+ }
+ break;
+ case 10:
+ switch (_vm->_boxContent) {
+ case 0: // Sixpence.
+ displayScrollChain('Q', 37); // You find the sixpence.
+ _vm->_money += 6;
+ _vm->_boxContent = _vm->_parser->kNothing;
+ _vm->incScore(2);
+ return;
+ case Parser::kNothing:
+ displayText("nothing at all. It's completely empty.");
+ break;
+ default:
+ displayText(_vm->getItem(_vm->_boxContent) + '.');
+ }
+ break;
+ case 11:
+ for (int j = 0; j < kObjectNum; j++) {
+ if (_vm->_objects[j])
+ displayText(_vm->getItem(j) + ", " + kControlToBuffer);
+ }
+ break;
+ }
+ break;
+ case kControlIcon:
+ _useIcon = _param;
+ break;
+ case kControlNewLine:
+ _maxLineNum++;
+ break;
+ case kControlQuestion:
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ _maxLineNum++;
+ _scroll[_maxLineNum] = kControlQuestion;
+
+ drawScroll(&Avalanche::Dialogs::scrollModeDialogue);
+ reset();
+ break;
+ case kControlRegister:
+ mouthnext = true;
+ break;
+ case kControlInsertSpaces:
+ for (int j = 0; j < 9; j++)
+ _scroll[_maxLineNum] += ' ';
+ break;
+ default: // Add new char.
+ if (_scroll[_maxLineNum].size() == 50) {
+ solidify(_maxLineNum);
+ _maxLineNum++;
+ }
+ _scroll[_maxLineNum] += text[i];
+ break;
+ }
+ }
+ }
+}
+
+void Dialogs::setTalkPos(int16 x, int16 y) {
+ _talkX = x;
+ _talkY = y;
+}
+
+int16 Dialogs::getTalkPosX() {
+ return _talkX;
+}
+
+bool Dialogs::displayQuestion(Common::String question) {
+ displayText(question + kControlNewLine + kControlQuestion);
+
+ if (_scReturn && (_vm->_rnd->getRandomNumber(1) == 0)) { // Half-and-half chance.
+ Common::String tmpStr = Common::String::format("...Positive about that?%cI%c%c%c", kControlRegister, kControlIcon, kControlNewLine, kControlQuestion);
+ displayText(tmpStr); // Be annoying!
+ if (_scReturn && (_vm->_rnd->getRandomNumber(3) == 3)) { // Another 25% chance
+ // \? are used to avoid that ??! is parsed as a trigraph
+ tmpStr = Common::String::format("%c100%% certain\?\?!%c%c%c%c", kControlInsertSpaces, kControlInsertSpaces, kControlIcon, kControlNewLine, kControlQuestion);
+ displayText(tmpStr); // Be very annoying!
+ }
+ }
+
+ return _scReturn;
+}
+
+void Dialogs::loadFont() {
+ Common::File file;
+
+ if (!file.open("avalot.fnt"))
+ error("AVALANCHE: Scrolls: File not found: avalot.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_fonts[0][i], 16);
+ file.close();
+
+ if (!file.open("avitalic.fnt"))
+ error("AVALANCHE: Scrolls: File not found: avitalic.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_fonts[1][i], 16);
+ file.close();
+
+ if (!file.open("ttsmall.fnt"))
+ error("AVALANCHE: Scrolls: File not found: ttsmall.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_vm->_font[i],16);
+ file.close();
+}
+
+/**
+ * Practically this one is a mini-game which called when you play the harp in the monastery.
+ * @remarks Originally called 'musical_scroll'
+ */
+void Dialogs::displayMusicalScroll() {
+ Common::String tmpStr = Common::String::format("To play the harp...%c%cUse these keys:%c%cQ W E R T Y U I O P [ ]%c%cOr press Enter to stop playing.%c",
+ kControlNewLine, kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlNewLine, kControlNewLine, kControlToBuffer);
+ displayText(tmpStr);
+
+ _vm->spriteRun();
+ CursorMan.showMouse(false);
+ drawScroll(&Avalanche::Dialogs::scrollModeMusic);
+ CursorMan.showMouse(true);
+ reset();
+}
+
+void Dialogs::unSkrimble(Common::String &text) {
+ for (uint16 i = 0; i < text.size(); i++)
+ text.setChar((~(text[i] - (i + 1))) % 256, i);
+}
+
+void Dialogs::doTheBubble(Common::String &text) {
+ text.insertChar(kControlSpeechBubble, text.size());
+ assert(text.size() < 2000);
+}
+
+/**
+ * Display a string in a scroll
+ * @remarks Originally called 'dixi'
+ */
+void Dialogs::displayScrollChain(char block, byte point, bool report, bool bubbling) {
+ Common::File indexfile;
+ if (!indexfile.open("avalot.idx"))
+ error("AVALANCHE: Visa: File not found: avalot.idx");
+
+ bool error = false;
+
+ indexfile.seek((toupper(block) - 'A') * 2);
+ uint16 idx_offset = indexfile.readUint16LE();
+ if (idx_offset == 0)
+ error = true;
+
+ indexfile.seek(idx_offset + point * 2);
+ uint16 sez_offset = indexfile.readUint16LE();
+ if (sez_offset == 0)
+ error = true;
+
+ indexfile.close();
+
+ _noError = !error;
+
+ if (error) {
+ if (report) {
+ Common::String todisplay = Common::String::format("%cError accessing scroll %c%d", kControlBell, block, point);
+ displayText(todisplay);
+ }
+ return;
+ }
+
+ Common::File sezfile;
+ if (!sezfile.open("avalot.sez"))
+ ::error("AVALANCHE: Visa: File not found: avalot.sez");
+
+ sezfile.seek(sez_offset);
+ uint16 _bufSize = sezfile.readUint16LE();
+ assert(_bufSize < 2000);
+ char *_buffer = new char[_bufSize];
+ sezfile.read(_buffer, _bufSize);
+ sezfile.close();
+ Common::String text(_buffer, _bufSize);
+ delete[] _buffer;
+
+ unSkrimble(text);
+ if (bubbling)
+ doTheBubble(text);
+ displayText(text);
+}
+
+/**
+ * Start speech
+ * @remarks Originally called 'speech'
+ */
+void Dialogs::speak(byte who, byte subject) {
+ if (subject == 0) { // No subject.
+ displayScrollChain('S', who, false, true);
+ return;
+ }
+
+ // Subject given.
+ _noError = false; // Assume that until we know otherwise.
+
+ Common::File indexfile;
+ if (!indexfile.open("converse.avd"))
+ error("AVALANCHE: Visa: File not found: converse.avd");
+
+ indexfile.seek(who * 2 - 2);
+ uint16 idx_offset = indexfile.readUint16LE();
+ uint16 next_idx_offset = indexfile.readUint16LE();
+
+ if ((idx_offset == 0) || ((((next_idx_offset - idx_offset) / 2) - 1) < subject))
+ return;
+
+ indexfile.seek(idx_offset + subject * 2);
+ uint16 sezOffset = indexfile.readUint16LE();
+ if ((sezOffset == 0) || (indexfile.err()))
+ return;
+ indexfile.close();
+
+ Common::File sezfile;
+ if (!sezfile.open("avalot.sez"))
+ error("AVALANCHE: Visa: File not found: avalot.sez");
+
+ sezfile.seek(sezOffset);
+ uint16 _bufSize = sezfile.readUint16LE();
+ assert(_bufSize < 2000);
+ char *_buffer = new char[_bufSize];
+ sezfile.read(_buffer, _bufSize);
+ sezfile.close();
+ Common::String text(_buffer, _bufSize);
+ delete[] _buffer;
+
+ unSkrimble(text);
+ doTheBubble(text);
+ displayText(text);
+
+ _noError = true;
+}
+
+void Dialogs::talkTo(byte whom) {
+ if (_vm->_parser->_person == kPeoplePardon) {
+ _vm->_parser->_person = (People)_vm->_subjectNum;
+ _vm->_subjectNum = 0;
+ }
+
+ if (_vm->_subjectNum == 0) {
+ switch (whom) {
+ case kPeopleSpludwick:
+ if ((_vm->_lustieIsAsleep) & (!_vm->_objects[kObjectPotion - 1])) {
+ displayScrollChain('Q', 68);
+ _vm->_objects[kObjectPotion - 1] = true;
+ _vm->refreshObjectList();
+ _vm->incScore(3);
+ return;
+ } else if (_vm->_talkedToCrapulus) {
+ // Spludwick - what does he need?
+ // 0 - let it through to use normal routine.
+ switch (_vm->_givenToSpludwick) {
+ case 1: // Fallthrough is intended.
+ case 2: {
+ Common::String objStr = _vm->getItem(AvalancheEngine::kSpludwicksOrder[_vm->_givenToSpludwick]);
+ Common::String tmpStr = Common::String::format("Can you get me %s, please?%c2%c",
+ objStr.c_str(), kControlRegister, kControlSpeechBubble);
+ displayText(tmpStr);
+ }
+ return;
+ case 3:
+ displayScrollChain('Q', 30); // Need any help with the game?
+ return;
+ }
+ } else {
+ displayScrollChain('Q', 42); // Haven't talked to Crapulus. Go and talk to him.
+ return;
+ }
+ break;
+ case kPeopleIbythneth:
+ if (_vm->_givenBadgeToIby) {
+ displayScrollChain('Q', 33); // Thanks a lot!
+ return; // And leave the proc.
+ }
+ break; // Or... just continue, 'cos he hasn't got it.
+ case kPeopleDogfood:
+ if (_vm->_wonNim) { // We've won the game.
+ displayScrollChain('Q', 6); // "I'm Not Playing!"
+ return; // Zap back.
+ } else
+ _vm->_askedDogfoodAboutNim = true;
+ break;
+ case kPeopleAyles:
+ if (!_vm->_aylesIsAwake) {
+ displayScrollChain('Q', 43); // He's fast asleep!
+ return;
+ } else if (!_vm->_givenPenToAyles) {
+ displayScrollChain('Q', 44); // Can you get me a pen, Avvy?
+ return;
+ }
+ break;
+
+ case kPeopleJacques:
+ displayScrollChain('Q', 43);
+ return;
+
+ case kPeopleGeida:
+ if (_vm->_givenPotionToGeida)
+ _vm->_geidaFollows = true;
+ else {
+ displayScrollChain('U', 17);
+ return;
+ }
+ break;
+ case kPeopleSpurge:
+ if (!_vm->_sittingInPub) {
+ displayScrollChain('Q', 71); // Try going over and sitting down.
+ return;
+ } else {
+ if (_vm->_spurgeTalkCount < 5)
+ _vm->_spurgeTalkCount++;
+ if (_vm->_spurgeTalkCount > 1) { // no. 1 falls through
+ displayScrollChain('Q', 70 + _vm->_spurgeTalkCount);
+ return;
+ }
+ }
+ break;
+ }
+ // On a subject. Is there any reason to block it?
+ } else if ((whom == kPeopleAyles) && (!_vm->_aylesIsAwake)) {
+ displayScrollChain('Q', 43); // He's fast asleep!
+ return;
+ }
+
+ if (whom > 149)
+ whom -= 149;
+
+ bool noMatches = true;
+ for (int i = 0; i < _vm->_animation->kSpriteNumbMax; i++) {
+ if (_vm->_animation->_sprites[i]->_characterId == whom) {
+ Common::String tmpStr = Common::String::format("%c%c%c", kControlRegister, i + 49, kControlToBuffer);
+ displayText(tmpStr);
+ noMatches = false;
+ break;
+ }
+ }
+
+ if (noMatches) {
+ Common::String tmpStr = Common::String::format("%c%c%c", kControlRegister, kControlRegister, kControlToBuffer);
+ displayText(tmpStr);
+ }
+
+ speak(whom, _vm->_subjectNum);
+
+ if (!_noError)
+ displayScrollChain('N', whom); // File not found!
+
+ if ((_vm->_subjectNum == 0) && ((whom + 149) == kPeopleCrapulus)) { // Crapulus: get the badge - first time only
+ _vm->_objects[kObjectBadge - 1] = true;
+ _vm->refreshObjectList();
+ displayScrollChain('Q', 1); // Circular from Cardiff.
+ _vm->_talkedToCrapulus = true;
+ _vm->setRoom(kPeopleCrapulus, kRoomDummy); // Crapulus walks off.
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->_vanishIfStill = true;
+ spr->walkTo(2); // Walks away.
+
+ _vm->incScore(2);
+ }
+}
+
+/**
+ * This makes Avalot say the response.
+ * @remarks Originally called 'sayit'
+ */
+void Dialogs::sayIt(Common::String str) {
+ Common::String x = str;
+ x.setChar(toupper(x[0]), 0);
+ Common::String tmpStr = Common::String::format("%c1%s.%c%c2", kControlRegister, x.c_str(), kControlSpeechBubble, kControlRegister);
+ displayText(tmpStr);
+}
+
+Common::String Dialogs::personSpeaks() {
+ if ((_vm->_parser->_person == kPeoplePardon) || (_vm->_parser->_person == kPeopleNone)) {
+ if ((_vm->_him == kPeoplePardon) || (_vm->getRoom(_vm->_him) != _vm->_room))
+ _vm->_parser->_person = _vm->_her;
+ else
+ _vm->_parser->_person = _vm->_him;
+ }
+
+ if (_vm->getRoom(_vm->_parser->_person) != _vm->_room) {
+ return Common::String::format("%c1", kControlRegister); // Avvy himself!
+ }
+
+ bool found = false; // The _person we're looking for's code is in _person.
+ Common::String tmpStr;
+
+ for (int i = 0; i < _vm->_animation->kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _vm->_animation->_sprites[i];
+ if (curSpr->_quick && (curSpr->_characterId + 149 == _vm->_parser->_person)) {
+ tmpStr += Common::String::format("%c%c", kControlRegister, '1' + i);
+ found = true;
+ }
+ }
+
+ if (found)
+ return tmpStr;
+
+ for (int i = 0; i < 16; i++) {
+ if ((kQuasipeds[i]._who == _vm->_parser->_person) && (kQuasipeds[i]._room == _vm->_room))
+ tmpStr += Common::String::format("%c%c", kControlRegister, 'A' + i);
+ }
+
+ return tmpStr;
+}
+
+/**
+ * Display a message when (uselessly) giving an object away
+ * @remarks Originally called 'heythanks'
+ */
+void Dialogs::sayThanks(byte thing) {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("Hey, thanks!%c(But now, you've lost it!)", kControlSpeechBubble);
+ displayText(tmpStr);
+
+ if (thing < kObjectNum)
+ _vm->_objects[thing] = false;
+}
+
+/**
+ * Display a 'Hello' message
+ */
+void Dialogs::sayHello() {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("Hello.%c", kControlSpeechBubble);
+ displayText(tmpStr);
+}
+
+/**
+ * Display a 'OK' message
+ */
+void Dialogs::sayOK() {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("That's OK.%c", kControlSpeechBubble);
+ displayText(tmpStr);
+}
+
+/**
+ * Display a 'Silly' message
+ * @remarks Originally called 'silly'
+ */
+void Dialogs::saySilly() {
+ displayText("Don't be silly!");
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/dialogs.h b/engines/avalanche/dialogs.h
new file mode 100644
index 0000000000..43e6a4fec6
--- /dev/null
+++ b/engines/avalanche/dialogs.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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+ /* SCROLLS The scroll driver. */
+
+#ifndef AVALANCHE_DIALOGS_H
+#define AVALANCHE_DIALOGS_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Dialogs;
+
+typedef void (Dialogs::*DialogFunctionType)();
+
+class Dialogs {
+public:
+ bool _aboutBox; // Is this the about box? - Used in scrollModeNormal(), not yet fully implemented
+ FontType _fonts[2];
+
+ Dialogs(AvalancheEngine *vm);
+
+ void init();
+ void reset();
+ void setReadyLight(byte state);
+ void displayText(Common::String text);
+ bool displayQuestion(Common::String question);
+ void setTalkPos(int16 x, int16 y);
+ int16 getTalkPosX();
+ void setBubbleStateNatural();
+ void displayMusicalScroll();
+ void displayScrollChain(char block, byte point, bool report = true, bool bubbling = false);
+ void talkTo(byte whom);
+ void sayIt(Common::String str);
+ Common::String personSpeaks();
+ void sayThanks(byte thing);
+ void sayHello();
+ void sayOK();
+ void saySilly();
+private:
+ AvalancheEngine *_vm;
+ int16 _talkX, _talkY;
+
+ enum FontStyle {
+ kFontStyleRoman,
+ kFontStyleItalic
+ };
+
+ static const int16 kHalfIconWidth = 19;
+ static const QuasipedType kQuasipeds[16];
+
+ Common::String _scroll[15];
+ Common::Point _dodgeCoord;
+ byte _maxLineNum;
+ bool _scReturn;
+ bool _noError;
+ byte _currentFont;
+ byte _param; // For using arguments code
+ byte _useIcon;
+ byte _scrollBells; // no. of times to ring the bell
+ int16 _underScroll; // Y-coord of just under the scroll text.
+ int16 _shadowBoxX, _shadowBoxY;
+
+ void drawBubble(DialogFunctionType modeFunc);
+ void drawScroll(DialogFunctionType modeFunc);
+ void scrollModeNormal();
+ void scrollModeDialogue();
+ void scrollModeMusic();
+
+ // These 2 are used only in musicalScroll().
+ void store(byte what, TuneType &played);
+ bool theyMatch(TuneType &played);
+ void stripTrailingSpaces(Common::String &str);
+ void solidify(byte n);
+ void dodgem();
+ void unDodgem();
+
+ Common::String displayMoney();
+ void easterEgg();
+ void say(int16 x, int16 y, Common::String text);
+ void resetScrollDriver();
+ void ringBell();
+ void loadFont();
+
+ void unSkrimble(Common::String &text);
+ void doTheBubble(Common::String &text);
+ void speak(byte who, byte subject);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_DIALOGS_H
diff --git a/engines/avalanche/enums.h b/engines/avalanche/enums.h
new file mode 100644
index 0000000000..2b5db67609
--- /dev/null
+++ b/engines/avalanche/enums.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_ENUMS_H
+#define AVALANCHE_ENUMS_H
+
+namespace Avalanche {
+enum Color {
+ kColorBlack = 0, kColorBlue, kColorGreen, kColorCyan, kColorRed,
+ kColorMagenta = 5, kColorBrown, kColorLightgray, kColorDarkgray, kColorLightblue,
+ kColorLightgreen = 10, kColorLightcyan, kColorLightred, kColorLightmagenta, kColorYellow,
+ kColorWhite = 15
+};
+
+// CHECKME: kRoomBossKey is a guess
+enum Room {
+ kRoomNowhere = 0, kRoomYours = 1, kRoomOutsideYours = 2, kRoomOutsideSpludwicks = 3,
+ kRoomYourHall = 5, kRoomMusicRoom = 7, kRoomOutsideArgentPub = 9, kRoomArgentRoad = 10,
+ kRoomWiseWomans = 11, kRoomSpludwicks = 12, kRoomInsideAbbey = 13, kRoomOutsideAbbey = 14,
+ kRoomAvvysGarden = 15, kRoomAylesOffice = 16, kRoomArgentPub = 19, kRoomBrummieRoad = 20,
+ kRoomBridge = 21, kRoomLusties = 22, kRoomLustiesRoom = 23, kRoomWestHall = 25,
+ kRoomEastHall = 26, kRoomOubliette = 27, kRoomGeidas = 28, kRoomCatacombs = 29,
+ kRoomEntranceHall = 40, kRoomRobins = 42, kRoomOutsideNottsPub = 46, kRoomNottsPub = 47,
+ kRoomOutsideDucks = 50, kRoomDucks = 51, kRoomOutsideCardiffCastle = 70, kRoomInsideCardiffCastle = 71,
+ kRoomBossKey = 98, kRoomMap = 99, kRoomDummy = 177 // Dummy room
+};
+
+// Objects you can hold:
+enum Object {
+ kObjectWine = 1, kObjectMoney, kObjectBodkin, kObjectPotion, kObjectChastity,
+ kObjectBolt, kObjectCrossbow, kObjectLute, kObjectBadge, kObjectMushroom,
+ kObjectKey, kObjectBell, kObjectPrescription, kObjectPen, kObjectInk,
+ kObjectClothes, kObjectHabit, kObjectOnion, kObjectDummy = 177
+};
+
+// People who hang around this game.
+enum People {
+ // Boys:
+ kPeopleAvalot = 150, kPeopleSpludwick = 151, kPeopleCrapulus = 152, kPeopleDrDuck = 153,
+ kPeopleMalagauche = 154, kPeopleFriarTuck = 155, kPeopleRobinHood = 156, kPeopleCwytalot = 157,
+ kPeopleDuLustie = 158, kPeopleDuke = 159, kPeopleDogfood = 160, kPeopleTrader = 161,
+ kPeopleIbythneth = 162, kPeopleAyles = 163, kPeoplePort = 164, kPeopleSpurge = 165,
+ kPeopleJacques = 166,
+ // Girls:
+ kPeopleArkata = 175, kPeopleGeida = 176, kPeopleInvisible = 177, kPeopleWisewoman = 178,
+ //
+ kPeoplePardon = 254, kPeopleNone = 0
+};
+
+enum VerbCode {
+ kVerbCodeExam = 1, kVerbCodeOpen = 2, kVerbCodePause = 3, kVerbCodeGet = 4, kVerbCodeDrop = 5,
+ kVerbCodeInv = 6, kVerbCodeTalk = 7, kVerbCodeGive = 8, kVerbCodeDrink = 9, kVerbCodeLoad = 10,
+ kVerbCodeSave = 11, kVerbCodePay = 12, kVerbCodeLook = 13, kVerbCodeBreak = 14, kVerbCodeQuit = 15,
+ kVerbCodeSit = 16, kVerbCodeStand = 17, kVerbCodeGo = 18, kVerbCodeInfo = 19, kVerbCodeUndress = 20,
+ kVerbCodeWear = 21, kVerbCodePlay = 22, kVerbCodeRing = 23, kVerbCodeHelp = 24, kVerbCodeLarrypass = 25,
+ kVerbCodePhaon = 26, kVerbCodeBoss = 27, kVerbCodePee = 28, kVerbCodeCheat = 29, kVerbCodeMagic = 30,
+ kVerbCodeRestart = 31, kVerbCodeEat = 32, kVerbCodeListen = 33, kVerbCodeBuy = 34, kVerbCodeAttack = 35,
+ kVerbCodePasswd = 36, kVerbCodeDir = 37, kVerbCodeDie = 38, kVerbCodeScore = 39, kVerbCodePut = 40,
+ kVerbCodeKiss = 41, kVerbCodeClimb = 42, kVerbCodeJump = 43, kVerbCodeHiscores = 44, kVerbCodeWake = 45,
+ kVerbCodeHello = 46, kVerbCodeThanks = 47,
+ kVerbCodeSmartAlec = 249, kVerbCodeExpletive = 253, kVerbCodePardon = 254
+};
+
+enum MouseCursor {
+ kCurUpArrow = 0, kCurScrewDriver = 1, kCurRightArrow = 2, kCurFletch = 3, kCurWait = 4, kCurHand = 5,
+ kCurCrosshair = 6, kCurIBeam = 7
+};
+
+// Magic/portal constants:
+enum Magics {
+ kMagicNothing, // Ignore it if this line is touched.
+ kMagicBounce, // Bounce off this line. Not valid for portals.
+ kMagicExclaim, // Put up a chain of scrolls.
+ kMagicTransport, // Enter new room.
+ kMagicUnfinished, // Unfinished connection.
+ kMagicSpecial, // Special function.
+ kMagicOpenDoor // Opening door.
+};
+
+// Constants to replace the command characters from Pascal.
+// For more information, see: https://github.com/urukgit/avalot/wiki/Scrolldrivers
+enum ControlCharacter {
+ kControlSpeechBubble = 2, // ^B
+ kControlCenter = 3, // ^C
+ kControlToBuffer = 4, // ^D
+ kControlItalic = 6, // ^F
+ kControlBell = 7, // ^G
+ kControlBackspace = 8, // ^H
+ kControlInsertSpaces = 9, // ^I
+ kControlLeftJustified = 12, // ^L
+ kControlNewLine = 13, // ^M
+ kControlParagraph = 16, // ^P
+ kControlQuestion = 17, // ^Q
+ kControlRoman = 18, // ^R
+ kControlRegister = 19, // ^S
+ kControlNegative = 21, // ^U
+ kControlIcon = 22 // ^V
+};
+
+static const int16 kScreenWidth = 640;
+static const int16 kScreenHeight = 200;
+
+static const int16 kWalk = 3;
+static const int16 kRun = 5;
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_ENUMS_H
diff --git a/engines/avalanche/graphics.cpp b/engines/avalanche/graphics.cpp
new file mode 100644
index 0000000000..841512847f
--- /dev/null
+++ b/engines/avalanche/graphics.cpp
@@ -0,0 +1,767 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/graphics.h"
+
+#include "engines/util.h"
+#include "graphics/palette.h"
+
+namespace Avalanche {
+
+const byte GraphicManager::kEgaPaletteIndex[16] = {0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63};
+
+const MouseHotspotType GraphicManager::kMouseHotSpots[9] = {
+ {8,0}, // 0 - up-arrow
+ {0,0}, // 1 - screwdriver
+ {15,6}, // 2 - right-arrow
+ {0,0}, // 3 - fletch
+ {8,7}, // 4 - hourglass
+ {4,0}, // 5 - TTHand
+ {8,5}, // 6 - Mark's crosshairs
+ {8,7}, // 7 - I-beam
+ {0,0} // 8 - question mark
+};
+
+GraphicManager::GraphicManager(AvalancheEngine *vm) {
+ _vm = vm;
+ setDialogColor(kColorBlack, kColorWhite);
+}
+
+GraphicManager::~GraphicManager() {
+ _surface.free();
+ _magics.free();
+ _background.free();
+ _screen.free();
+ _scrolls.free();
+ _backup.free();
+
+ for (int i = 0; i < 10; i++)
+ _digits[i].free();
+ for (int i = 0; i < 9; i++)
+ _directions[i].free();
+}
+
+void GraphicManager::init() {
+ initGraphics(kScreenWidth, kScreenHeight * 2, true); // Doubling the height.
+
+ for (int i = 0; i < 64; ++i) {
+ _egaPalette[i][0] = (i >> 2 & 1) * 0xaa + (i >> 5 & 1) * 0x55;
+ _egaPalette[i][1] = (i >> 1 & 1) * 0xaa + (i >> 4 & 1) * 0x55;
+ _egaPalette[i][2] = (i & 1) * 0xaa + (i >> 3 & 1) * 0x55;
+ }
+
+ for (int i = 0; i < 16; i++)
+ g_system->getPaletteManager()->setPalette(_egaPalette[kEgaPaletteIndex[i]], i, 1);
+
+ // Set the "flesh colors":
+ g_system->getPaletteManager()->setPalette(_egaPalette[39], 13, 1);
+ g_system->getPaletteManager()->setPalette(_egaPalette[28], 5, 1);
+
+ _surface.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _magics.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _screen.create(kScreenWidth, kScreenHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+ _scrolls.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+}
+
+/**
+ * Load the scoring digits & rwlites
+ * @remarks Originally called 'load_digits'
+ */
+void GraphicManager::loadDigits() {
+ const byte digitsize = 134;
+ const byte rwlitesize = 126;
+
+ Common::File file;
+ if (!file.open("digit.avd"))
+ error("AVALANCHE: File not found: digit.avd");
+
+ for (int i = 0; i < 10; i++) {
+ file.seek(i * digitsize);
+ _digits[i] = loadPictureGraphic(file);
+ }
+
+ for (int i = 0; i < 9; i++) {
+ file.seek(10 * digitsize + i * rwlitesize);
+ _directions[i] = loadPictureGraphic(file);
+ }
+
+ file.close();
+}
+
+void GraphicManager::loadMouse(byte which) {
+ if (which == _vm->_currentMouse)
+ return;
+
+ _vm->_currentMouse = which;
+
+ Common::File f;
+ if (!f.open("mice.avd"))
+ error("AVALANCHE: Gyro: File not found: mice.avd");
+
+ Graphics::Surface cursor;
+ cursor.create(16, 32, Graphics::PixelFormat::createFormatCLUT8());
+ cursor.fillRect(Common::Rect(0, 0, 16, 32), 255);
+
+ // The AND mask.
+ f.seek(kMouseSize * 2 * which + 134);
+
+ Graphics::Surface mask = loadPictureGraphic(f);
+
+ for (int j = 0; j < mask.h; j++) {
+ for (int i = 0; i < mask.w; i++) {
+ byte pixel = *(byte *)mask.getBasePtr(i, j);
+ if (pixel == 0) {
+ *(byte *)cursor.getBasePtr(i, j * 2 ) = 0;
+ *(byte *)cursor.getBasePtr(i, j * 2 + 1) = 0;
+ }
+ }
+ }
+
+ mask.free();
+
+ // The OR mask.
+ f.seek(kMouseSize * 2 * which + 134 * 2);
+
+ mask = loadPictureGraphic(f);
+
+ for (int j = 0; j < mask.h; j++) {
+ for (int i = 0; i < mask.w; i++) {
+ byte pixel = *(byte *)mask.getBasePtr(i, j);
+ if (pixel != 0) {
+ *(byte *)cursor.getBasePtr(i, j * 2 ) = pixel;
+ *(byte *)cursor.getBasePtr(i, j * 2 + 1) = pixel;
+ }
+ }
+ }
+
+ mask.free();
+ f.close();
+
+ CursorMan.replaceCursor(cursor.getPixels(), 16, 32, kMouseHotSpots[which]._horizontal, kMouseHotSpots[which]._vertical * 2, 255, false);
+ cursor.free();
+}
+
+void GraphicManager::drawThinkPic(Common::String filename, int id) {
+ static const int16 picSize = 966;
+ Common::File file;
+ if (!file.open(filename))
+ error("drawThinkPic(): File not found: %s", filename.c_str());
+
+ file.seek(id * picSize + 65);
+ Graphics::Surface picture = loadPictureGraphic(file);
+ drawPicture(_surface, picture, 205, 170);
+
+ picture.free();
+ file.close();
+}
+
+void GraphicManager::drawToolbar() {
+ Common::File file;
+ if (!file.open("useful.avd"))
+ error("drawToolbar(): File not found: useful.avd");
+
+ file.seek(40);
+
+ CursorMan.showMouse(false);
+ Graphics::Surface picture = loadPictureGraphic(file);
+ drawPicture(_surface, picture, 5, 169);
+ CursorMan.showMouse(true);
+
+ picture.free();
+ file.close();
+}
+
+Common::Point GraphicManager::drawArc(Graphics::Surface &surface, int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ Common::Point endPoint;
+ const float convfac = M_PI / 180.0;
+
+ int32 xRadius = radius;
+ int32 yRadius = radius * kScreenWidth / (8 * kScreenHeight); // Just don't ask why...
+
+ if (xRadius == 0)
+ xRadius++;
+ if (yRadius == 0)
+ yRadius++;
+
+ // Check for an ellipse with negligable x and y radius.
+ if ((xRadius <= 1) && (yRadius <= 1)) {
+ *(byte *)_scrolls.getBasePtr(x, y) = color;
+ endPoint.x = x;
+ endPoint.y = y;
+ return endPoint;
+ }
+
+ // Check if valid angles.
+ stAngle = stAngle % 361;
+ endAngle = endAngle % 361;
+
+ // If impossible angles, then swap them!
+ if (endAngle < stAngle) {
+ uint16 tmpAngle=endAngle;
+ endAngle=stAngle;
+ stAngle=tmpAngle;
+ }
+
+ // Approximate the number of pixels required by using the circumference equation of an ellipse.
+ uint16 numOfPixels = (uint16)floor(sqrt(3.0) * sqrt(pow(double(xRadius), 2) + pow(double(yRadius), 2)) + 0.5);
+
+ // Calculate the angle precision required.
+ float delta = 90.0 / numOfPixels;
+
+ // Always just go over the first 90 degrees. Could be optimized a
+ // bit if startAngle and endAngle lie in the same quadrant, left as an
+ // exercise for the reader. :)
+ float j = 0;
+
+ // Calculate stop position, go 1 further than 90 because otherwise 1 pixel is sometimes not drawn.
+ uint16 deltaEnd = 91;
+
+ // Set the end point.
+ float tempTerm = endAngle * convfac;
+ endPoint.x = (int16)floor(xRadius * cos(tempTerm) + 0.5) + x;
+ endPoint.y = (int16)floor(yRadius * sin(tempTerm + M_PI) + 0.5) + y;
+
+ // Calculate points.
+ int16 xNext = xRadius;
+ int16 yNext = 0;
+ do {
+ int16 xTemp = xNext;
+ int16 yTemp = yNext;
+ // This is used by both sin and cos.
+ tempTerm = (j + delta) * convfac;
+
+ xNext = (int16)floor(xRadius * cos(tempTerm) + 0.5);
+ yNext = (int16)floor(yRadius * sin(tempTerm + M_PI) + 0.5);
+
+ int16 xp = x + xTemp;
+ int16 xm = x - xTemp;
+ int16 yp = y + yTemp;
+ int16 ym = y - yTemp;
+
+ if ((j >= stAngle) && (j <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xp, yp) = color;
+
+ if (((180 - j) >= stAngle) && ((180 - j) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xm, yp) = color;
+
+ if (((j + 180) >= stAngle) && ((j + 180) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xm, ym) = color;
+
+ if (((360 - j) >= stAngle) && ((360 - j) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xp, ym) = color;
+
+ j += delta;
+ } while (j <= deltaEnd);
+
+ return endPoint;
+}
+
+Common::Point GraphicManager::drawScreenArc(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ return drawArc(_surface, x, y, stAngle, endAngle, radius, color);
+}
+
+void GraphicManager::drawPieSlice(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ while (radius > 0)
+ drawArc(_scrolls, x, y, stAngle, endAngle, radius--, color);
+}
+
+void GraphicManager::drawTriangle(Common::Point *p, Color color) {
+ // Draw the borders with a marking color.
+ _scrolls.drawLine(p[0].x, p[0].y, p[1].x, p[1].y, 255);
+ _scrolls.drawLine(p[1].x, p[1].y, p[2].x, p[2].y, 255);
+ _scrolls.drawLine(p[2].x, p[2].y, p[0].x, p[0].y, 255);
+
+ // Get the top and the bottom of the triangle.
+ uint16 maxY = p[0].y, minY = p[0].y;
+ for (int i = 1; i < 3; i++) {
+ if (p[i].y < minY)
+ minY = p[i].y;
+ if (p[i].y > maxY)
+ maxY = p[i].y;
+ }
+
+ // Fill the triangle.
+ for (uint16 y = minY; y <= maxY; y++) {
+ uint16 x = 0;
+ while (*(byte *)_scrolls.getBasePtr(x, y) != 255)
+ x++;
+ uint16 minX = x;
+ uint16 maxX = x;
+ x++;
+ while ((*(byte *)_scrolls.getBasePtr(x, y) != 255) && (x != 639))
+ x++;
+ if (x != 639)
+ maxX = x;
+ if (minX != maxX)
+ _scrolls.drawLine(minX, y, maxX, y, color);
+ }
+
+ // Redraw the borders with the actual color.
+ _scrolls.drawLine(p[0].x, p[0].y, p[1].x, p[1].y, color);
+ _scrolls.drawLine(p[1].x, p[1].y, p[2].x, p[2].y, color);
+ _scrolls.drawLine(p[2].x, p[2].y, p[0].x, p[0].y, color);
+}
+
+void GraphicManager::drawText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ for (uint i = 0; i < text.size(); i++) {
+ for (int j = 0; j < fontHeight; j++) {
+ byte pixel = font[(byte)text[i]][j];
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit)
+ *(byte *)surface.getBasePtr(x + i * 8 + 7 - bit, y + j) = color;
+ }
+ }
+ }
+}
+
+void GraphicManager::drawNormalText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ drawText(_surface, text, font, fontHeight, x, y, color);
+}
+
+void GraphicManager::drawScrollText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ drawText(_scrolls, text, font, fontHeight, x, y, color);
+}
+
+void GraphicManager::drawDigit(int index, int x, int y) {
+ drawPicture(_surface, _digits[index], x, y);
+}
+
+void GraphicManager::drawDirection(int index, int x, int y) {
+ drawPicture(_surface, _directions[index], x, y);
+}
+
+void GraphicManager::drawScrollShadow(int16 x1, int16 y1, int16 x2, int16 y2) {
+ for (byte i = 0; i < 2; i ++) {
+ _scrolls.fillRect(Common::Rect(x1 + i, y1 + i, x1 + i + 1, y2 - i), kColorWhite);
+ _scrolls.fillRect(Common::Rect(x1 + i, y1 + i, x2 - i, y1 + i + 1), kColorWhite);
+
+ _scrolls.fillRect(Common::Rect(x2 - i, y1 + i, x2 - i + 1, y2 - i + 1), kColorDarkgray);
+ _scrolls.fillRect(Common::Rect(x1 + i, y2 - i, x2 - i, y2 - i + 1), kColorDarkgray);
+ }
+}
+
+void GraphicManager::drawShadowBox(int16 x1, int16 y1, int16 x2, int16 y2, Common::String text) {
+ CursorMan.showMouse(false);
+
+ drawScrollShadow(x1, y1, x2, y2);
+
+ bool offset = text.size() % 2;
+ x1 = (x2 - x1) / 2 + x1 - text.size() / 2 * 8 - offset * 3;
+ y1 = (y2 - y1) / 2 + y1 - 4;
+ drawScrollText(text, _vm->_font, 8, x1, y1, kColorBlue);
+ drawScrollText(Common::String('_'), _vm->_font, 8, x1, y1, kColorBlue);
+
+ CursorMan.showMouse(true);
+}
+
+void GraphicManager::drawMenuBar(Color color) {
+ _surface.fillRect(Common::Rect(0, 0, 640, 10), color);
+}
+
+void GraphicManager::drawMenuBlock(int x1, int y1, int x2, int y2, Color color) {
+ _surface.fillRect(Common::Rect(x1, y1, x2, y2), color);
+}
+
+void GraphicManager::drawMenuItem(int x1, int y1, int x2, int y2) {
+ _surface.fillRect(Common::Rect(x1, y1, x2, y2), kMenuBackgroundColor);
+ _surface.frameRect(Common::Rect(x1 - 1, y1 - 1, x2 + 1, y2 + 1), kMenuBorderColor);
+}
+
+void GraphicManager::drawSpeedBar(int speed) {
+ if (speed == kRun) {
+ _surface.drawLine(336, 199, 338, 199, kColorLightblue);
+ _surface.drawLine(371, 199, 373, 199, kColorYellow);
+ } else {
+ _surface.drawLine(371, 199, 373, 199, kColorLightblue);
+ _surface.drawLine(336, 199, 338, 199, kColorYellow);
+ }
+}
+void GraphicManager::drawScroll(int mx, int lx, int my, int ly) {
+ _scrolls.copyFrom(_surface);
+
+ // The right corners of the scroll.
+ drawPieSlice(mx + lx, my - ly, 0, 90, 15, kColorLightgray);
+ drawPieSlice(mx + lx, my + ly, 270, 360, 15, kColorLightgray);
+ drawArc(_scrolls, mx + lx, my - ly, 0, 90, 15, kColorRed);
+ drawArc(_scrolls, mx + lx, my + ly, 270, 360, 15, kColorRed);
+
+ // The body of the scroll.
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my + ly, mx + lx, my + ly + 6), kColorLightgray);
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my - ly - 6, mx + lx, my - ly + 1), kColorLightgray);
+ _scrolls.fillRect(Common::Rect(mx - lx - 15, my - ly, mx + lx + 15, my + ly + 1), kColorLightgray);
+
+ // The left corners of the scroll.
+ drawPieSlice(mx - lx - 31, my - ly, 0, 180, 15, kColorDarkgray);
+ drawArc(_scrolls, mx - lx - 31, my - ly, 0, 180, 15, kColorRed);
+ _scrolls.drawLine(mx - lx - 31 - 15, my - ly, mx - lx - 31 + 15, my - ly, kColorRed);
+ drawPieSlice(mx - lx - 31, my + ly, 180, 360, 15, kColorDarkgray);
+ drawArc(_scrolls, mx - lx - 31, my + ly, 180, 360, 15, kColorRed);
+ _scrolls.drawLine(mx - lx - 31 - 15, my + ly, mx - lx - 31 + 15, my + ly, kColorRed);
+
+ // The rear borders of the scroll.
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my - ly - 6, mx + lx, my - ly - 5), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my + ly + 6, mx + lx, my + ly + 7), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx - lx - 15, my - ly, mx - lx - 14, my + ly), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx + lx + 15, my - ly, mx + lx + 16, my + ly), kColorRed);
+}
+
+void GraphicManager::drawBackgroundSprite(int16 x, int16 y, SpriteType &sprite) {
+ drawPicture(_background, sprite._picture, x, y);
+}
+
+void GraphicManager::drawDebugLines() {
+ if (!_vm->_showDebugLines)
+ return;
+
+ for (int i = 0; i < _vm->_lineNum; i++) {
+ LineType *curLine = &_vm->_lines[i];
+ _surface.drawLine(curLine->_x1, curLine->_y1, curLine->_x2, curLine->_y2, curLine->_color);
+ }
+
+ for (int i = 0; i < _vm->_fieldNum; i++) {
+ FieldType *curField = &_vm->_fields[i];
+ if (curField->_x1 < 640)
+ _surface.frameRect(Common::Rect(curField->_x1, curField->_y1, curField->_x2, curField->_y2), kColorLightmagenta);
+ }
+}
+
+/**
+ * This function mimics Pascal's getimage().
+ */
+Graphics::Surface GraphicManager::loadPictureGraphic(Common::File &file) {
+ // The height and the width are stored in 2-2 bytes. We have to add 1 to each because Pascal stores the value of them -1.
+ uint16 width = file.readUint16LE() + 1;
+ uint16 height = file.readUint16LE() + 1;
+
+ Graphics::Surface picture; // We make a Surface object for the picture itself.
+ picture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Produce the picture. We read it in row-by-row, and every row has 4 planes.
+ for (int y = 0; y < height; y++) {
+ for (int8 plane = 3; plane >= 0; plane--) { // The planes are in the opposite way.
+ for (uint16 x = 0; x < width; x += 8) {
+ byte pixel = file.readByte();
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit != 0)
+ *(byte *)picture.getBasePtr(x + 7 - bit, y) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+ return picture;
+}
+
+/**
+ * Reads Row-planar EGA data.
+ * This function is our own creation, very much like the one above. The main differences are that
+ * we don't read the width and the height from the file, the planes are in a different order
+ * and we read the picture plane-by-plane.
+ */
+Graphics::Surface GraphicManager::loadPictureRaw(Common::File &file, uint16 width, uint16 height) {
+ Graphics::Surface picture;
+ picture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ for (int plane = 0; plane < 4; plane++) {
+ for (uint16 y = 0; y < height; y++) {
+ for (uint16 x = 0; x < width; x += 8) {
+ byte pixel = file.readByte();
+ for (int i = 0; i < 8; i++) {
+ byte pixelBit = (pixel >> i) & 1;
+ *(byte *)picture.getBasePtr(x + 7 - i, y) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+
+ return picture;
+}
+
+void GraphicManager::clearAlso() {
+ _magics.fillRect(Common::Rect(0, 0, 640, 200), 0);
+ _magics.frameRect(Common::Rect(0, 45, 640, 161), 15);
+}
+
+void GraphicManager::clearTextBar() {
+ _surface.fillRect(Common::Rect(24, 161, 640, 169), kColorBlack); // Black out the line of the text.
+}
+
+void GraphicManager::setAlsoLine(int x1, int y1, int x2, int y2, Color color) {
+ _magics.drawLine(x1, y1, x2, y2, color);
+}
+
+void GraphicManager::drawScreenLine(int16 x, int16 y, int16 x2, int16 y2, Color color) {
+ _surface.drawLine(x, y, x2, y2, color);
+}
+
+byte GraphicManager::getAlsoColor(int x1, int y1, int x2, int y2) {
+ byte returnColor = 0;
+ for (int16 i = x1; i <= x2; i++) {
+ for (int16 j = y1; j <= y2; j++) {
+ byte actColor = *(byte *)_magics.getBasePtr(i, j);
+ returnColor = MAX(returnColor, actColor);
+ }
+ }
+
+ return returnColor;
+}
+
+byte GraphicManager::getScreenColor(Common::Point pos) {
+ return *(byte *)_surface.getBasePtr(pos.x, pos.y / 2);
+}
+
+void GraphicManager::drawSprite(AnimationType *sprite, byte picnum, int16 x, int16 y) {
+ // First we make the pixels of the sprite blank.
+ for (int j = 0; j < sprite->_yLength; j++) {
+ for (int i = 0; i < sprite->_xLength; i++) {
+ if ((x + i < _surface.w) && (y + j < _surface.h)) {
+ if (((*sprite->_sil[picnum])[j][i / 8] >> ((7 - i % 8)) & 1) == 0)
+ *(byte *)_surface.getBasePtr(x + i, y + j) = 0;
+ }
+ }
+ }
+
+ // Then we draw the picture to the blank places.
+ uint16 maniPos = 0; // Because the original manitype starts at 5!!! See Graphics.h for definition.
+
+ for (int j = 0; j < sprite->_yLength; j++) {
+ for (int8 plane = 3; plane >= 0; plane--) { // The planes are in the opposite way.
+ for (uint16 i = 0; i < sprite->_xLength; i += 8) {
+ byte pixel = (*sprite->_mani[picnum])[maniPos++];
+ for (int bit = 0; bit < 8; bit++) {
+ if ((x + i + 7 < _surface.w) && (y + j < _surface.h)) {
+ byte pixelBit = (pixel >> bit) & 1;
+ *(byte *)_surface.getBasePtr(x + i + 7 - bit, y + j) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+ }
+}
+
+void GraphicManager::drawPicture(Graphics::Surface &target, const Graphics::Surface picture, uint16 destX, uint16 destY) {
+ // Copy the picture to the given place on the screen.
+ uint16 maxX = picture.w;
+ uint16 maxY = picture.h;
+
+ if (destX + maxX > target.w)
+ maxX = target.w - destX;
+
+ if (destY + maxY > target.h)
+ maxY = target.h - destY;
+
+ for (uint16 y = 0; y < maxY; y++) {
+ for (uint16 x = 0; x < maxX; x++)
+ *(byte *)target.getBasePtr(x + destX, y + destY) = *(const byte *)picture.getBasePtr(x, y);
+ }
+}
+
+void GraphicManager::drawCursor(byte pos) {
+ int pixPos = 24 + (pos * 8);
+ // Draw the '_' character.
+ for (int i = 0; i < 8; i++)
+ *(byte *)_surface.getBasePtr(pixPos + i, 168) = kColorWhite;
+}
+
+void GraphicManager::drawReadyLight(Color color) {
+ _surface.fillRect(Common::Rect(419, 195, 438, 197), color);
+}
+
+/**
+ * This is for drawing a big "about" or "gameover" picture loaded from a file into an empty scroll.
+ */
+void GraphicManager::drawSign(Common::String fn, int16 xl, int16 yl, int16 y) {
+ Common::File file;
+ Common::String filename = Common::String::format("%s.avd", fn.c_str());
+
+ if (!file.open(filename))
+ error("AVALANCHE: Scrolls: File not found: %s", filename.c_str());
+
+ // I know it looks very similar to the loadPicture methods, but in truth it's the combination of the two.
+ uint16 width = xl * 8;
+ uint16 height = yl;
+
+ Graphics::Surface sign; // We make a Surface object for the picture itself.
+ sign.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Produce the picture. We read it in row-by-row, and every row has 4 planes.
+ for (int yy = 0; yy < height; yy++) {
+ for (int8 plane = 0; plane < 4; plane++) { // The planes are in the "right" order.
+ for (uint16 xx = 0; xx < width; xx += 8) {
+ byte pixel = file.readByte();
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit != 0)
+ *(byte *)sign.getBasePtr(xx + 7 - bit, yy) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+
+ drawPicture(_scrolls, sign, kScreenWidth / 2 - width / 2, y);
+
+ file.close();
+}
+
+/**
+ * Draws an icon to the current scroll.
+ * @remarks Originally called 'geticon'
+ */
+void GraphicManager::drawIcon(int16 x, int16 y, byte which) {
+ Common::File file;
+
+ if (!file.open("icons.avd"))
+ error("AVALANCHE: Scrolls: File not found: icons.avd");
+
+ which--;
+ file.seek(which * 426);
+
+ Graphics::Surface icon = loadPictureGraphic(file);
+ drawPicture(_scrolls, icon, x, y);
+
+ icon.free();
+ file.close();
+}
+
+void GraphicManager::prepareBubble(int xc, int xw, int my, Common::Point points[3]) {
+ // Backup the screen before drawing the bubble.
+ _scrolls.copyFrom(_surface);
+
+ int16 talkX = _vm->_dialogs->getTalkPosX();
+ // The body of the bubble.
+ _scrolls.fillRect(Common::Rect(xc + talkX - xw + 9, 7, talkX + xw - 8 + xc, my + 1), _talkBackgroundColor);
+ _scrolls.fillRect(Common::Rect(xc + talkX - xw - 1, 12, talkX + xw + xc + 2, my - 4), _talkBackgroundColor);
+
+ // Top the 4 rounded corners of the bubble.
+ drawPieSlice(xc + talkX + xw - 10, 11, 0, 90, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX + xw - 10, my - 4, 270, 360, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX - xw + 10, 11, 90, 180, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX - xw + 10, my - 4, 180, 270, 9, _talkBackgroundColor);
+
+ // "Tail" of the speech bubble.
+ drawTriangle(points, _talkBackgroundColor);
+}
+
+/**
+ * Set the background of the text to the desired color.
+ */
+void GraphicManager::wipeChar(int x, int y, Color color) {
+ for (int k = 0; k < 8; k++)
+ *(byte *)_surface.getBasePtr(x + k, y) = color;
+}
+
+void GraphicManager::drawChar(byte ander, int x, int y, Color color) {
+ byte pixel = ander;
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit)
+ *(byte *)_surface.getBasePtr(x + 7 - bit, y) = color;
+ }
+}
+void GraphicManager::refreshScreen() {
+ // These cycles are for doubling the screen height.
+ for (uint16 y = 0; y < _screen.h / 2; y++) {
+ memcpy(_screen.getBasePtr(0, y * 2), _surface.getBasePtr(0, y), _screen.w);
+ memcpy(_screen.getBasePtr(0, y * 2 + 1), _surface.getBasePtr(0, y), _screen.w);
+ }
+ // Now we copy the stretched picture to the screen.
+ g_system->copyRectToScreen(_screen.getPixels(), _screen.pitch, 0, 0, kScreenWidth, kScreenHeight * 2);
+ g_system->updateScreen();
+}
+
+void GraphicManager::loadBackground(Common::File &file) {
+ _background.free();
+ _background = loadPictureRaw(file, kBackgroundWidth, kBackgroundHeight);
+}
+
+void GraphicManager::refreshBackground() {
+ drawPicture(_surface, _background, 0, 10);
+}
+
+/**
+ * Only used when entering the map.
+ * @remarks Originally called 'zoomout'
+ */
+void GraphicManager::zoomOut(int16 x, int16 y) {
+ //setlinestyle(dottedln, 0, 1); TODO: Implement it with a dotted line style!!!
+
+ saveScreen();
+ for (byte i = 1; i <= 20; i ++) {
+ int16 x1 = x - (x / 20) * i;
+ int16 y1 = y - ((y - 10) / 20) * i;
+ int16 x2 = x + (((639 - x) / 20) * i);
+ int16 y2 = y + (((161 - y) / 20) * i);
+
+ _surface.frameRect(Common::Rect(x1, y1, x2, y2), kColorWhite);
+ refreshScreen();
+ _vm->_system->delayMillis(17);
+
+ restoreScreen();
+ }
+ removeBackup();
+}
+
+void GraphicManager::showScroll() {
+ _surface.copyFrom(_scrolls); // TODO: Rework it using getSubArea !!!!!!!
+}
+
+void GraphicManager::getNaturalPicture(SpriteType &sprite) {
+ sprite._type = kNaturalImage; // We simply read from the screen and later, in drawSprite() we draw it right back.
+ sprite._size = sprite._xl * 8 * sprite._yl + 1;
+ sprite._picture.create(sprite._xl * 8, sprite._yl + 1, Graphics::PixelFormat::createFormatCLUT8());
+ for (uint16 y = 0; y < sprite._yl + 1; y++) {
+ for (uint16 x = 0; x < sprite._xl * 8; x++)
+ *(byte *)sprite._picture.getBasePtr(x, y) = *(byte *)_vm->_graphics->_surface.getBasePtr(sprite._x * 8 + x, sprite._y + y);
+ }
+}
+
+void GraphicManager::saveScreen() {
+ _backup.copyFrom(_surface);
+}
+
+void GraphicManager::removeBackup() {
+ _backup.free();
+}
+
+void GraphicManager::restoreScreen() {
+ _surface.copyFrom(_backup);
+ refreshScreen();
+}
+
+void GraphicManager::setDialogColor(Color bg, Color text) {
+ _talkBackgroundColor = bg;
+ _talkFontColor = text;
+}
+
+// Original name background()
+void GraphicManager::setBackgroundColor(Color x) {
+ warning("STUB: setBackgroundColor()");
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/graphics.h b/engines/avalanche/graphics.h
new file mode 100644
index 0000000000..4af6d4e8db
--- /dev/null
+++ b/engines/avalanche/graphics.h
@@ -0,0 +1,142 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_GRAPHICS_H
+#define AVALANCHE_GRAPHICS_H
+
+#include "avalanche/enums.h"
+
+#include "common/file.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+class AnimationType;
+struct SpriteType;
+
+typedef byte FontType[256][16];
+typedef byte ManiType[2049];
+typedef byte SilType[51][11]; // 35, 4
+
+struct MouseHotspotType {
+ int16 _horizontal, _vertical;
+};
+
+class GraphicManager {
+public:
+ static const MouseHotspotType kMouseHotSpots[9];
+ Color _talkBackgroundColor, _talkFontColor;
+
+ GraphicManager(AvalancheEngine *vm);
+ ~GraphicManager();
+ void init();
+ void loadDigits();
+ void loadMouse(byte which);
+
+ Common::Point drawScreenArc(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+ void drawPieSlice(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+ void drawTriangle(Common::Point *p, Color color);
+ void drawNormalText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ void drawScrollText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ void drawDigit(int index, int x, int y);
+ void drawDirection(int index, int x, int y);
+ void drawScrollShadow(int16 x1, int16 y1, int16 x2, int16 y2);
+ void drawShadowBox(int16 x1, int16 y1, int16 x2, int16 y2, Common::String text);
+ void drawScroll(int mx, int lx, int my, int ly);
+ void drawMenuBar(Color color);
+ void drawSpeedBar(int speed);
+ void drawBackgroundSprite(int16 x, int16 y, SpriteType &sprite);
+ void drawMenuBlock(int x1, int y1, int x2, int y2, Color color);
+ void drawMenuItem(int x1, int y1, int x2, int y2);
+ void wipeChar(int x, int y, Color color);
+ void drawChar(byte ander, int x, int y, Color color);
+ void drawDebugLines();
+
+ void clearAlso();
+ void clearTextBar();
+ void setAlsoLine(int x1, int y1, int x2, int y2, Color color);
+ byte getAlsoColor(int x1, int y1, int x2, int y2);
+ byte getScreenColor(Common::Point pos);
+
+ // The caller has to .free() the returned Surfaces!!!
+ // Further information about these two: http://www.shikadi.net/moddingwiki/Raw_EGA_data
+ Graphics::Surface loadPictureRaw(Common::File &file, uint16 width, uint16 height);
+
+ void drawSprite(AnimationType *sprite, byte picnum, int16 x, int16 y);
+ void drawPicture(Graphics::Surface &target, const Graphics::Surface picture, uint16 destX, uint16 destY);
+ void drawThinkPic(Common::String filename, int id);
+ void drawToolbar();
+ void drawCursor(byte pos);
+ void drawReadyLight(Color color);
+ void drawSign(Common::String name, int16 xl, int16 yl, int16 y);
+ void drawIcon(int16 x, int16 y, byte which);
+ void drawScreenLine(int16 x, int16 y, int16 x2, int16 y2, Color color);
+ void prepareBubble(int xc, int xw, int my, Common::Point points[3]);
+ void refreshScreen();
+ void loadBackground(Common::File &file);
+ void refreshBackground();
+ void setBackgroundColor(Color x);
+ void setDialogColor(Color bg, Color text);
+
+ void zoomOut(int16 x, int16 y);
+ void showScroll();
+ void getNaturalPicture(SpriteType &sprite);
+
+ void saveScreen();
+ void removeBackup();
+ void restoreScreen();
+
+private:
+ static const uint16 kBackgroundWidth = kScreenWidth;
+ static const byte kEgaPaletteIndex[16];
+ static const byte kBackgroundHeight = 8 * 12080 / kScreenWidth; // With 640 width it's 151.
+ // The 8 = number of bits in a byte, and 12080 comes from Lucerna::load().
+
+ Graphics::Surface _background;
+ Graphics::Surface _backup;
+ Graphics::Surface _digits[10]; // digitsize and rwlitesize are defined in loadDigits() !!!
+ Graphics::Surface _directions[9]; // Maybe it will be needed to move them to the class itself instead.
+ Graphics::Surface _magics; // Lucerna::draw_also_lines() draws the "magical" lines here. Further information: https://github.com/urukgit/avalot/wiki/Also
+ Graphics::Surface _screen; // Only used in refreshScreen() to make it more optimized. (No recreation of it at every call of the function.)
+ Graphics::Surface _scrolls;
+ Graphics::Surface _surface;
+ byte _egaPalette[64][3];
+
+ AvalancheEngine *_vm;
+
+ Graphics::Surface loadPictureGraphic(Common::File &file); // Reads Graphic-planar EGA data.
+ void drawText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ // Taken from Free Pascal's Procedure InternalEllipseDefault. Used to replace Pascal's procedure arc.
+ // Returns the end point of the arc. (Needed in Clock.)
+ // TODO: Make it more accurate later.
+ Common::Point drawArc(Graphics::Surface &surface, int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_GRAPHICS_H
diff --git a/engines/avalanche/menu.cpp b/engines/avalanche/menu.cpp
new file mode 100644
index 0000000000..c3fa709ee4
--- /dev/null
+++ b/engines/avalanche/menu.cpp
@@ -0,0 +1,844 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: DROPDOWN A customized version of Oopmenu (qv). */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/menu.h"
+
+namespace Avalanche {
+
+void HeadType::init(char trig, char altTrig, Common::String title, byte pos, MenuFunc setupFunc, MenuFunc chooseFunc, Menu *menu) {
+ _trigger = trig;
+ _altTrigger = altTrig;
+ _title = title;
+ _position = pos;
+ _xpos = _position * _menu->kSpacing + _menu->kIndent;
+ _xright = (_position + 1) * _menu->kSpacing + _menu->kIndent;
+ _setupFunc = setupFunc;
+ _chooseFunc = chooseFunc;
+
+ _menu = menu;
+}
+
+void HeadType::draw() {
+ CursorMan.showMouse(false);
+ _menu->drawMenuText(_xpos, 1, _trigger, _title, true, false);
+ CursorMan.showMouse(true);
+}
+
+void HeadType::highlight() {
+ CursorMan.showMouse(false);
+
+ _menu->_vm->_sound->stopSound();
+ _menu->drawMenuText(_xpos, 1, _trigger, _title, true, true);
+
+ _menu->_activeMenuItem._left = _xpos;
+ _menu->_activeMenuItem._activeNow = true;
+ _menu->_activeMenuItem._activeNum = _position;
+ _menu->_menuActive = true;
+
+ // Force reload and redraw of cursor.
+ _menu->_vm->_currentMouse = 177;
+
+}
+
+bool HeadType::parseAltTrigger(char key) {
+ if (key != _altTrigger)
+ return true;
+ return false;
+}
+
+void MenuItem::init(Menu *menu) {
+ _menu = menu;
+
+ _activeNow = false;
+ _activeNum = 1;
+ _menu->_menuActive = false;
+}
+
+void MenuItem::reset() {
+ _optionNum = 0;
+ _width = 0;
+ _firstlix = false;
+ _oldY = 0;
+ _highlightNum = 0;
+}
+
+void MenuItem::setupOption(Common::String title, char trigger, Common::String shortcut, bool valid) {
+ uint16 width = (title + shortcut).size() + 3;
+ if (_width < width)
+ _width = width;
+
+ _options[_optionNum]._title = title;
+ _options[_optionNum]._trigger = trigger;
+ _options[_optionNum]._shortcut = shortcut;
+ _options[_optionNum]._valid = valid;
+ _optionNum++;
+}
+
+void MenuItem::displayOption(byte y, bool highlit) {
+ Common::String text = _options[y]._title;
+ while (text.size() + _options[y]._shortcut.size() < _width)
+ text += ' '; // Pad _options[y] with spaces.
+ text += _options[y]._shortcut;
+
+ Color backgroundColor;
+ if (highlit)
+ backgroundColor = kColorBlack;
+ else
+ backgroundColor = kColorLightgray;
+
+ _menu->_vm->_graphics->drawMenuBlock((_flx1 + 1) * 8, 3 + (y + 1) * 10, (_flx2 + 1) * 8, 13 + (y + 1) * 10, backgroundColor);
+ _menu->drawMenuText(_left, 4 + (y + 1) * 10, _options[y]._trigger, text, _options[y]._valid, highlit);
+}
+
+void MenuItem::display() {
+ CursorMan.showMouse(false);
+
+ _firstlix = true;
+ _flx1 = _left - 2;
+ _flx2 = _left + _width;
+ _fly = 15 + _optionNum * 10;
+ _activeNow = true;
+ _menu->_menuActive = true;
+
+ _menu->_vm->_graphics->drawMenuItem((_flx1 + 1) * 8, 12, (_flx2 + 1) * 8, _fly);
+
+ displayOption(0, true);
+ for (int y = 1; y < _optionNum; y++)
+ displayOption(y, false);
+
+ _menu->_vm->_currentMouse = 177;
+
+ CursorMan.showMouse(true); // 4 = fletch
+}
+
+void MenuItem::wipe() {
+ CursorMan.showMouse(false);
+
+ _menu->drawMenuText(_menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._xpos, 1,
+ _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._trigger,
+ _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._title, true, false);
+
+ _activeNow = false;
+ _menu->_menuActive = false;
+ _firstlix = false;
+
+ CursorMan.showMouse(true);
+}
+
+void MenuItem::moveHighlight(int8 inc) {
+ if (inc != 0) {
+ int8 highlightNum = _highlightNum + inc;
+ if ((highlightNum < 0) || (highlightNum >= _optionNum))
+ return;
+ _highlightNum = highlightNum;
+ }
+ CursorMan.showMouse(false);
+ displayOption(_oldY, false);
+ displayOption(_highlightNum, true);
+ _oldY = _highlightNum;
+ CursorMan.showMouse(true);
+}
+
+/**
+ * This makes the menu highlight follow the mouse.
+ * @remarks Originally called 'lightup'
+ */
+void MenuItem::lightUp(Common::Point cursorPos) {
+ if ((cursorPos.x < _flx1 * 8) || (cursorPos.x > _flx2 * 8) || (cursorPos.y <= 25) || (cursorPos.y > ((_fly - 3) * 2 + 1)))
+ return;
+ _highlightNum = (cursorPos.y - 26) / 20;
+ if (_highlightNum == _oldY)
+ return;
+ moveHighlight(0);
+}
+
+void MenuItem::select(byte which) {
+ if (!_options[which]._valid)
+ return;
+
+ _choiceNum = which;
+ wipe();
+
+ if (_choiceNum == _optionNum)
+ _choiceNum--; // Off the bottom.
+ if (_choiceNum > _optionNum)
+ _choiceNum = 0; // Off the top, I suppose.
+
+ (_menu->*_menu->_menuBar._menuItems[_activeNum]._chooseFunc)();
+}
+
+void MenuItem::parseKey(char c) {
+ c = toupper(c);
+ bool found = false;
+ for (int i = 0; i < _optionNum; i++) {
+ if ((toupper(_options[i]._trigger) == c) && _options[i]._valid) {
+ select(i);
+ found = true;
+ }
+ }
+ if (!found)
+ _menu->_vm->_sound->blip();
+}
+
+MenuBar::MenuBar() {
+ _menuNum = 0;
+ _menu = nullptr;
+}
+
+void MenuBar::init(Menu *menu) {
+ _menu = menu;
+ _menuNum = 0;
+}
+
+void MenuBar::createMenuItem(char trig, Common::String title, char altTrig, MenuFunc setupFunc, MenuFunc chooseFunc) {
+ _menuItems[_menuNum].init(trig, altTrig, title, _menuNum, setupFunc, chooseFunc, _menu);
+ _menuNum++;
+}
+
+void MenuBar::draw() {
+ _menu->_vm->_graphics->drawMenuBar(kMenuBackgroundColor);
+
+ byte savecp = _menu->_vm->_cp;
+ _menu->_vm->_cp = 3;
+
+ for (int i = 0; i < _menuNum; i++)
+ _menuItems[i].draw();
+
+ _menu->_vm->_cp = savecp;
+}
+
+void MenuBar::parseAltTrigger(char c) {
+ byte i = 0;
+ while ((i < _menuNum) && (_menuItems[i].parseAltTrigger(c)))
+ i++;
+ if (i == _menuNum)
+ return;
+ setupMenuItem(i);
+}
+
+void MenuBar::setupMenuItem(byte which) {
+ if (_menu->_activeMenuItem._activeNow) {
+ _menu->_activeMenuItem.wipe(); // Get rid of menu.
+ if (_menu->_activeMenuItem._activeNum == _menuItems[which]._position)
+ return; // Clicked on own highlight.
+ }
+ _menuItems[which].highlight();
+ (_menu->*_menuItems[which]._setupFunc)();
+}
+
+void MenuBar::chooseMenuItem(int16 x) {
+ for (int i = 0; i < _menuNum; i++) {
+ if ((x > _menuItems[i]._xpos * 8) && (x < _menuItems[i]._xright * 8)) {
+ setupMenuItem(i);
+ break;
+ }
+ }
+}
+
+Menu::Menu(AvalancheEngine *vm) {
+ _vm = vm;
+ _activeMenuItem.init(this);
+ _menuBar.init(this);
+
+ _menuActive = false;
+ _lastPerson = kPeopleNone;
+}
+
+void Menu::findWhatYouCanDoWithIt() {
+ switch (_vm->_thinks) {
+ case kObjectWine:
+ case kObjectPotion:
+ case kObjectInk:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeDrink;
+ break;
+ case kObjectBell:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeRing;
+ break;
+ case kObjectChastity:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeWear;
+ break;
+ case kObjectLute:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodePlay;
+ break;
+ case kObjectMushroom:
+ case kObjectOnion:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeEat;
+ break;
+ case kObjectClothes:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeWear;
+ break;
+ default:
+ _verbStr = kVerbCodeExam; // Anything else.
+ }
+}
+
+void Menu::drawMenuText(int16 x, int16 y, char trigger, Common::String text, bool valid, bool highlighted) {
+ Color fontColor;
+ Color backgroundColor;
+ if (highlighted) {
+ fontColor = kColorWhite;
+ backgroundColor = kColorBlack;
+ } else {
+ fontColor = kColorBlack;
+ backgroundColor = kColorLightgray;
+ }
+
+ byte ander;
+ if (valid)
+ ander = 255;
+ else
+ ander = 170;
+
+ FontType font;
+ for (uint i = 0; i < text.size(); i++) {
+ for (int j = 0; j < 8; j++) {
+ byte idx = text[i];
+ font[idx][j] = _vm->_font[idx][j] & ander; // Set the font.
+ // And set the background of the text to the desired color.
+ _vm->_graphics->wipeChar(x * 8 + i * 8, y + j, backgroundColor);
+ }
+ }
+
+ _vm->_graphics->drawNormalText(text, font, 8, x * 8, y, fontColor);
+
+ // Underline the selected character.
+ if ((trigger == 0) || !text.contains(trigger) )
+ return;
+ else {
+ byte i;
+ for (i = 0; text[i] != trigger; i++)
+ ; // Search for the character in the string.
+
+ _vm->_graphics->drawChar(ander, x * 8 + i * 8, y + 8, fontColor);
+ }
+
+ _vm->_graphics->refreshScreen();
+}
+
+void Menu::bleep() {
+ _vm->_sound->playNote(177, 7);
+}
+
+void Menu::parseKey(char r, char re) {
+#if 0
+ switch (r) {
+ case 0:
+ case 224: {
+ switch (re) {
+ case 'K':
+ if (_activeMenuItem._activeNum > 1) {
+ _activeMenuItem.wipe();
+ _menuBar.setupMenuItem(_activeMenuItem._activeNum - 1);
+ } else {
+ // Get menu on the left-hand side.
+ _activeMenuItem.wipe();
+ _menuBar.chooseMenuItem((_menuBar._menuNum - 1) * kSpacing + kIndent);
+ }
+ break;
+ case 'M':
+ if (_activeMenuItem._activeNum < _menuBar._menuNum) {
+ _activeMenuItem.wipe();
+ _menuBar.setupMenuItem(_activeMenuItem._activeNum + 1);
+ } else {
+ // Get menu on the far right-hand side.
+ _activeMenuItem.wipe();
+ _menuBar.chooseMenuItem(kIndent);
+ }
+ break;
+ case 'H':
+ _activeMenuItem.moveHighlight(-1);
+ break;
+ case 'P':
+ _activeMenuItem.moveHighlight(1);
+ break;
+ default:
+ _menuBar.parseAltTrigger(re);
+ }
+ }
+ break;
+ case 13:
+ _activeMenuItem.select(_activeMenuItem._highlightNum);
+ break;
+ default:
+ if (_activeMenuItem._activeNow)
+ _activeMenuItem.parseKey(r);
+ }
+#endif
+
+ warning("STUB: Dropdown::parseKey()"); // To be implemented properly later! Don't remove the comment above!
+}
+
+Common::String Menu::selectGender(byte x) {
+ if (x < 175)
+ return "im";
+ else
+ return "er";
+}
+
+void Menu::setupMenuGame() {
+ _activeMenuItem.reset();
+ _activeMenuItem.setupOption("Help...", 'H', "f1", true);
+ _activeMenuItem.setupOption("Boss Key", 'B', "alt-B", false);
+ _activeMenuItem.setupOption("Untrash screen", 'U', "ctrl-f7", true);
+ _activeMenuItem.setupOption("Score and rank", 'S', "f9", true);
+ _activeMenuItem.setupOption("About Avvy...", 'A', "shift-f10", true);
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuFile() {
+ _activeMenuItem.reset();
+ _activeMenuItem.setupOption("New game", 'N', "f4", true);
+ _activeMenuItem.setupOption("Load...", 'L', "^f3", true);
+ _activeMenuItem.setupOption("Save", 'S', "^f2", _vm->_alive);
+ _activeMenuItem.setupOption("Save As...", 'v', "", _vm->_alive);
+ _activeMenuItem.setupOption("DOS Shell", 'D', "alt-1", false);
+ _activeMenuItem.setupOption("Quit", 'Q', "alt-X", true);
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuAction() {
+ _activeMenuItem.reset();
+
+ Common::String f5Does = _vm->f5Does();
+ for (int i = 0; i < 2; i++)
+ if (!f5Does.empty())
+ f5Does.deleteChar(0);
+ if (f5Does.empty())
+ _activeMenuItem.setupOption("Do something", 'D', "f5", false);
+ else
+ _activeMenuItem.setupOption(f5Does, f5Does[0], "f5", true);
+ _activeMenuItem.setupOption("Pause game", 'P', "f6", true);
+ if (_vm->_room == kRoomMap)
+ _activeMenuItem.setupOption("Journey thither", 'J', "f7", _vm->_animation->nearDoor());
+ else
+ _activeMenuItem.setupOption("Open the door", 'O', "f7", _vm->_animation->nearDoor());
+ _activeMenuItem.setupOption("Look around", 'L', "f8", true);
+ _activeMenuItem.setupOption("Inventory", 'I', "Tab", true);
+ if (_vm->_animation->_sprites[0]->_speedX == kWalk)
+ _activeMenuItem.setupOption("Run fast", 'R', "^R", true);
+ else
+ _activeMenuItem.setupOption("Walk slowly", 'W', "^W", true);
+
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuPeople() {
+ if (!people.empty())
+ people.clear();
+
+ _activeMenuItem.reset();
+
+ for (int i = kPeopleAvalot; i <= kPeopleWisewoman; i++) {
+ if (_vm->getRoom((People)i) == _vm->_room) {
+ _activeMenuItem.setupOption(_vm->getName((People)i), getNameChar((People)i), "", true);
+ people += i;
+ }
+ }
+
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuObjects() {
+ _activeMenuItem.reset();
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_vm->_objects[i])
+ _activeMenuItem.setupOption(getThing(i + 1), getThingChar(i + 1), "", true);
+ }
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuWith() {
+ _activeMenuItem.reset();
+
+ if (_vm->_thinkThing) {
+ findWhatYouCanDoWithIt();
+
+ for (uint i = 0; i < _verbStr.size(); i++) {
+ char vbchar;
+ Common::String verb;
+
+ _vm->_parser->verbOpt(_verbStr[i], verb, vbchar);
+ _activeMenuItem.setupOption(verb, vbchar, "", true);
+ }
+
+ // We disable the "give" option if: (a), you haven't selected anybody, (b), the _person you've selected isn't in the room,
+ // or (c), the _person you've selected is YOU!
+
+ if ((_lastPerson == kPeopleAvalot) || (_lastPerson == _vm->_parser->kNothing)
+ || (_vm->getRoom(_lastPerson) != _vm->_room))
+ _activeMenuItem.setupOption("Give to...", 'G', "", false); // Not here.
+ else {
+ _activeMenuItem.setupOption(Common::String("Give to ") + _vm->getName(_lastPerson), 'G', "", true);
+ _verbStr = _verbStr + kVerbCodeGive;
+ }
+ } else {
+ _activeMenuItem.setupOption("Examine", 'x', "", true);
+ _activeMenuItem.setupOption(Common::String("Talk to h") + selectGender(_vm->_thinks), 'T', "", true);
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeTalk;
+ switch (_vm->_thinks) {
+ case kPeopleGeida:
+ case kPeopleArkata:
+ _activeMenuItem.setupOption("Kiss her", 'K', "", true);
+ _verbStr = _verbStr + kVerbCodeKiss;
+ break;
+ case kPeopleDogfood:
+ _activeMenuItem.setupOption("Play his game", 'P', "", !_vm->_wonNim); // True if you HAVEN'T won.
+ _verbStr = _verbStr + kVerbCodePlay;
+ break;
+ case kPeopleMalagauche: {
+ bool isSober = !_vm->_teetotal;
+ _activeMenuItem.setupOption("Buy some wine", 'w', "", !_vm->_objects[kObjectWine - 1]);
+ _activeMenuItem.setupOption("Buy some beer", 'b', "", isSober);
+ _activeMenuItem.setupOption("Buy some whisky", 'h', "", isSober);
+ _activeMenuItem.setupOption("Buy some cider", 'c', "", isSober);
+ _activeMenuItem.setupOption("Buy some mead", 'm', "", isSober);
+ _verbStr = _verbStr + 101 + 100 + 102 + 103 + 104;
+ }
+ break;
+ case kPeopleTrader:
+ _activeMenuItem.setupOption("Buy an onion", 'o', "", !_vm->_objects[kObjectOnion - 1]);
+ _verbStr = _verbStr + 105;
+ break;
+ }
+ }
+ _activeMenuItem.display();
+}
+
+void Menu::runMenuGame() {
+ // Help, boss, untrash screen.
+ switch (_activeMenuItem._choiceNum) {
+ case 0:
+ _vm->callVerb(kVerbCodeHelp);
+ break;
+ case 1:
+ _vm->callVerb(kVerbCodeBoss);
+ break;
+ case 2:
+ _vm->majorRedraw();
+ break;
+ case 3:
+ _vm->callVerb(kVerbCodeScore);
+ break;
+ case 4:
+ _vm->callVerb(kVerbCodeInfo);
+ break;
+ }
+}
+
+void Menu::runMenuFile() {
+ // New game, load, save, save as, DOS shell, about, quit.
+ switch (_activeMenuItem._choiceNum) {
+ case 0:
+ _vm->callVerb(kVerbCodeRestart);
+ break;
+ case 1:
+ if (!_vm->_parser->_realWords[1].empty())
+ _vm->_parser->_realWords[1].clear();
+ _vm->callVerb(kVerbCodeLoad);
+ break;
+ // Case 2 is 'Save', Case 3 is 'Save As'. Both triggers ScummVM save screen.
+ case 2:
+ case 3:
+ if (!_vm->_parser->_realWords[1].empty())
+ _vm->_parser->_realWords[1].clear();
+ _vm->callVerb(kVerbCodeSave);
+ break;
+ case 4:
+ // Command Prompt, disabled
+ break;
+ case 5:
+ _vm->callVerb(kVerbCodeQuit);
+ break;
+ }
+}
+
+void Menu::runMenuAction() {
+ // Get up, pause game, open door, look, inventory, walk/run.
+ switch (_activeMenuItem._choiceNum) {
+ case 0: {
+ _vm->_parser->_person = kPeoplePardon;
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ Common::String f5Does = _vm->f5Does();
+ VerbCode verb = (VerbCode)(byte)f5Does[0];
+ _vm->callVerb(verb);
+ }
+ break;
+ case 1:
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ _vm->callVerb(kVerbCodePause);
+ break;
+ case 2:
+ _vm->callVerb(kVerbCodeOpen);
+ break;
+ case 3:
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ _vm->callVerb(kVerbCodeLook);
+ break;
+ case 4:
+ _vm->callVerb(kVerbCodeInv);
+ break;
+ case 5: {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_speedX == kWalk)
+ avvy->_speedX = kRun;
+ else
+ avvy->_speedX = kWalk;
+ _vm->_animation->updateSpeed();
+ }
+ break;
+ }
+}
+
+void Menu::runMenuObjects() {
+ _vm->thinkAbout(_vm->_objectList[_activeMenuItem._choiceNum], AvalancheEngine::kThing);
+}
+
+void Menu::runMenuPeople() {
+ _vm->thinkAbout(people[_activeMenuItem._choiceNum], AvalancheEngine::kPerson);
+ _lastPerson = (People)people[_activeMenuItem._choiceNum];
+}
+
+void Menu::runMenuWith() {
+ _vm->_parser->_thing = _vm->_thinks;
+
+ if (_vm->_thinkThing) {
+ _vm->_parser->_thing += 49;
+
+ if (_verbStr[_activeMenuItem._choiceNum] == kVerbCodeGive)
+ _vm->_parser->_person = _lastPerson;
+ else
+ _vm->_parser->_person = kPeoplePardon;
+ } else {
+ switch (_verbStr[_activeMenuItem._choiceNum]) {
+ case 100: // Beer
+ case 102: // Whisky
+ case 103: // Cider
+ _vm->_parser->_thing = _verbStr[_activeMenuItem._choiceNum];
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 101: // Wine
+ _vm->_parser->_thing = 50;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 104: // Mead
+ _vm->_parser->_thing = 107;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 105: // Onion (trader)
+ _vm->_parser->_thing = 67;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ default:
+ _vm->_parser->_person = (People)_vm->_parser->_thing;
+ _vm->_parser->_thing = Parser::kPardon;
+ _vm->_subjectNum = 0;
+ }
+ }
+ _vm->callVerb((VerbCode)(byte)_verbStr[_activeMenuItem._choiceNum]);
+}
+
+void Menu::setup() {
+ _menuBar.init(this);
+ _activeMenuItem.init(this);
+
+ _menuBar.createMenuItem('F', "File", '!', &Avalanche::Menu::setupMenuFile, &Avalanche::Menu::runMenuFile);
+ _menuBar.createMenuItem('G', "Game", 34, &Avalanche::Menu::setupMenuGame, &Avalanche::Menu::runMenuGame);
+ _menuBar.createMenuItem('A', "Action", 30, &Avalanche::Menu::setupMenuAction, &Avalanche::Menu::runMenuAction);
+ _menuBar.createMenuItem('O', "Objects", 24, &Avalanche::Menu::setupMenuObjects, &Avalanche::Menu::runMenuObjects);
+ _menuBar.createMenuItem('P', "People", 25, &Avalanche::Menu::setupMenuPeople, &Avalanche::Menu::runMenuPeople);
+ _menuBar.createMenuItem('W', "With", 17, &Avalanche::Menu::setupMenuWith, &Avalanche::Menu::runMenuWith);
+
+ _menuBar.draw();
+}
+
+void Menu::update() { // TODO: Optimize it ASAP!!! It really needs it...
+ _vm->_graphics->saveScreen();
+
+ Common::Point cursorPos = _vm->getMousePos();
+ while (!_activeMenuItem._activeNow && (cursorPos.y <= 21) && _vm->_holdLeftMouse) {
+ _menuBar.chooseMenuItem(cursorPos.x);
+ do
+ _vm->updateEvents();
+ while (_vm->_holdLeftMouse && !_vm->shouldQuit());
+
+ while (!_vm->shouldQuit()) {
+ do {
+ _vm->updateEvents();
+
+ // We update the cursor's picture.
+ cursorPos = _vm->getMousePos();
+ // Change arrow...
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21))
+ _vm->_graphics->loadMouse(kCurUpArrow); // Up arrow
+ else if ((22 <= cursorPos.y) && (cursorPos.y <= 339)) {
+ if ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8) && (cursorPos.y > 21) && (cursorPos.y <= _activeMenuItem._fly * 2 + 1))
+ _vm->_graphics->loadMouse(kCurRightArrow); // Right-arrow
+ else
+ _vm->_graphics->loadMouse(kCurFletch); // Fletch
+ } else if ((340 <= cursorPos.y) && (cursorPos.y <= 399))
+ _vm->_graphics->loadMouse(kCurScrewDriver); // Screwdriver
+
+ _activeMenuItem.lightUp(cursorPos);
+
+ _vm->_graphics->refreshScreen();
+ } while (!_vm->_holdLeftMouse && !_vm->shouldQuit());
+
+ if (_vm->_holdLeftMouse) {
+ if (cursorPos.y > 21) {
+ if (!((_activeMenuItem._firstlix) && ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8)
+ && (cursorPos.y >= 24) && (cursorPos.y <= (_activeMenuItem._fly * 2 + 1))))) {
+ // Clicked OUTSIDE the menu.
+ if (_activeMenuItem._activeNow) {
+ _activeMenuItem.wipe();
+ _vm->_holdLeftMouse = false;
+ _vm->_graphics->removeBackup();
+ return;
+ } // No "else"- clicking on menu has no effect (only releasing).
+ }
+ } else {
+ // Clicked on menu bar.
+ if (_activeMenuItem._activeNow) {
+ _activeMenuItem.wipe();
+ _vm->_graphics->restoreScreen();
+
+ if (((_activeMenuItem._left * 8) <= cursorPos.x) && (cursorPos.x <= (_activeMenuItem._left * 8 + 80))) { // 80: the width of one menu item on the bar in pixels.
+ // If we clicked on the same menu item (the one that is already active) on the bar...
+ _vm->_holdLeftMouse = false;
+ _vm->_graphics->removeBackup();
+ return;
+ } else {
+ _vm->_holdLeftMouse = true;
+ break;
+ }
+ }
+ }
+
+ // NOT clicked button...
+ if ((_activeMenuItem._firstlix) && ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8)
+ && (cursorPos.y >= 12) && (cursorPos.y <= (_activeMenuItem._fly * 2 + 1)))) {
+
+ // We act only if the button is released over a menu item.
+ while (!_vm->shouldQuit()) {
+ cursorPos = _vm->getMousePos();
+ _activeMenuItem.lightUp(cursorPos);
+ _vm->_graphics->refreshScreen();
+
+ _vm->updateEvents();
+ if (!_vm->_holdLeftMouse)
+ break;
+ }
+
+ uint16 which = (cursorPos.y - 26) / 20;
+ _activeMenuItem.select(which);
+ if (_activeMenuItem._options[which]._valid) { // If the menu item wasn't active, we do nothing.
+ _vm->_graphics->removeBackup();
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ _vm->_graphics->removeBackup();
+}
+
+char Menu::getThingChar(byte which) {
+ static const char thingsChar[] = "WMBParCLguKeSnIohn"; // V=Vinegar
+
+ char result;
+ switch (which) {
+ case kObjectWine:
+ if (_vm->_wineState == 3)
+ result = 'V'; // Vinegar
+ else
+ result = thingsChar[which - 1];
+ break;
+ default:
+ result = thingsChar[which - 1];
+ }
+ return result;
+}
+
+byte Menu::getNameChar(People whose) {
+ static const char ladChar[] = "ASCDMTRwLfgeIyPu";
+ static const char lassChar[] = "kG\0xB1o";
+
+ if (whose <= kPeopleJacques)
+ return ladChar[whose - kPeopleAvalot];
+ else if ((whose >= kPeopleArkata) && (whose <= kPeopleWisewoman))
+ return lassChar[whose - kPeopleArkata];
+ else
+ error("getName() - Unexpected character id %d", (byte) whose);
+}
+
+Common::String Menu::getThing(byte which) {
+ static const char things[kObjectNum][20] = {
+ "Wine", "Money-bag", "Bodkin", "Potion", "Chastity belt",
+ "Crossbow bolt", "Crossbow", "Lute", "Pilgrim's badge", "Mushroom", "Key",
+ "Bell", "Scroll", "Pen", "Ink", "Clothes", "Habit", "Onion"
+ };
+
+ Common::String result;
+ switch (which) {
+ case kObjectWine:
+ switch (_vm->_wineState) {
+ case 1:
+ case 4:
+ result = Common::String(things[which - 1]);
+ break;
+ case 3:
+ result = "Vinegar";
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ result = Common::String("rotten onion");
+ else
+ result = Common::String(things[which - 1]);
+ break;
+ default:
+ result = Common::String(things[which - 1]);
+ }
+ return result;
+}
+
+bool Menu::isActive() {
+ return _menuActive;
+}
+
+void Menu::init() {
+ _menuActive = false;
+}
+
+void Menu::resetVariables() {
+ _lastPerson = kPeoplePardon;
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/menu.h b/engines/avalanche/menu.h
new file mode 100644
index 0000000000..b7674fbb9d
--- /dev/null
+++ b/engines/avalanche/menu.h
@@ -0,0 +1,182 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: DROPDOWN A customized version of Oopmenu (qv). */
+
+#ifndef AVALANCHE_MENU_H
+#define AVALANCHE_MENU_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Menu;
+
+typedef void (Menu::*MenuFunc)();
+static const Color kMenuBackgroundColor = kColorLightgray;
+static const Color kMenuBorderColor = kColorBlack;
+
+class HeadType {
+public:
+ Common::String _title;
+ char _trigger, _altTrigger;
+ byte _position;
+ int16 _xpos, _xright;
+ MenuFunc _setupFunc, _chooseFunc;
+
+ void init(char trig, char alTtrig, Common::String title, byte pos, MenuFunc setupFunc, MenuFunc chooseFunc, Menu *menu);
+ void draw();
+ void highlight();
+ bool parseAltTrigger(char key);
+
+private:
+ Menu *_menu;
+};
+
+struct OptionType {
+ Common::String _title;
+ byte _trigger;
+ Common::String _shortcut;
+ bool _valid;
+};
+
+class MenuItem {
+public:
+ OptionType _options[12];
+ uint16 _width, _left;
+ bool _firstlix;
+ int16 _flx1, _flx2, _fly;
+ bool _activeNow; // Is there an active option now?
+ byte _activeNum; // And if so, which is it?
+ byte _choiceNum; // Your choice?
+
+ void init(Menu *menu);
+ void reset();
+ void setupOption(Common::String title, char trigger, Common::String shortcut, bool valid);
+ void display();
+ void wipe();
+ void lightUp(Common::Point cursorPos);
+ void select(byte which);
+
+private:
+ byte _oldY; // used by lightUp
+ byte _optionNum;
+ byte _highlightNum;
+
+ Menu *_menu;
+
+ void displayOption(byte y, bool highlit);
+ void moveHighlight(int8 inc);
+
+ // CHECKME: Useless function?
+ void parseKey(char c);
+};
+
+class MenuBar {
+public:
+ HeadType _menuItems[8];
+ byte _menuNum;
+
+ MenuBar();
+ void init(Menu *menu);
+ void createMenuItem(char trig, Common::String title, char altTrig, MenuFunc setupFunc, MenuFunc chooseFunc);
+ void draw();
+ void chooseMenuItem(int16 x);
+
+private:
+ Menu *_menu;
+
+ void setupMenuItem(byte which);
+ // CHECKME: Useless function
+ void parseAltTrigger(char c);
+};
+
+class Menu {
+public:
+ friend class HeadType;
+ friend class MenuItem;
+ friend class MenuBar;
+
+ MenuItem _activeMenuItem;
+ MenuBar _menuBar;
+
+ Menu(AvalancheEngine *vm);
+
+ void update();
+ void setup(); // Standard menu bar.
+ bool isActive();
+ void init();
+ void resetVariables();
+
+private:
+ static const byte kIndent = 5;
+ static const byte kSpacing = 10;
+
+// Checkme: Useless constants?
+// static const Color kMenuFontColor = kColorBlack;
+// static const Color kHighlightBackgroundColor = kColorBlack;
+// static const Color kHighlightFontColor = kColorWhite;
+// static const Color kDisabledColor = kColorDarkgray;
+
+ Common::String people;
+ Common::String _verbStr; // what you can do with your object. :-)
+ bool _menuActive; // Kludge so we don't have to keep referring to the menu.
+ People _lastPerson; // Last person to have been selected using the People menu.
+
+ AvalancheEngine *_vm;
+
+ Common::String selectGender(byte x); // Returns "im" for boys, and "er" for girls.
+ void findWhatYouCanDoWithIt();
+ void drawMenuText(int16 x, int16 y, char trigger, Common::String text, bool valid, bool highlighted);
+ void bleep();
+
+ char getThingChar(byte which);
+ byte getNameChar(People whose);
+ Common::String getThing(byte which);
+
+ void setupMenuGame();
+ void setupMenuFile();
+ void setupMenuAction();
+ void setupMenuPeople();
+ void setupMenuObjects();
+ void setupMenuWith();
+
+ void runMenuGame();
+ void runMenuFile();
+ void runMenuAction();
+ void runMenuObjects();
+ void runMenuPeople();
+ void runMenuWith();
+
+ // CHECKME: Useless function?
+ void parseKey(char r, char re);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_MENU_H
diff --git a/engines/avalanche/module.mk b/engines/avalanche/module.mk
new file mode 100644
index 0000000000..0f66bb8213
--- /dev/null
+++ b/engines/avalanche/module.mk
@@ -0,0 +1,27 @@
+MODULE := engines/avalanche
+
+MODULE_OBJS = \
+ animation.o \
+ avalanche.o \
+ avalot.o \
+ background.o \
+ closing.o \
+ console.o \
+ detection.o \
+ graphics.o \
+ menu.o \
+ parser.o \
+ pingo.o \
+ dialogs.o \
+ sequence.o \
+ sound.o \
+ timer.o \
+ nim.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_AVALANCHE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/avalanche/nim.cpp b/engines/avalanche/nim.cpp
new file mode 100644
index 0000000000..a2572f1fa5
--- /dev/null
+++ b/engines/avalanche/nim.cpp
@@ -0,0 +1,177 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/nim.h"
+
+namespace Avalanche {
+
+const char * const Nim::kNames[2] = {"Avalot", "Dogfood"};
+
+Nim::Nim(AvalancheEngine *vm) {
+ _vm = vm;
+
+ _playedNim = 0;
+}
+
+void Nim::resetVariables() {
+ _playedNim = 0;
+}
+
+void Nim::synchronize(Common::Serializer &sz) {
+ if (sz.isLoading() && sz.getVersion() < 2)
+ return;
+
+ sz.syncAsByte(_playedNim);
+}
+
+void Nim::playNim() {
+ if (_vm->_wonNim) { // Already won the game.
+ _vm->_dialogs->displayScrollChain('Q', 6);
+ return;
+ }
+
+ if (!_vm->_askedDogfoodAboutNim) {
+ _vm->_dialogs->displayScrollChain('Q', 84);
+ return;
+ }
+
+ _vm->_dialogs->displayScrollChain('Q', 3);
+ _playedNim++;
+ _vm->fadeOut();
+
+ _vm->_graphics->saveScreen();
+
+ CursorMan.showMouse(false);
+ setup();
+ board();
+ CursorMan.showMouse(true);
+
+ do {
+ startMove();
+ if (_dogfoodsTurn)
+ dogFood();
+ else
+ takeSome();
+ _stones[_row] -= _number;
+ showChanges();
+ } while (_stonesLeft != 0);
+
+ endOfGame(); // Winning sequence is A1, B3, B1, C1, C1, btw.
+
+ _vm->fadeOut();
+ CursorMan.showMouse(false);
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ CursorMan.showMouse(true);
+ _vm->fadeIn();
+
+ if (_dogfoodsTurn) {
+ // Dogfood won - as usual.
+ if (_playedNim == 1) // Your first game.
+ _vm->_dialogs->displayScrollChain('Q', 4); // Goody! Play me again?
+ else
+ _vm->_dialogs->displayScrollChain('Q', 5); // Oh, look at that! I've won again!
+ _vm->decreaseMoney(4); // And you've just lost 4d!
+ } else {
+ // You won - strange!
+ _vm->_dialogs->displayScrollChain('Q', 7);
+ _vm->_objects[kObjectLute - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_wonNim = true;
+ _vm->_background->draw(-1, -1, 0); // Show the settle with no lute on it.
+
+ // 7 points for winning!
+ _vm->incScore(7);
+ }
+
+ if (_playedNim == 1) {
+ // 3 points for playing your 1st game.
+ _vm->incScore(3);
+ }
+}
+
+void Nim::chalk(int x,int y, Common::String z) {
+ warning("STUB: Nim::chalk()");
+}
+
+void Nim::setup() {
+ warning("STUB: Nim::setup()");
+}
+
+void Nim::plotStone(byte x,byte y) {
+ warning("STUB: Nim::plotStone()");
+}
+
+void Nim::board() {
+ warning("STUB: Nim::board()");
+}
+
+void Nim::startMove() {
+ warning("STUB: Nim::startMove()");
+}
+
+void Nim::showChanges() {
+ warning("STUB: Nim::showChanges()");
+}
+
+void Nim::blip() {
+ warning("STUB: Nim::blip()");
+}
+
+void Nim::checkMouse() {
+ warning("STUB: Nim::checkMouse()");
+}
+
+void Nim::less() {
+ warning("STUB: Nim::less()");
+}
+
+void Nim::takeSome() {
+ warning("STUB: Nim::takeSome()");
+}
+
+void Nim::endOfGame() {
+ warning("STUB: Nim::endOfGame()");
+}
+
+void Nim::dogFood() {
+ warning("STUB: Nim::dogFood()");
+}
+
+bool Nim::find(byte x) {
+ warning("STUB: Nim::find()");
+ return true;
+}
+
+void Nim::findAp(byte start,byte stepsize) {
+ warning("STUB: Nim::findAp()");
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/nim.h b/engines/avalanche/nim.h
new file mode 100644
index 0000000000..a76afcfe22
--- /dev/null
+++ b/engines/avalanche/nim.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_NIM_H
+#define AVALANCHE_NIM_H
+
+namespace Avalanche {
+
+class Nim {
+public:
+ Nim(AvalancheEngine *vm);
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+ void playNim();
+
+private:
+ AvalancheEngine *_vm;
+
+ static const char * const kNames[2];
+
+ byte _old[3];
+ byte _stones[3];
+ byte _stonePic[4][23][7]; // Picture of Nimstone.
+ byte _turns;
+ bool _dogfoodsTurn;
+ byte _stonesLeft;
+ bool _clicked;
+ byte _row;
+ byte _number;
+ bool _squeak;
+ int8 _mNum, _mRow;
+ byte _playedNim; // How many times you've played Nim.
+
+ void chalk(int x,int y, Common::String z);
+ void setup();
+ void plotStone(byte x,byte y);
+ void board();
+ void startMove();
+ void showChanges();
+ void blip();
+ void checkMouse();
+ void less();
+ void takeSome();
+ void endOfGame();
+ void dogFood();
+ bool find(byte x);
+ void findAp(byte start,byte stepsize);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_NIM_H
diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp
new file mode 100644
index 0000000000..811e71ee1d
--- /dev/null
+++ b/engines/avalanche/parser.cpp
@@ -0,0 +1,2481 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/parser.h"
+#include "avalanche/nim.h"
+
+#include "gui/saveload.h"
+
+namespace Avalanche {
+
+const char *Parser::kCopyright = "1995";
+const char *Parser::kVersionNum = "1.30";
+
+Parser::Parser(AvalancheEngine *vm) {
+ _vm = vm;
+
+ _verb = kVerbCodePardon;
+ _thing = kPardon;
+ _person = kPeopleNone;
+ _polite = false;
+ _inputTextPos = 0;
+ _quote = false;
+ _cursorState = false;
+ _weirdWord = false;
+ _wearing = kNothing;
+ _thing2 = 0;
+ _sworeNum = 0;
+ _alcoholLevel = 0;
+
+ _boughtOnion = false;
+}
+
+void Parser::init() {
+ if (!_inputText.empty())
+ _inputText.clear();
+ _inputTextPos = 0;
+
+ _weirdWord = false;
+
+ // Initailaze the vocabulary.
+ // Verbs: 1-49
+ _vocabulary[0].init(1, "EXAMINE");
+ _vocabulary[1].init(1, "READ");
+ _vocabulary[2].init(1, "XAM");
+ _vocabulary[3].init(2, "OPEN");
+ _vocabulary[4].init(2, "LEAVE");
+ _vocabulary[5].init(2, "UNLOCK");
+ _vocabulary[6].init(3, "PAUSE");
+ _vocabulary[7].init(47, "TA"); // Early to avoid Take and Talk.
+ _vocabulary[8].init(4, "TAKE");
+ _vocabulary[9].init(4, "GET");
+ _vocabulary[10].init(4, "PICK");
+ _vocabulary[11].init(5, "DROP");
+ _vocabulary[12].init(6, "INVENTORY");
+ _vocabulary[13].init(7, "TALK");
+ _vocabulary[14].init(7, "SAY");
+ _vocabulary[15].init(7, "ASK");
+ _vocabulary[16].init(8, "GIVE");
+ _vocabulary[17].init(9, "DRINK");
+ _vocabulary[18].init(9, "IMBIBE");
+ _vocabulary[19].init(9, "DRAIN");
+ _vocabulary[20].init(10, "LOAD");
+ _vocabulary[21].init(10, "RESTORE");
+ _vocabulary[22].init(11, "SAVE");
+ _vocabulary[23].init(12, "BRIBE");
+ _vocabulary[24].init(12, "PAY");
+ _vocabulary[25].init(13, "LOOK");
+ _vocabulary[26].init(14, "BREAK");
+ _vocabulary[27].init(15, "QUIT");
+ _vocabulary[28].init(15, "EXIT");
+ _vocabulary[29].init(16, "SIT");
+ _vocabulary[30].init(16, "SLEEP");
+ _vocabulary[31].init(17, "STAND");
+
+ _vocabulary[32].init(18, "GO");
+ _vocabulary[33].init(19, "INFO");
+ _vocabulary[34].init(20, "UNDRESS");
+ _vocabulary[35].init(20, "DOFF");
+ _vocabulary[36].init(21, "DRESS");
+ _vocabulary[37].init(21, "WEAR");
+ _vocabulary[38].init(21, "DON");
+ _vocabulary[39].init(22, "PLAY");
+ _vocabulary[40].init(22, "STRUM");
+ _vocabulary[41].init(23, "RING");
+ _vocabulary[42].init(24, "HELP");
+ _vocabulary[43].init(25, "KENDAL");
+ _vocabulary[44].init(26, "CAPYBARA");
+ _vocabulary[45].init(27, "BOSS");
+ _vocabulary[46].init(255, "NINET"); // block for NINETY
+ _vocabulary[47].init(28, "URINATE");
+ _vocabulary[48].init(28, "MINGITE");
+ _vocabulary[49].init(29, "NINETY");
+ _vocabulary[50].init(30, "ABRACADABRA");
+ _vocabulary[51].init(30, "PLUGH");
+ _vocabulary[52].init(30, "XYZZY");
+ _vocabulary[53].init(30, "HOCUS");
+ _vocabulary[54].init(30, "POCUS");
+ _vocabulary[55].init(30, "IZZY");
+ _vocabulary[56].init(30, "WIZZY");
+ _vocabulary[57].init(30, "PLOVER");
+ _vocabulary[58].init(30, "MELENKURION");
+ _vocabulary[59].init(30, "ZORTON");
+ _vocabulary[60].init(30, "BLERBI");
+ _vocabulary[61].init(30, "THURB");
+ _vocabulary[62].init(30, "SNOEZE");
+ _vocabulary[63].init(30, "SAMOHT");
+ _vocabulary[64].init(30, "NOSIDE");
+ _vocabulary[65].init(30, "PHUGGG");
+ _vocabulary[66].init(30, "KNERL");
+ _vocabulary[67].init(30, "MAGIC");
+ _vocabulary[68].init(30, "KLAETU");
+ _vocabulary[69].init(30, "VODEL");
+ _vocabulary[70].init(30, "BONESCROLLS");
+ _vocabulary[71].init(30, "RADOF");
+
+ _vocabulary[72].init(31, "RESTART");
+ _vocabulary[73].init(32, "SWALLOW");
+ _vocabulary[74].init(32, "EAT");
+ _vocabulary[75].init(33, "LISTEN");
+ _vocabulary[76].init(33, "HEAR");
+ _vocabulary[77].init(34, "BUY");
+ _vocabulary[78].init(34, "PURCHASE");
+ _vocabulary[79].init(34, "ORDER");
+ _vocabulary[80].init(34, "DEMAND");
+ _vocabulary[81].init(35, "ATTACK");
+ _vocabulary[82].init(35, "HIT");
+ _vocabulary[83].init(35, "KILL");
+ _vocabulary[84].init(35, "PUNCH");
+ _vocabulary[85].init(35, "KICK");
+ _vocabulary[86].init(35, "SHOOT");
+ _vocabulary[87].init(35, "FIRE");
+
+ // Passwords: 36
+ _vocabulary[88].init(36, "TIROS");
+ _vocabulary[89].init(36, "WORDY");
+ _vocabulary[90].init(36, "STACK");
+ _vocabulary[91].init(36, "SHADOW");
+ _vocabulary[92].init(36, "OWL");
+ _vocabulary[93].init(36, "ACORN");
+ _vocabulary[94].init(36, "DOMESDAY");
+ _vocabulary[95].init(36, "FLOPPY");
+ _vocabulary[96].init(36, "DIODE");
+ _vocabulary[97].init(36, "FIELD");
+ _vocabulary[98].init(36, "COWSLIP");
+ _vocabulary[99].init(36, "OSBYTE");
+ _vocabulary[100].init(36, "OSCLI");
+ _vocabulary[101].init(36, "TIMBER");
+ _vocabulary[102].init(36, "ADVAL");
+ _vocabulary[103].init(36, "NEUTRON");
+ _vocabulary[104].init(36, "POSITRON");
+ _vocabulary[105].init(36, "ELECTRON");
+ _vocabulary[106].init(36, "CIRCUIT");
+ _vocabulary[107].init(36, "AURUM");
+ _vocabulary[108].init(36, "PETRIFY");
+ _vocabulary[109].init(36, "EBBY");
+ _vocabulary[110].init(36, "CATAPULT");
+ _vocabulary[111].init(36, "GAMERS");
+ _vocabulary[112].init(36, "FUDGE");
+ _vocabulary[113].init(36, "CANDLE");
+ _vocabulary[114].init(36, "BEEB");
+ _vocabulary[115].init(36, "MICRO");
+ _vocabulary[116].init(36, "SESAME");
+ _vocabulary[117].init(36, "LORDSHIP");
+
+ _vocabulary[118].init(37, "DIR");
+ _vocabulary[119].init(37, "LS");
+ _vocabulary[120].init(38, "DIE");
+ _vocabulary[121].init(39, "SCORE");
+ _vocabulary[122].init(40, "PUT");
+ _vocabulary[123].init(40, "INSERT");
+ _vocabulary[124].init(41, "KISS");
+ _vocabulary[125].init(41, "SNOG");
+ _vocabulary[126].init(41, "CUDDLE");
+ _vocabulary[127].init(42, "CLIMB");
+ _vocabulary[128].init(42, "CLAMBER");
+ _vocabulary[129].init(43, "JUMP");
+ _vocabulary[130].init(44, "HIGHSCORES");
+ _vocabulary[131].init(44, "HISCORES");
+ _vocabulary[132].init(45, "WAKEN");
+ _vocabulary[133].init(45, "AWAKEN");
+ _vocabulary[134].init(46, "HELLO");
+ _vocabulary[135].init(46, "HI");
+ _vocabulary[136].init(46, "YO");
+ _vocabulary[137].init(47, "THANKS"); // = 47, "ta", which was defined earlier.
+
+ // Nouns - Objects: 50-100
+ _vocabulary[138].init(50, "WINE");
+ _vocabulary[139].init(50, "BOOZE");
+ _vocabulary[140].init(50, "NASTY");
+ _vocabulary[141].init(50, "VINEGAR");
+ _vocabulary[142].init(51, "MONEYBAG");
+ _vocabulary[143].init(51, "BAG");
+ _vocabulary[144].init(51, "CASH");
+ _vocabulary[145].init(51, "DOSH");
+ _vocabulary[146].init(51, "WALLET");
+ _vocabulary[147].init(52, "BODKIN");
+ _vocabulary[148].init(52, "DAGGER");
+ _vocabulary[149].init(53, "POTION");
+ _vocabulary[150].init(54, "CHASTITY");
+ _vocabulary[151].init(54, "BELT");
+ _vocabulary[152].init(55, "BOLT");
+ _vocabulary[153].init(55, "ARROW");
+ _vocabulary[154].init(55, "DART");
+ _vocabulary[155].init(56, "CROSSBOW");
+ _vocabulary[156].init(56, "BOW");
+ _vocabulary[157].init(57, "LUTE");
+ _vocabulary[158].init(58, "PILGRIM");
+ _vocabulary[159].init(58, "BADGE");
+ _vocabulary[160].init(59, "MUSHROOMS");
+ _vocabulary[161].init(59, "TOADSTOOLS");
+ _vocabulary[162].init(60, "KEY");
+ _vocabulary[163].init(61, "BELL");
+ _vocabulary[164].init(62, "PRESCRIPT");
+ _vocabulary[165].init(62, "SCROLL");
+ _vocabulary[166].init(62, "MESSAGE");
+ _vocabulary[167].init(63, "PEN");
+ _vocabulary[168].init(63, "QUILL");
+ _vocabulary[169].init(64, "INK");
+ _vocabulary[170].init(64, "INKPOT");
+ _vocabulary[171].init(65, "CLOTHES");
+ _vocabulary[172].init(66, "HABIT");
+ _vocabulary[173].init(66, "DISGUISE");
+ _vocabulary[174].init(67, "ONION");
+
+ _vocabulary[175].init(99, "PASSWORD");
+
+ // Objects from Also are placed between 101 and 131.
+ // Nouns - People - Male: 150-174
+ _vocabulary[176].init(150, "AVVY");
+ _vocabulary[177].init(150, "AVALOT");
+ _vocabulary[178].init(150, "YOURSELF");
+ _vocabulary[179].init(150, "ME");
+ _vocabulary[180].init(150, "MYSELF");
+ _vocabulary[181].init(151, "SPLUDWICK");
+ _vocabulary[182].init(151, "THOMAS");
+ _vocabulary[183].init(151, "ALCHEMIST");
+ _vocabulary[184].init(151, "CHEMIST");
+ _vocabulary[185].init(152, "CRAPULUS");
+ _vocabulary[186].init(152, "SERF");
+ _vocabulary[187].init(152, "SLAVE");
+ _vocabulary[188].init(158, "DU"); // Put in early for Baron DU Lustie to save confusion with Duck & Duke.
+ _vocabulary[189].init(152, "CRAPPY");
+ _vocabulary[190].init(153, "DUCK");
+ _vocabulary[191].init(153, "DOCTOR");
+ _vocabulary[192].init(154, "MALAGAUCHE");
+ _vocabulary[193].init(155, "FRIAR");
+ _vocabulary[194].init(155, "TUCK");
+ _vocabulary[195].init(156, "ROBIN");
+ _vocabulary[196].init(156, "HOOD");
+ _vocabulary[197].init(157, "CWYTALOT");
+ _vocabulary[198].init(157, "GUARD");
+ _vocabulary[199].init(157, "BRIDGEKEEP");
+ _vocabulary[200].init(158, "BARON");
+ _vocabulary[201].init(158, "LUSTIE");
+ _vocabulary[202].init(159, "DUKE");
+ _vocabulary[203].init(159, "GRACE");
+ _vocabulary[204].init(160, "DOGFOOD");
+ _vocabulary[205].init(160, "MINSTREL");
+ _vocabulary[206].init(161, "TRADER");
+ _vocabulary[207].init(161, "SHOPKEEPER");
+ _vocabulary[208].init(161, "STALLHOLDER");
+ _vocabulary[209].init(162, "PILGRIM");
+ _vocabulary[210].init(162, "IBYTHNETH");
+ _vocabulary[211].init(163, "ABBOT");
+ _vocabulary[212].init(163, "AYLES");
+ _vocabulary[213].init(164, "PORT");
+ _vocabulary[214].init(165, "SPURGE");
+ _vocabulary[215].init(166, "JACQUES");
+ _vocabulary[216].init(166, "SLEEPER");
+ _vocabulary[217].init(166, "RINGER");
+
+ // Nouns - People - Female: 175-199
+ _vocabulary[218].init(175, "WIFE");
+ _vocabulary[219].init(175, "ARKATA");
+ _vocabulary[220].init(176, "GEDALODAVA");
+ _vocabulary[221].init(176, "GEIDA");
+ _vocabulary[222].init(176, "PRINCESS");
+ _vocabulary[223].init(178, "WISE");
+ _vocabulary[224].init(178, "WITCH");
+
+ // Pronouns: 200-224
+ _vocabulary[225].init(200, "HIM");
+ _vocabulary[226].init(200, "MAN");
+ _vocabulary[227].init(200, "GUY");
+ _vocabulary[228].init(200, "DUDE");
+ _vocabulary[229].init(200, "CHAP");
+ _vocabulary[230].init(200, "FELLOW");
+ _vocabulary[231].init(201, "HER");
+ _vocabulary[232].init(201, "GIRL");
+ _vocabulary[233].init(201, "WOMAN");
+ _vocabulary[234].init(202, "IT");
+ _vocabulary[235].init(202, "THING");
+ _vocabulary[236].init(203, "MONK");
+ _vocabulary[237].init(204, "BARMAN");
+ _vocabulary[238].init(204, "BARTENDER");
+
+ // Prepositions: 225-249
+ _vocabulary[239].init(225, "TO");
+ _vocabulary[240].init(226, "AT");
+ _vocabulary[241].init(227, "UP");
+ _vocabulary[242].init(228, "INTO");
+ _vocabulary[243].init(228, "INSIDE");
+ _vocabulary[244].init(229, "OFF");
+ _vocabulary[245].init(230, "UP");
+ _vocabulary[246].init(231, "DOWN");
+ _vocabulary[247].init(232, "ON");
+
+ // Please: 251
+ _vocabulary[248].init(251, "PLEASE");
+
+ // About: 252
+ _vocabulary[249].init(252, "ABOUT");
+ _vocabulary[250].init(252, "CONCERNING");
+
+ // Swear words: 253
+ /* I M P O R T A N T M E S S A G E
+
+ DO *NOT* READ THE LINES BELOW IF YOU ARE OF A SENSITIVE
+ DISPOSITION. THOMAS IS *NOT* RESPONSIBLE FOR THEM.
+ GOODNESS KNOWS WHO WROTE THEM.
+ READ THEM AT YOUR OWN RISK. BETTER STILL, DON'T READ THEM.
+ WHY ARE YOU SNOOPING AROUND IN MY PROGRAM, ANYWAY? */
+ _vocabulary[251].init(253, "SHIT");
+ _vocabulary[252].init(28 , "PISS");
+ _vocabulary[253].init(28 , "PEE");
+ _vocabulary[254].init(253, "FART");
+ _vocabulary[255].init(253, "FUCK");
+ _vocabulary[256].init(253, "BALLS");
+ _vocabulary[257].init(253, "BLAST");
+ _vocabulary[258].init(253, "BUGGER");
+ _vocabulary[259].init(253, "KNICKERS");
+ _vocabulary[260].init(253, "BLOODY");
+ _vocabulary[261].init(253, "HELL");
+ _vocabulary[262].init(253, "DAMN");
+ _vocabulary[263].init(253, "SMEG");
+ // ...and other even ruder words. You didn't read them, did you? Good.
+
+ // Answer-back smart-alec words: 249
+ _vocabulary[264].init(249, "YES");
+ _vocabulary[265].init(249, "NO");
+ _vocabulary[266].init(249, "BECAUSE");
+
+ // Noise words: 255
+ _vocabulary[267].init(255, "THE");
+ _vocabulary[268].init(255, "A");
+ _vocabulary[269].init(255, "NOW");
+ _vocabulary[270].init(255, "SOME");
+ _vocabulary[271].init(255, "AND");
+ _vocabulary[272].init(255, "THAT");
+ _vocabulary[273].init(255, "POCUS");
+ _vocabulary[274].init(255, "HIS");
+ _vocabulary[275].init(255, "THIS");
+ _vocabulary[276].init(255, "SENTINEL"); // for "Ken SENT Me"
+}
+
+void Parser::handleInputText(const Common::Event &event) {
+ byte inChar = event.kbd.ascii;
+ warning("STUB: Parser::handleInputText()");
+// if (_vm->_menu->_activeMenuItem._activeNow) {
+// _vm->_menu->parseKey(inChar, _vm->_enhanced->extd);
+// } else {
+ if (_inputText.size() < 76) {
+ if ((inChar == '"') || (inChar == '`')) {
+ if (_quote)
+ inChar = '`';
+ else
+ inChar = '"';
+ _quote = !_quote; // quote - unquote
+ }
+
+ _inputText.insertChar(inChar, _inputTextPos);
+ _inputTextPos++;
+ plotText();
+ } else
+ _vm->_sound->blip();
+// }
+}
+
+void Parser::handleBackspace() {
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ return;
+
+ if (_inputTextPos > 0) {
+ _inputTextPos--;
+ if ((_inputText[_inputTextPos] == '"') || (_inputText[_inputTextPos] == '`'))
+ _quote = !_quote;
+ _inputText.deleteChar(_inputTextPos);
+ plotText();
+ } else
+ _vm->_sound->blip();
+}
+
+void Parser::handleReturn() {
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ tryDropdown();
+ else if (!_inputText.empty()) {
+ _inputTextBackup = _inputText;
+ parse();
+ doThat();
+ _inputText.clear();
+ wipeText();
+ }
+}
+
+void Parser::handleFunctionKey(const Common::Event &event) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F1:
+ _vm->callVerb(kVerbCodeHelp);
+ break;
+ case Common::KEYCODE_F2:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ clearWords();
+ _vm->callVerb(kVerbCodeSave);
+ } else
+ _vm->_sound->toggleSound();
+ break;
+ case Common::KEYCODE_F3:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ clearWords();
+ _vm->callVerb(kVerbCodeLoad);
+ } else if (_inputText.size() < _inputTextBackup.size()) {
+ _inputText = _inputText + &(_inputTextBackup.c_str()[_inputText.size()]);
+ _inputTextPos = _inputText.size();
+ plotText();
+ }
+ break;
+ case Common::KEYCODE_F4:
+ if (event.kbd.flags & Common::KBD_ALT)
+ _vm->callVerb(kVerbCodeQuit);
+ else
+ _vm->callVerb(kVerbCodeRestart);
+ break;
+ case Common::KEYCODE_F5: {
+ _person = kPeoplePardon;
+ _thing = kPardon;
+ Common::String f5does = _vm->f5Does();
+ VerbCode verb = (VerbCode)(byte)f5does[0];
+ _vm->callVerb(verb);
+ }
+ break;
+ case Common::KEYCODE_F6:
+ _vm->callVerb(kVerbCodePause);
+ break;
+ case Common::KEYCODE_F7:
+ if (event.kbd.flags & Common::KBD_CTRL)
+ _vm->majorRedraw();
+ else
+ _vm->callVerb(kVerbCodeOpen);
+ break;
+ case Common::KEYCODE_F8:
+ _vm->callVerb(kVerbCodeLook);
+ break;
+ case Common::KEYCODE_F9:
+ _vm->callVerb(kVerbCodeScore);
+ break;
+ case Common::KEYCODE_F10:
+ if (event.kbd.flags & Common::KBD_SHIFT)
+ _vm->callVerb(kVerbCodeInfo);
+ else
+ _vm->callVerb(kVerbCodeQuit);
+ break;
+ case Common::KEYCODE_F11:
+ clearWords();
+ _vm->callVerb(kVerbCodeSave);
+ break;
+ case Common::KEYCODE_F12:
+ clearWords();
+ _vm->callVerb(kVerbCodeLoad);
+ break;
+ default:
+ break;
+ }
+}
+
+void Parser::plotText() {
+ CursorMan.showMouse(false);
+ cursorOff();
+
+ _vm->_graphics->clearTextBar();
+ _vm->_graphics->drawNormalText(_inputText, _vm->_font, 8, 24, 161, kColorWhite);
+
+ cursorOn();
+ CursorMan.showMouse(true);
+}
+
+void Parser::cursorOn() {
+ if (_cursorState == true)
+ return;
+ _vm->_graphics->drawCursor(_inputTextPos);
+ _cursorState = true;
+}
+
+void Parser::cursorOff() {
+ if (_cursorState == false)
+ return;
+ _vm->_graphics->drawCursor(_inputTextPos);
+ _cursorState = false;
+}
+
+/**
+ * Asks the parsekey proc in Dropdown if it knows it.
+ */
+void Parser::tryDropdown() {
+ // TODO: Implement at the same time with Dropdown's keyboard handling.
+ warning("STUB: Parser::tryDropdown()");
+}
+
+/**
+ * Returns the index of the first appearance of crit in src.
+ */
+int16 Parser::getPos(const Common::String &crit, const Common::String &src) {
+ if (src.contains(crit))
+ return strstr(src.c_str(),crit.c_str()) - src.c_str();
+ else
+ return -1;
+}
+
+void Parser::wipeText() {
+ CursorMan.showMouse(false);
+ cursorOff();
+
+ _vm->_graphics->clearTextBar();
+
+ _quote = true;
+ _inputTextPos = 0;
+
+ cursorOn();
+ CursorMan.showMouse(true);
+}
+
+void Parser::clearWords() {
+ for (int i = 0; i < 11; i++) {
+ if (!_realWords[i].empty())
+ _realWords[i].clear();
+ }
+}
+
+byte Parser::wordNum(Common::String word) {
+ if (word.empty())
+ return 0;
+
+ for (int32 i = kParserWordsNum - 1; i >= 0; i--) {
+ if (_vocabulary[i]._word == word)
+ return _vocabulary[i]._number;
+ }
+
+ // If not found as a whole, we look for it as a substring.
+ for (int32 i = kParserWordsNum - 1; i >= 0; i--) {
+ if (Common::String(_vocabulary[i]._word.c_str(), word.size()) == word)
+ return _vocabulary[i]._number;
+ }
+
+ return kPardon;
+}
+
+void Parser::replace(Common::String oldChars, byte newChar) {
+ int16 pos = getPos(oldChars, _thats);
+ while (pos != -1) {
+ if (newChar == 0)
+ _thats.deleteChar(pos);
+ else {
+ for (uint i = pos; i < pos + oldChars.size(); i++)
+ _thats.deleteChar(pos);
+ _thats.insertChar(newChar, pos);
+ }
+ pos = getPos(oldChars, _thats);
+ }
+}
+
+Common::String Parser::rank() {
+ static const RankType ranks[9] = {
+ {0, "Beginner"}, {10, "Novice"},
+ {20, "Improving"}, {35, "Not bad"},
+ {50, "Passable"}, {65, "Good"},
+ {80, "Experienced"}, {108, "The BEST!"},
+ {32767, "copyright'93"}
+ };
+
+ for (int i = 0; i < 8; i++) {
+ if ((_vm->_dnascore >= ranks[i]._score) && (_vm->_dnascore < ranks[i + 1]._score))
+ return Common::String(ranks[i]._title);
+ }
+ return "";
+}
+
+Common::String Parser::totalTime() {
+ uint16 h, m, s;
+
+ uint32 curTime = _vm->getTimeInSeconds() - _vm->_startTime;
+ if (_vm->_isLoaded)
+ curTime += _vm->_totalTime;
+
+ h = (uint16)(curTime / 3600);
+ s = (uint16)(curTime % 3600);
+ m = s / 60;
+ s = s % 60;
+
+ Common::String result = "You've been playing for ";
+ if (h > 0)
+ result += Common::String::format("%d hours, ", h);
+ if ((m > 0) || (h != 0))
+ result += Common::String::format("%d minutes and ", m);
+ return result + Common::String::format("%d seconds", s);
+}
+
+void Parser::cheatParse(Common::String codes) {
+ warning("STUB: Parser::cheatParse()");
+}
+
+/**
+ * Strips punctuation from word.
+ */
+void Parser::stripPunctuation(Common::String &word) {
+ const char punct[] = "~`!@#$%^&*()_+-={}[]:\"|;'\\,./<>?";
+
+ for (int i = 0; i < 32; i++) {
+ for (;;) {
+ int16 pos = getPos(Common::String(punct[i]), word);
+ if (pos == -1)
+ break;
+ word.deleteChar(pos);
+ }
+ }
+}
+
+void Parser::displayWhat(byte target, bool animate, bool &ambiguous) {
+ if (target == kPardon) {
+ ambiguous = true;
+ if (animate)
+ _vm->_dialogs->displayText("Whom?");
+ else
+ _vm->_dialogs->displayText("What?");
+ } else {
+ if (animate) {
+ Common::String tmpStr = Common::String::format("{ %s }", _vm->getName((People)target).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ Common::String z = _vm->getItem(target);
+ if (z != "") {
+ Common::String tmpStr = Common::String::format("{ %s }", z.c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ }
+ }
+}
+
+bool Parser::doPronouns() {
+ bool ambiguous = false;
+
+ for (uint i = 0; i < _thats.size(); i++) {
+ byte wordCode = _thats[i];
+ switch (wordCode) {
+ case 200:
+ displayWhat(_vm->_him, true, ambiguous);
+ _thats.setChar(_vm->_him, i);
+ break;
+ case 201:
+ displayWhat(_vm->_her, true, ambiguous);
+ _thats.setChar(_vm->_her, i);
+ break;
+ case 202:
+ displayWhat(_vm->_it, false, ambiguous);
+ _thats.setChar(_vm->_it, i);
+ break;
+ }
+ }
+
+ return ambiguous;
+}
+
+void Parser::properNouns() {
+ _inputText.toLowercase();
+
+ // We set every word's first character to uppercase.
+ for (uint i = 1; i < (_inputText.size() - 1); i++) {
+ if (_inputText[i] == ' ')
+ _inputText.setChar(toupper(_inputText[i + 1]), i + 1);
+ }
+
+ // And the first character as well.
+ _inputText.setChar(toupper(_inputText[0]), 0);
+}
+
+void Parser::storeInterrogation(byte interrogation) {
+ if (_inputText.empty())
+ return;
+
+ // Strip _inputText:
+ while ((_inputText[0] == ' ') && (!_inputText.empty()))
+ _inputText.deleteChar(0);
+ while ((_inputText.lastChar() == ' ') && (!_inputText.empty()))
+ _inputText.deleteLastChar();
+
+ _vm->_timer->loseTimer(Timer::kReasonCardiffsurvey); // If you want to use any other timer, put this into the case statement.
+
+ switch (interrogation) {
+ case 1:
+ _inputText.toLowercase();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_favoriteDrink = _inputText;
+ _vm->_cardiffQuestionNum = 2;
+ break;
+ case 2:
+ properNouns();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_favoriteSong = _inputText;
+ _vm->_cardiffQuestionNum = 3;
+ break;
+ case 3:
+ properNouns();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_worstPlaceOnEarth = _inputText;
+ _vm->_cardiffQuestionNum = 4;
+ break;
+ case 4:
+ _inputText.toLowercase();
+ _vm->_dialogs->sayIt(_inputText);
+ if (!_vm->_spareEvening.empty())
+ _vm->_spareEvening.clear();
+ _vm->_spareEvening = _inputText;
+ _vm->_dialogs->displayScrollChain('Z', 5); // His closing statement...
+ _vm->_animation->_sprites[1]->walkTo(3); // The end of the drawbridge
+ _vm->_animation->_sprites[1]->_vanishIfStill = true; // Then go away!
+ _vm->_magics[1]._operation = kMagicNothing;
+ _vm->_cardiffQuestionNum = 5;
+ break;
+ case 99:
+ //store_high(_inputText);
+ warning("STUB: Parser::store_interrogation()");
+ break;
+ }
+
+ if (interrogation < 4)
+ _vm->_timer->cardiffSurvey();
+}
+
+void Parser::parse() {
+ // First parsing - word identification
+ if (!_thats.empty())
+ _thats.clear();
+
+ _polite = false;
+ _verb = kVerbCodePardon;
+ _thing = kPardon;
+ _thing2 = kPardon;
+ _person = kPeoplePardon;
+ clearWords();
+
+ // A cheat mode attempt.
+ if (_inputText[0] == '.') {
+ cheatParse(_inputText);
+ _thats = kNothing;
+ return;
+ }
+
+ // Are we being interrogated right now?
+ if (_vm->_interrogation > 0) {
+ storeInterrogation(_vm->_interrogation);
+ _weirdWord = true;
+ return;
+ }
+
+ // Actually process the command.
+ Common::String inputText = _inputText + ' ';
+ Common::String inputTextUpper = inputText;
+ byte n = 0;
+ inputTextUpper.toUppercase();
+ while (!inputTextUpper.empty()) {
+ while ((!inputTextUpper.empty()) && (inputTextUpper[0] == ' ')) {
+ inputTextUpper.deleteChar(0);
+ inputText.deleteChar(0);
+ }
+ if (inputTextUpper.empty())
+ break;
+
+ // Get the following word of the strings.
+ byte size = getPos(Common::String(' '), inputTextUpper) + 1;
+ char *subStr = new char[size];
+ Common::strlcpy(subStr, inputTextUpper.c_str(), size);
+ Common::String thisword = subStr;
+ Common::strlcpy(subStr, inputText.c_str(), size);
+ _realWords[n] = subStr;
+ delete[] subStr;
+
+ stripPunctuation(inputTextUpper);
+
+ bool notfound = true;
+
+ // Check also[] first, which contains words about the actual room.
+ if (!thisword.empty()) {
+ for (int i = 0; i < 31; i++) {
+ if ((_vm->_also[i][0]) && (getPos(',' + thisword, *_vm->_also[i][0]) > -1)) {
+ _thats += Common::String(99 + i);
+ notfound = false;
+ }
+ }
+ }
+
+ // Check Accis's own table (words[]) for "global" commands.
+ if (notfound) {
+ byte answer = wordNum(thisword);
+ if (answer == kPardon) {
+ notfound = true;
+ _thats = _thats + kPardon;
+ } else
+ _thats = _thats + answer;
+ n++;
+ }
+
+ // Delete words we already processed.
+ int16 spacePos = getPos(Common::String(' '), inputTextUpper);
+ if (spacePos > -1) {
+ for (int i = 0; i <= spacePos; i++)
+ inputTextUpper.deleteChar(0);
+ }
+
+ spacePos = getPos(Common::String(' '), inputText);
+ if (spacePos > -1) {
+ for (int i = 0; i <= spacePos; i++)
+ inputText.deleteChar(0);
+ }
+ }
+
+ Common::String unkString;
+ int16 pos = getPos(Common::String('\xFE'), _thats);
+ if (pos > -1)
+ unkString = _realWords[pos];
+ else
+ unkString.clear();
+
+ // Replace words' codes that mean the same.
+ replace(Common::String("\xFF"), 0); // zap noise words
+ replace(Common::String("\xD\xE2"), 1); // "look at" = "examine"
+ replace(Common::String("\xD\xE4"), 1); // "look in" = "examine"
+ replace(Common::String("\x4\xE6"), 17); // "get up" = "stand"
+ replace(Common::String("\x4\xE7"), 17); // "get down" = "stand"... well, why not?
+ replace(Common::String("\x12\xE4"), 2); // "go in" = "open [door]"
+ replace(Common::String("\x1C\xE5"), 253); // "P' off" is a swear word
+ replace(Common::String("\x4\x6"), 6); // "Take inventory" (remember Colossal Adventure?)
+ replace(Common::String("\x28\xE8"), 21); // "put on" = "don"
+ replace(Common::String("\x4\xE5"), 20); // "take off" = "doff"
+
+ // Words that could mean more than one _person
+ if (_vm->_room == kRoomNottsPub)
+ replace(Common::String('\xCC'), 164); // Barman = Port
+ else
+ replace(Common::String('\xCC'), 154); // Barman = Malagauche
+
+ switch (_vm->_room) {
+ case kRoomAylesOffice:
+ replace(Common::String('\xCB'), 163); // Monk = Ayles
+ break;
+ case kRoomMusicRoom:
+ replace(Common::String('\xCB'), 166); // Monk = Jacques
+ break;
+ default:
+ replace(Common::String('\xCB'), 162); // Monk = Ibythneth
+ }
+
+ if (doPronouns()) {
+ _weirdWord = true;
+ _thats = kNothing;
+ return;
+ }
+
+ // Second parsing.
+ _vm->_subjectNum = 0; // Find subject of conversation.
+
+ for (int i = 0; (i < 11) && !_realWords[i].empty(); i++) {
+ if ((_realWords[i][0] == '\'') || (_realWords[i][0] == '\"')) {
+ _vm->_subjectNum = (byte)_thats[i];
+ _thats.setChar(kMoved, i);
+ break;
+ }
+ }
+
+ if ((_vm->_subjectNum == 0) && !_thats.empty()) { // Still not found.
+ for (uint16 i = 0; i < _thats.size() - 1; i++) {
+ if ((byte)_thats[i] == 252) { // The word is "about", or something similar.
+ _vm->_subjectNum = (byte)_thats[i + 1];
+ _thats.setChar(0, i + 1);
+ break;
+ }
+ }
+ }
+
+ if ((_vm->_subjectNum == 0) && !_thats.empty()) { // STILL not found! Must be the word after "say".
+ for (uint16 i = 0; i < _thats.size() - 1; i++) {
+ if (((byte)_thats[i] == 7) && ((byte)_thats[i + 1] != 0) && !((225 <= (byte)_thats[i + 1]) && ((byte)_thats[i + 1] <= 229))) {
+ // SAY not followed by a preposition
+ _vm->_subjectNum = (byte)_thats[i + 1];
+ _thats.setChar(0, i + 1);
+ break;
+ }
+ }
+ }
+
+ for (int16 i = _thats.size() - 1; i >= 0; i--) { // Reverse order, so first will be used.
+ byte curChar = (byte)_thats[i];
+ if ((curChar == 253) || (curChar == 249) || ((1 <= curChar) && (curChar <= 49)))
+ _verb = (VerbCode)curChar;
+ else if ((50 <= curChar) && (curChar <= 149)) {
+ _thing2 = _thing;
+ _thing = curChar;
+ } else if ((150 <= curChar) && (curChar <= 199))
+ _person = (People)curChar;
+ else if (curChar == 251)
+ _polite = true;
+ }
+
+ if ((!unkString.empty()) && (_verb != kVerbCodeExam) && (_verb != kVerbCodeTalk) &&
+ (_verb != kVerbCodeSave) && (_verb != kVerbCodeLoad) && (_verb != kVerbCodeDir)) {
+ Common::String tmpStr = Common::String::format("Sorry, but I have no idea what \"%s\" means. Can you rephrase it?", unkString.c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ _weirdWord = true;
+ } else
+ _weirdWord = false;
+
+ if (_thats.empty())
+ _thats = kNothing;
+
+ if (_thing != kPardon)
+ _vm->_it = _thing;
+
+ if (_person != kPardon) {
+ if (_person < kPeopleArkata)
+ _vm->_him = _person;
+ else
+ _vm->_her = _person;
+ }
+}
+
+/**
+ * Examine a standard object-thing
+ */
+void Parser::examineObject() {
+ if (_thing != _vm->_thinks)
+ _vm->thinkAbout(_thing, AvalancheEngine::kThing);
+ switch (_thing) {
+ case kObjectWine :
+ // 4 is perfect wine. 0 is not holding the wine.
+ switch (_vm->_wineState) {
+ case 1:
+ // Normal examine wine scroll
+ _vm->_dialogs->displayScrollChain('T', 1);
+ break;
+ case 2:
+ // Bad wine
+ _vm->_dialogs->displayScrollChain('D', 6);
+ break;
+ case 3:
+ // Vinegar
+ _vm->_dialogs->displayScrollChain('D', 7);
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ // Yucky onion
+ _vm->_dialogs->displayScrollChain('Q', 21);
+ else
+ // Normal onion
+ _vm->_dialogs->displayScrollChain('T', 18);
+ break;
+ default:
+ // Ordinarily
+ _vm->_dialogs->displayScrollChain('T', _thing);
+ }
+}
+
+bool Parser::isPersonHere() {
+ // Person equivalent of "isHolding".
+ if ((_person == kPeoplePardon) || (_person == kPeopleNone) || (_vm->getRoom(_person) == _vm->_room))
+ return true;
+ else {
+ Common::String tmpStr;
+ if (_person < kPeopleArkata)
+ tmpStr = "He isn't around at the moment.";
+ else
+ tmpStr = "She isn't around at the moment.";
+ _vm->_dialogs->displayText(tmpStr);
+ return false;
+ }
+}
+
+void Parser::exampers() {
+ if (isPersonHere()) {
+ if (_thing != _vm->_thinks)
+ _vm->thinkAbout(_person, AvalancheEngine::kPerson);
+
+ byte newPerson = _person - 149;
+
+ if ((_person == kPeopleDogfood) && _vm->_wonNim)
+ // "I'm Not Playing!"
+ _vm->_dialogs->displayScrollChain('Q', 8);
+ else if ((_person == kPeopleDuLustie) && _vm->_lustieIsAsleep)
+ // He's asleep.
+ _vm->_dialogs->displayScrollChain('Q', 65);
+ else
+ _vm->_dialogs->displayScrollChain('P', newPerson);
+
+ if ((_person == kPeopleAyles) && !_vm->_aylesIsAwake)
+ _vm->_dialogs->displayScrollChain('Q', 13);
+
+ // CHECKME: Present in the original, but it doesn't make sense.
+ // _person = newPerson;
+ }
+}
+
+/**
+ * Return whether Avvy is holding an object or not
+ * @remarks Originally called 'holding'
+ */
+bool Parser::isHolding() {
+ // Also object
+ if ((51 <= _thing) && (_thing <= 99))
+ return true;
+
+ bool holdingResult = false;
+
+ if (_thing >= 100)
+ _vm->_dialogs->displayText("Be reasonable!");
+ else if (_thing <= kObjectNum) {
+ if (!_vm->_objects[_thing - 1])
+ // Verbs that need "_thing" to be in the inventory.
+ _vm->_dialogs->displayText("You're not holding it, Avvy.");
+ else
+ holdingResult = true;
+ } else
+ holdingResult = true;
+
+ return holdingResult;
+}
+
+void Parser::openBox(bool isOpening) {
+ if ((_vm->_room == kRoomYours) && (_thing == 54)) {
+ _vm->_background->draw(-1, -1, 4);
+
+ _vm->_background->update();
+ _vm->_animation->animLink();
+ _vm->_graphics->refreshScreen();
+
+ _vm->_system->delayMillis(55);
+
+ if (!isOpening) {
+ _vm->_background->draw(-1, -1, 5);
+ _vm->_background->update();
+ _vm->_animation->animLink();
+ _vm->_graphics->refreshScreen();
+ }
+ }
+}
+
+void Parser::examine() {
+ // EITHER it's an object OR it's an Also OR it's a _person OR it's something else.
+ if ((_person == kPeoplePardon) && (_thing != kPardon)) {
+ if (isHolding()) {
+ // Remember: it's been slipped! Ie subtract 49.
+ if ((1 <= _thing) && (_thing <= 49))
+ // Standard object
+ examineObject();
+ else if ((50 <= _thing) && (_thing <= 100)) {
+ // Also _thing
+ int id = _thing - 50;
+ assert(id < 31);
+ openBox(true);
+ _vm->_dialogs->displayText(*_vm->_also[id][1]);
+ openBox(false);
+ }
+ }
+ } else if (_person != kPardon)
+ exampers();
+ else
+ // Don't know: guess.
+ _vm->_dialogs->displayText("It's just as it looks on the picture.");
+}
+
+void Parser::inventory() {
+ byte itemNum = 0;
+ Common::String tmpStr = Common::String("You're carrying ");
+
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_vm->_objects[i]) {
+ itemNum++;
+ if (itemNum == _vm->_carryNum)
+ tmpStr += "and ";
+
+ tmpStr += _vm->getItem(i + 1);
+
+ if ((i + 1) == _wearing)
+ tmpStr += ", which you're wearing";
+
+ if (itemNum < _vm->_carryNum)
+ tmpStr += ", ";
+ }
+ }
+
+ if (_wearing == kNothing)
+ tmpStr += Common::String::format("...%c%c...and you're stark naked!", kControlNewLine, kControlNewLine);
+ else
+ tmpStr += '.';
+
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+/**
+ * Eat something.
+ */
+void Parser::swallow() {
+ switch (_thing) {
+ case kObjectWine:
+ // _wineState == 4 for perfect wine
+ switch (_vm->_wineState) {
+ case 1:
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 6);
+ return;
+ }
+ _vm->_dialogs->displayScrollChain('U', 1);
+ _vm->_pingo->wobble();
+ _vm->_dialogs->displayScrollChain('U', 2);
+ _vm->_objects[kObjectWine - 1] = false;
+ _vm->refreshObjectList();
+ drink();
+ break;
+ case 2:
+ case 3:
+ // You can't drink it!
+ _vm->_dialogs->displayScrollChain('D', 8);
+ break;
+ }
+ break;
+ case kObjectPotion:
+ _vm->_graphics->setBackgroundColor(kColorRed);
+ _vm->_dialogs->displayScrollChain('U', 3);
+ _vm->gameOver();
+ _vm->_graphics->setBackgroundColor(kColorBlack);
+ break;
+ case kObjectInk:
+ _vm->_dialogs->displayScrollChain('U', 4);
+ break;
+ case kObjectChastity:
+ _vm->_dialogs->displayScrollChain('U', 5);
+ break;
+ case kObjectMushroom:
+ _vm->_dialogs->displayScrollChain('U', 6);
+ _vm->gameOver();
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayScrollChain('U', 11);
+ else {
+ _vm->_dialogs->displayScrollChain('U', 8);
+ _vm->_objects[kObjectOnion - 1] = false;
+ _vm->refreshObjectList();
+ }
+ break;
+ default:
+ if ((_vm->_room == kRoomArgentPub) || (_vm->_room == kRoomNottsPub))
+ _vm->_dialogs->displayText("Try BUYing things before you drink them!");
+ else
+ _vm->_dialogs->displayText("The taste of it makes you retch!");
+ }
+}
+
+/**
+ * this lists the other people in the room.
+ */
+void Parser::peopleInRoom() {
+ // First compute the number of people in the room.
+ byte numPeople = 0;
+ for (int i = 151; i < 179; i++) { // Start at 1 so we don't list Avvy himself!
+ if (_vm->getRoom((People)i) == _vm->_room)
+ numPeople++;
+ }
+
+ // If nobody's here, we can cut out straight away.
+ if (numPeople == 0)
+ return;
+
+ Common::String tmpStr;
+ byte actPerson = 0;
+ for (int i = 151; i < 179; i++) {
+ if (_vm->getRoom((People)i) == _vm->_room) {
+ actPerson++;
+ if (actPerson == 1)
+ // Display first name on the list.
+ tmpStr = _vm->getName((People)i);
+ else if (actPerson < numPeople)
+ // Display one the names in the middle of the list
+ tmpStr += ", " + _vm->getName((People)i);
+ else
+ // Display the last name of the list
+ tmpStr += " and " + _vm->getName((People)i);
+ }
+ }
+
+ if (numPeople == 1)
+ tmpStr += " is";
+ else
+ tmpStr += " are";
+
+ _vm->_dialogs->displayText(tmpStr + " here.");
+}
+
+/**
+ * This is called when you say "look".
+ */
+void Parser::lookAround() {
+ _vm->_dialogs->displayText(*_vm->_also[0][1]);
+ switch (_vm->_room) {
+ case kRoomSpludwicks:
+ if (_vm->_avariciusTalk > 0)
+ _vm->_dialogs->displayScrollChain('Q', 23);
+ else
+ peopleInRoom();
+ break;
+ case kRoomRobins:
+ if (_vm->_tiedUp)
+ _vm->_dialogs->displayScrollChain('Q', 38);
+ if (_vm->_mushroomGrowing)
+ _vm->_dialogs->displayScrollChain('Q', 55);
+ break;
+ case kRoomInsideCardiffCastle:
+ if (!_vm->_takenPen)
+ _vm->_dialogs->displayScrollChain('Q', 49);
+ break;
+ case kRoomLustiesRoom:
+ if (_vm->_lustieIsAsleep)
+ _vm->_dialogs->displayScrollChain('Q', 65);
+ break;
+ case kRoomCatacombs:
+ switch (_vm->_catacombY * 256 + _vm->_catacombX) {
+ case 258 :
+ // Inside art gallery.
+ _vm->_dialogs->displayScrollChain('Q', 80);
+ break;
+ case 514 :
+ // Outside ditto.
+ _vm->_dialogs->displayScrollChain('Q', 81);
+ break;
+ case 260 :
+ // Outside Geida's room.
+ _vm->_dialogs->displayScrollChain('Q', 82);
+ break;
+ }
+ break;
+ default:
+ peopleInRoom();
+ }
+}
+
+void Parser::openDoor() {
+ // Special cases.
+ switch (_vm->_room) {
+ case kRoomYours:
+ if (_vm->_animation->inField(1)) {
+ // Opening the box.
+ _thing = 54; // The box.
+ _person = kPeoplePardon;
+ examine();
+ return;
+ }
+ break;
+ case kRoomSpludwicks:
+ if (_thing == 61) {
+ _vm->_dialogs->displayScrollChain('Q', 85);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ((!_vm->_userMovesAvvy) && (_vm->_room != kRoomLusties))
+ // No doors can open if you can't move Avvy.
+ return;
+
+ for (int i = 0; i < 7; i++) {
+ if (_vm->_animation->inField(i + 8)) {
+ MagicType *portal = &_vm->_portals[i];
+ switch (portal->_operation) {
+ case kMagicExclaim:
+ _vm->_animation->_sprites[0]->bounce();
+ _vm->_dialogs->displayScrollChain('X', portal->_data);
+ break;
+ case kMagicTransport:
+ _vm->flipRoom((Room)((portal->_data) >> 8), portal->_data & 0x0F);
+ break;
+ case kMagicUnfinished:
+ _vm->_animation->_sprites[0]->bounce();
+ _vm->_dialogs->displayText("Sorry. This place is not available yet!");
+ break;
+ case kMagicSpecial:
+ _vm->_animation->callSpecial(portal->_data);
+ break;
+ case kMagicOpenDoor:
+ _vm->openDoor((Room)(portal->_data >> 8), portal->_data & 0x0F, i + 9);
+ break;
+ }
+
+ return;
+ }
+ }
+
+ if (_vm->_room == kRoomMap)
+ _vm->_dialogs->displayText("Avvy, you can complete the whole game without ever going " \
+ "to anywhere other than Argent, Birmingham, Cardiff, Nottingham and Norwich.");
+ else
+ _vm->_dialogs->displayText("Door? What door?");
+}
+
+/**
+ * Called when you call kVerbCodeput.
+ */
+void Parser::putProc() {
+ if (!isHolding())
+ return;
+
+ // Slip the second object.
+ _thing2 -= 49;
+ char temp = _thing;
+ _thing = _thing2;
+ if (!isHolding())
+ return;
+ _thing = temp;
+
+ // Thing is the _thing which you're putting in. _thing2 is where you're putting it.
+ switch (_thing2) {
+ case kObjectWine:
+ if (_thing == kObjectOnion) {
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayText("That's a bit like shutting the stable door after the horse has bolted!");
+ else {
+ // Put onion into wine?
+ if (_vm->_wineState != 3) {
+ Common::String tmpStr = Common::String::format("%cOignon au vin%c is a bit too strong for your tastes!",
+ kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ // Put onion into vinegar! Yes!
+ _vm->_onionInVinegar = true;
+ _vm->incScore(7);
+ _vm->_dialogs->displayScrollChain('U', 9);
+ }
+ }
+ } else
+ _vm->_dialogs->saySilly();
+ break;
+
+ case 54:
+ if (_vm->_room == kRoomYours) {
+ // Put something into the box.
+ if (_vm->_boxContent != kNothing)
+ _vm->_dialogs->displayText("There's something in the box already, Avvy. Try taking that out first.");
+ else {
+ switch (_thing) {
+ case kObjectMoney:
+ _vm->_dialogs->displayText("You'd better keep some ready cash on you!");
+ break;
+ case kObjectBell:
+ _vm->_dialogs->displayText("That's a silly place to keep a bell.");
+ break;
+ case kObjectBodkin:
+ _vm->_dialogs->displayText("But you might need it!");
+ break;
+ case kObjectOnion:
+ _vm->_dialogs->displayText("Just give it to Spludwick, Avvy!");
+ break;
+ default:
+ // Put the object into the box...
+ if (_wearing == _thing) {
+ Common::String tmpStr = Common::String::format("You'd better take %s off first!", _vm->getItem(_thing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ // Open box.
+ openBox(true);
+
+ _vm->_boxContent = _thing;
+ _vm->_objects[_thing - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayText("OK, it's in the box.");
+
+ // Shut box.
+ openBox(false);
+ }
+ }
+ }
+ } else
+ _vm->_dialogs->saySilly();
+ break;
+
+ default:
+ _vm->_dialogs->saySilly();
+ }
+}
+
+/**
+ * Display text when ingredients are not in the right order
+ * @remarks Originally called 'not_in_order'
+ */
+void Parser::notInOrder() {
+ Common::String itemStr = _vm->getItem(_vm->kSpludwicksOrder[_vm->_givenToSpludwick]);
+ Common::String tmpStr = Common::String::format("Sorry, I need the ingredients in the right order for this potion. " \
+ "What I need next is %s%c2%c", itemStr.c_str(), kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+/**
+ * Move Spludwick to cauldron
+ * @remarks Originally called 'go_to_cauldron'
+ */
+void Parser::goToCauldron() {
+ // Stops Geida_Procs.
+ _vm->_animation->_sprites[1]->_callEachStepFl = false;
+ _vm->_timer->addTimer(1, Timer::kProcSpludwickGoesToCauldron, Timer::kReasonSpludwickWalk);
+ _vm->_animation->_sprites[1]->walkTo(1);
+}
+
+/**
+ * Check is it's possible to give something to Spludwick
+ * The result of this function is whether or not he says "Hey, thanks!".
+ * @remarks Originally called 'give2spludwick'
+ */
+bool Parser::giveToSpludwick() {
+ if (_vm->kSpludwicksOrder[_vm->_givenToSpludwick] != _thing) {
+ notInOrder();
+ return false;
+ }
+
+ switch (_thing) {
+ case kObjectOnion:
+ _vm->_objects[kObjectOnion - 1] = false;
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayScrollChain('Q', 22);
+ else {
+ _vm->_givenToSpludwick++;
+ _vm->_dialogs->displayScrollChain('Q', 20);
+ goToCauldron();
+ _vm->incScore(3);
+ }
+ _vm->refreshObjectList();
+ break;
+ case kObjectInk:
+ _vm->_objects[kObjectInk - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_givenToSpludwick++;
+ _vm->_dialogs->displayScrollChain('Q', 24);
+ goToCauldron();
+ _vm->incScore(3);
+ break;
+ case kObjectMushroom:
+ _vm->_objects[kObjectMushroom - 1] = false;
+ _vm->_dialogs->displayScrollChain('Q', 25);
+ _vm->incScore(5);
+ _vm->_givenToSpludwick++;
+ goToCauldron();
+ _vm->_objects[kObjectPotion - 1] = true;
+ _vm->refreshObjectList();
+ break;
+ default:
+ return true;
+ }
+ return false;
+}
+
+void Parser::drink() {
+ _alcoholLevel++;
+ if (_alcoholLevel == 5) {
+ // Get the key.
+ _vm->_objects[kObjectKey - 1] = true;
+ _vm->_teetotal = true;
+ _vm->_avvyIsAwake = false;
+ _vm->_avvyInBed = true;
+ _vm->refreshObjectList();
+ _vm->fadeOut();
+ _vm->flipRoom(kRoomYours, 1);
+ _vm->_graphics->setBackgroundColor(kColorYellow);
+ _vm->_animation->_sprites[0]->_visible = false;
+ }
+}
+
+void Parser::cardiffClimbing() {
+ if (_vm->_standingOnDais) {
+ // Clamber up.
+ _vm->_dialogs->displayText("You climb down, back onto the floor.");
+ _vm->_standingOnDais = false;
+ _vm->_animation->appearPed(0, 2);
+ } else if (_vm->_animation->inField(0)) {
+ // Clamber down
+ _vm->_dialogs->displayText("You clamber up onto the dais.");
+ _vm->_standingOnDais = true;
+ _vm->_animation->appearPed(0, 1);
+ } else
+ _vm->_dialogs->displayText("Get a bit closer, Avvy.");
+}
+
+void Parser::already() {
+ _vm->_dialogs->displayText("You're already standing!");
+}
+
+/**
+ * Called when you ask Avvy to stand.
+ */
+void Parser::standUp() {
+ switch (_vm->_room) {
+ case kRoomYours:
+ // Avvy isn't asleep.
+ if (_vm->_avvyIsAwake && _vm->_avvyInBed) {
+ // But he's in bed.
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 12);
+ _vm->_graphics->setBackgroundColor(kColorBlack);
+ _vm->_dialogs->displayScrollChain('D', 14);
+ }
+ _vm->_animation->_sprites[0]->_visible = true;
+ _vm->_userMovesAvvy = true;
+ _vm->_animation->appearPed(0, 1);
+ _vm->_animation->setDirection(kDirLeft);
+ // Display a picture of empty pillow in the background.
+ _vm->_background->draw(-1, -1, 3);
+ _vm->incScore(1);
+ _vm->_avvyInBed = false;
+ _vm->_timer->loseTimer(Timer::kReasonArkataShouts);
+ } else
+ already();
+ break;
+
+ case kRoomInsideCardiffCastle:
+ cardiffClimbing();
+ break;
+
+ case kRoomNottsPub:
+ if (_vm->_sittingInPub) {
+ // Not sitting down.
+ _vm->_background->draw(-1, -1, 3);
+ // But standing up.
+ _vm->_animation->_sprites[0]->_visible = true;
+ // And walking away.
+ _vm->_animation->appearPed(0, 3);
+ // Really not sitting down.
+ _vm->_sittingInPub = false;
+ // And ambulant.
+ _vm->_userMovesAvvy = true;
+ } else
+ already();
+ break;
+ default:
+ already();
+ }
+}
+
+void Parser::getProc(char thing) {
+ switch (_vm->_room) {
+ case kRoomYours:
+ if (_vm->_animation->inField(1)) {
+ if (_vm->_boxContent == thing) {
+ _vm->_background->draw(-1, -1, 4);
+ _vm->_dialogs->displayText("OK, I've got it.");
+ _vm->_objects[thing - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_boxContent = kNothing;
+ _vm->_background->draw(-1, -1, 5);
+ } else {
+ Common::String tmpStr = Common::String::format("I can't see %s in the box.", _vm->getItem(thing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ break;
+ case kRoomInsideCardiffCastle:
+ switch (thing) {
+ case kObjectPen:
+ if (_vm->_animation->inField(1)) {
+ // Standing on the dais.
+ if (_vm->_takenPen)
+ _vm->_dialogs->displayText("It's not there, Avvy.");
+ else {
+ // OK: we're taking the pen, and it's there.
+ // No pen there now.
+ _vm->_background->draw(-1, -1, 3);
+ // Zap!
+ _vm->_animation->callSpecial(3);
+ _vm->_takenPen = true;
+ _vm->_objects[kObjectPen - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayText("Taken.");
+ }
+ } else if (_vm->_standingOnDais)
+ _vm->_dialogs->displayScrollChain('Q', 53);
+ else
+ _vm->_dialogs->displayScrollChain('Q', 51);
+ break;
+ case kObjectBolt:
+ _vm->_dialogs->displayScrollChain('Q', 52);
+ break;
+ default:
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ }
+ break;
+ case kRoomRobins:
+ if ((thing == kObjectMushroom) & (_vm->_animation->inField(0)) & (_vm->_mushroomGrowing)) {
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_dialogs->displayText("Got it!");
+ _vm->_mushroomGrowing = false;
+ _vm->_takenMushroom = true;
+ _vm->_objects[kObjectMushroom - 1] = true;
+ _vm->refreshObjectList();
+ _vm->incScore(3);
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ break;
+ default:
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ }
+}
+
+/**
+ * Give the lute to Geida
+ * @remarks Originally called 'give_Geida_the_lute'
+ */
+void Parser::giveGeidaTheLute() {
+ if (_vm->_room != kRoomLustiesRoom) {
+ Common::String tmpStr = Common::String::format("Not yet. Try later!%c2%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ return;
+ }
+ _vm->_objects[kObjectLute - 1] = false;
+ _vm->refreshObjectList();
+ // She plays it.
+ _vm->_dialogs->displayScrollChain('Q', 64);
+
+ _vm->_timer->addTimer(1, Timer::kProcGiveLuteToGeida, Timer::kReasonGeidaSings);
+ //_vm->_enid->backToBootstrap(4); TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+}
+
+void Parser::playHarp() {
+ if (_vm->_animation->inField(6))
+ _vm->_dialogs->displayMusicalScroll();
+ else
+ _vm->_dialogs->displayText("Get a bit closer to it, Avvy!");
+}
+
+void Parser::winSequence() {
+ _vm->_dialogs->displayScrollChain('Q', 78);
+ _vm->_sequence->startWinSeq();
+ _vm->_timer->addTimer(30, Timer::kProcWinning, Timer::kReasonWinning);
+}
+
+/**
+ * @remarks Originally called 'do_that'
+ */
+void Parser::doThat() {
+ static const char booze[8][8] = {"Bitter", "GIED", "Whisky", "Cider", "", "", "", "Mead"};
+ static const char kWhat[] = "That's not possible!";
+
+ if (_thats == Common::String(kNothing)) {
+ if (!_thats.empty())
+ _thats.clear();
+ return;
+ }
+
+ if (_weirdWord)
+ return;
+
+ if (_thing < 200)
+ // "Slip" object
+ _thing -= 49;
+
+ if ((_verb != kVerbCodeLoad) && (_verb != kVerbCodeSave) && (_verb != kVerbCodeQuit) && (_verb != kVerbCodeInfo) && (_verb != kVerbCodeHelp)
+ && (_verb != kVerbCodeLarrypass) && (_verb != kVerbCodePhaon) && (_verb != kVerbCodeBoss) && (_verb != kVerbCodeCheat) && (_verb != kVerbCodeRestart)
+ && (_verb != kVerbCodeDir) && (_verb != kVerbCodeScore) && (_verb != kVerbCodeHiscores) && (_verb != kVerbCodeSmartAlec)) {
+ if (!_vm->_alive) {
+ _vm->_dialogs->displayText("You're dead, so don't talk. What are you, a ghost or something? " \
+ "Try restarting, or restoring a saved game!");
+ return;
+ }
+ if (!_vm->_avvyIsAwake && (_verb != kVerbCodeDie) && (_verb != kVerbCodeExpletive) && (_verb != kVerbCodeWake)) {
+ _vm->_dialogs->displayText("Talking in your sleep? Try waking up!");
+ return;
+ }
+ }
+
+ switch (_verb) {
+ case kVerbCodeExam:
+ examine();
+ break;
+ case kVerbCodeOpen:
+ openDoor();
+ break;
+ case kVerbCodePause: {
+ // Note that the original game doesn't care about the "O.K." box neither, it accepts
+ // clicks from everywhere on the screen to continue. Just like my code.
+ Common::String tmpStr = Common::String::format("Game paused.%c%c%cPress Enter, Esc, or click the mouse on the `O.K.\" " \
+ "box to continue.", kControlCenter, kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeGet:
+ if (_thing != kPardon) {
+ // Legitimate try to pick something up.
+ if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("You can't carry any more!");
+ else
+ getProc(_thing);
+ } else {
+ // Not... ditto.
+ if (_person != kPeoplePardon)
+ _vm->_dialogs->displayText("You can't sweep folk off their feet!");
+ else
+ _vm->_dialogs->displayText("I assure you, you don't need it.");
+ }
+ break;
+ case kVerbCodeDrop:
+ _vm->_dialogs->displayText("Two years ago you dropped a florin in the street. Three days " \
+ "later it was gone! So now you never leave ANYTHING lying around. OK?");
+ break;
+ case kVerbCodeInv:
+ inventory();
+ break;
+ case kVerbCodeTalk:
+ if (_person == kPeoplePardon) {
+ if (_vm->_subjectNum == 99) {
+ // They typed "say password".
+ Common::String tmpStr = Common::String::format("Yes, but what %cis%c the password?", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else if (((1 <= _vm->_subjectNum) && (_vm->_subjectNum <= 49)) || (_vm->_subjectNum == 253) || (_vm->_subjectNum == 249)) {
+ _thats.deleteChar(0);
+
+ for (int i = 0; i < 10; i++)
+ _realWords[i] = _realWords[i + 1];
+
+ _verb = (VerbCode)_vm->_subjectNum;
+ doThat();
+ return;
+ } else {
+ _person = (People)_vm->_subjectNum;
+ _vm->_subjectNum = 0;
+ if ((_person == kPeopleNone) || (_person == kPeoplePardon))
+ _vm->_dialogs->displayText("Talk to whom?");
+ else if (isPersonHere())
+ _vm->_dialogs->talkTo(_person);
+ }
+ } else if (isPersonHere())
+ _vm->_dialogs->talkTo(_person);
+ break;
+ case kVerbCodeGive:
+ if (isHolding()) {
+ if (_person == kPeoplePardon)
+ _vm->_dialogs->displayText("Give to whom?");
+ else if (isPersonHere()) {
+ switch (_thing) {
+ case kObjectMoney :
+ _vm->_dialogs->displayText("You can't bring yourself to give away your moneybag.");
+ break;
+ case kObjectBodkin:
+ case kObjectBell:
+ case kObjectClothes:
+ case kObjectHabit :
+ _vm->_dialogs->displayText("Don't give it away, it might be useful!");
+ break;
+ default:
+ switch (_person) {
+ case kPeopleCrapulus:
+ if (_thing == kObjectWine) {
+ _vm->_dialogs->displayText("Crapulus grabs the wine and gulps it down.");
+ _vm->_objects[kObjectWine - 1] = false;
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleCwytalot:
+ if ((_thing == kObjectCrossbow) || (_thing == kObjectBolt))
+ _vm->_dialogs->displayText("You might be able to influence Cwytalot more if you used it!");
+ else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleSpludwick:
+ if (giveToSpludwick())
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleIbythneth:
+ if (_thing == kObjectBadge) {
+ _vm->_dialogs->displayScrollChain('Q', 32); // Thanks! Wow!
+ _vm->incScore(3);
+ _vm->_objects[kObjectBadge - 1] = false;
+ _vm->_objects[kObjectHabit - 1] = true;
+ _vm->_givenBadgeToIby = true;
+ _vm->_background->draw(-1, -1, 7);
+ _vm->_background->draw(-1, -1, 8);
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleAyles:
+ if (_vm->_aylesIsAwake) {
+ if (_thing == kObjectPen) {
+ _vm->_objects[kObjectPen - 1] = false;
+ _vm->_dialogs->displayScrollChain('Q', 54);
+ _vm->_objects[kObjectInk - 1] = true;
+ _vm->_givenPenToAyles = true;
+ _vm->refreshObjectList();
+ _vm->incScore(2);
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ } else
+ _vm->_dialogs->displayText("But he's asleep!");
+ break;
+ case kPeopleGeida:
+ switch (_thing) {
+ case kObjectPotion:
+ _vm->_objects[kObjectPotion - 1] = false;
+ // She drinks it.
+ _vm->_dialogs->displayScrollChain('U', 16);
+ _vm->incScore(2);
+ _vm->_givenPotionToGeida = true;
+ _vm->refreshObjectList();
+ break;
+ case kObjectLute:
+ giveGeidaTheLute();
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ break;
+ case kPeopleArkata:
+ switch (_thing) {
+ case kObjectPotion:
+ if (_vm->_givenPotionToGeida)
+ winSequence();
+ else
+ // That Geida woman!
+ _vm->_dialogs->displayScrollChain('Q', 77);
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ }
+ }
+ // Just in case...
+ _vm->refreshObjectList();
+ }
+ break;
+
+ case kVerbCodeEat:
+ case kVerbCodeDrink:
+ if (isHolding())
+ swallow();
+ break;
+
+ case kVerbCodeLoad: {
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
+ delete dialog;
+
+ if (savegameId < 0)
+ // dialog aborted, nothing to load
+ return;
+
+ _vm->loadGame(savegameId);
+ }
+ break;
+ case kVerbCodeSave: {
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
+ Common::String savegameDescription = dialog->getResultString();
+ delete dialog;
+
+ if (savegameId < 0)
+ // dialog aborted, nothing to save
+ return;
+
+ _vm->saveGame(savegameId, savegameDescription);
+ }
+ break;
+ case kVerbCodePay:
+ _vm->_dialogs->displayText("No money need change hands.");
+ break;
+ case kVerbCodeLook:
+ lookAround();
+ break;
+ case kVerbCodeBreak:
+ _vm->_dialogs->displayText("Vandalism is prohibited within this game!");
+ break;
+ case kVerbCodeQuit:
+ if (!_polite)
+ _vm->_dialogs->displayText("How about a `please\", Avvy?");
+ else {
+ Common::String tmpStr = Common::String::format("%cC%cDo you really want to quit?", kControlRegister, kControlIcon);
+ if (_vm->_dialogs->displayQuestion(tmpStr))
+ _vm->_letMeOut = true;
+ }
+ break;
+ case kVerbCodeGo:
+ _vm->_dialogs->displayText("Just use the arrow keys to walk there.");
+ break;
+ case kVerbCodeInfo: {
+ _vm->_dialogs->_aboutBox = true;
+
+ Common::String toDisplay;
+ for (int i = 0; i < 7; i++)
+ toDisplay += kControlNewLine;
+ toDisplay = toDisplay + "LORD AVALOT D'ARGENT" + kControlCenter + kControlNewLine
+ + "The medi\x91val descendant of" + kControlNewLine
+ + "Denarius Avaricius Sextus" + kControlNewLine + kControlNewLine
+ + "version " + kVersionNum + kControlNewLine + kControlNewLine + "Copyright \xEF "
+ + kCopyright + ", Mark, Mike and Thomas Thurman." + kControlRegister + 'Y' + kControlIcon;
+ _vm->_dialogs->displayText(toDisplay);
+ _vm->_dialogs->_aboutBox = false;
+ }
+ break;
+ case kVerbCodeUndress:
+ if (_wearing == kNothing)
+ _vm->_dialogs->displayText("You're already stark naked!");
+ else if (_vm->_avvysInTheCupboard) {
+ Common::String tmpStr = Common::String::format("You take off %s.", _vm->getItem(_wearing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ _wearing = kNothing;
+ _vm->refreshObjectList();
+ } else
+ _vm->_dialogs->displayText("Hadn't you better find somewhere more private, Avvy?");
+ break;
+ case kVerbCodeWear:
+ if (isHolding()) { // Wear something.
+ switch (_thing) {
+ case kObjectChastity:
+ // \? are used to avoid that ??! is parsed as a trigraph
+ _vm->_dialogs->displayText("Hey, what kind of a weirdo are you\?\?!");
+ break;
+ case kObjectClothes:
+ case kObjectHabit: {
+ // Change clothes!
+ if (_wearing != kNothing) {
+ if (_wearing == _thing)
+ _vm->_dialogs->displayText("You're already wearing that.");
+ else
+ _vm->_dialogs->displayText("You'll be rather warm wearing two sets of clothes!");
+ return;
+ } else
+ _wearing = _thing;
+
+ _vm->refreshObjectList();
+
+ byte i;
+ if (_thing == kObjectHabit)
+ i = 3;
+ else
+ i = 0;
+
+ _vm->_animation->setAvvyClothes(i);
+ }
+ break;
+ default:
+ _vm->_dialogs->displayText(kWhat);
+ }
+ }
+ break;
+ case kVerbCodePlay:
+ if (_thing == kPardon) {
+ // They just typed "play"...
+ switch (_vm->_room) {
+ case kRoomArgentPub:
+ _vm->_nim->playNim(); // ...in the pub, => play Nim.
+ break;
+ case kRoomMusicRoom:
+ playHarp();
+ break;
+ default:
+ break;
+ }
+ } else if (isHolding()) {
+ switch (_thing) {
+ case kObjectLute :
+ _vm->_dialogs->displayScrollChain('U', 7);
+
+ if (_vm->getRoom(kPeopleCwytalot) == _vm->_room)
+ _vm->_dialogs->displayScrollChain('U', 10);
+
+ if (_vm->getRoom(kPeopleDuLustie) == _vm->_room)
+ _vm->_dialogs->displayScrollChain('U', 15);
+ break;
+ case 52:
+ if (_vm->_room == kRoomMusicRoom)
+ playHarp();
+ else
+ _vm->_dialogs->displayText(kWhat);
+ break;
+ case 55:
+ if (_vm->_room == kRoomArgentPub)
+ // play_nim();
+ warning("STUB: Parser::doThat() - case kVerbCodeplay - play_nim()");
+ else
+ _vm->_dialogs->displayText(kWhat);
+ break;
+ default:
+ _vm->_dialogs->displayText(kWhat);
+ }
+ }
+ break;
+ case kVerbCodeRing:
+ if (isHolding()) {
+ if (_thing == kObjectBell) {
+ _vm->_dialogs->displayText("Ding, dong, ding, dong, ding, dong, ding, dong...");
+ if ((_vm->_bellsAreRinging) & (_vm->getFlag('B')))
+ // '\?' are used to avoid that '??!' is parsed as a trigraph
+ _vm->_dialogs->displayText("(Are you trying to join in, Avvy\?\?!)");
+ } else
+ _vm->_dialogs->displayText(kWhat);
+ }
+ break;
+ case kVerbCodeHelp:
+ // boot_help();
+ warning("STUB: Parser::doThat() - case kVerbCodehelp");
+ break;
+ case kVerbCodeLarrypass:
+ _vm->_dialogs->displayText("Wrong game!");
+ break;
+ case kVerbCodePhaon:
+ _vm->_dialogs->displayText("Hello, Phaon!");
+ break;
+ case kVerbCodeBoss:
+ // bosskey();
+ warning("STUB: Parser::doThat() - case kVerbCodeboss");
+ break;
+ case kVerbCodePee:
+ if (_vm->getFlag('P')) {
+ _vm->_dialogs->displayText("Hmm, I don't think anyone will notice...");
+ _vm->_timer->addTimer(4, Timer::kProcUrinate, Timer::kReasonGoToToilet);
+ } else {
+ Common::String tmpStr = Common::String::format("It would be %cVERY%c unwise to do that here, Avvy!", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeCheat: {
+ Common::String tmpStr = Common::String::format("%cCheat mode now enabled.", kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->_cheat = true;
+ }
+ break;
+ case kVerbCodeMagic:
+ if (_vm->_avariciusTalk > 0)
+ _vm->_dialogs->displayScrollChain('Q', 19);
+ else {
+ if ((_vm->_room == kRoomSpludwicks) & (_vm->_animation->inField(1))) {
+ // Avaricius appears!
+ _vm->_dialogs->displayScrollChain('Q', 17);
+ if (_vm->getRoom(kPeopleSpludwick) == kRoomSpludwicks)
+ _vm->_dialogs->displayScrollChain('Q', 18);
+ else {
+ Avalanche::AnimationType *spr = _vm->_animation->_sprites[1];
+ // Avaricius
+ spr->init(1, false);
+ _vm->_animation->appearPed(1, 3);
+ spr->walkTo(4);
+ spr->_callEachStepFl = true;
+ spr->_eachStepProc = Animation::kProcBackAndForth;
+ _vm->_avariciusTalk = 14;
+ _vm->_timer->addTimer(177, Timer::kProcAvariciusTalks, Timer::kReasonAvariciusTalks);
+ }
+ } else
+ _vm->_dialogs->displayText("Nothing appears to happen...");
+ }
+ break;
+ case kVerbCodeSmartAlec:
+ _vm->_dialogs->displayText("Listen, smart alec, that was just rhetoric.");
+ break;
+ case kVerbCodeExpletive:
+ switch (_sworeNum) {
+ case 0: {
+ Common::String tmpStr = Common::String::format("Avvy! Do you mind? There might be kids playing!%c%c" \
+ "(I shouldn't say it again, if I were you!)", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case 1: {
+ Common::String tmpStr = Common::String::format("You hear a distant rumble of thunder. Must you always" \
+ "do things I tell you not to?%c%cDon't do it again!", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ default: {
+ _vm->_pingo->zonk();
+ Common::String tmpStr = Common::String::format("A crack of lightning shoots from the sky, and fries you." \
+ "%c%c(`Such is the anger of the gods, Avvy!\")", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->gameOver();
+ }
+ }
+ _sworeNum++;
+ break;
+ case kVerbCodeListen:
+ if ((_vm->_bellsAreRinging) & (_vm->getFlag('B')))
+ _vm->_dialogs->displayText("All other noise is drowned out by the ringing of the bells.");
+ else if (_vm->_listen.empty())
+ _vm->_dialogs->displayText("You can't hear anything much at the moment, Avvy.");
+ else
+ _vm->_dialogs->displayText(_vm->_listen);
+ break;
+ case kVerbCodeBuy:
+ // What are they trying to buy?
+ switch (_vm->_room) {
+ case kRoomArgentPub:
+ // We're in a pub, and near the bar.
+ if (_vm->_animation->inField(5)) {
+ switch (_thing) {
+ case 51:
+ case 53:
+ case 54:
+ case 58:
+ // Beer, whisky, cider or mead.
+ if (_vm->_malagauche == 177) {
+ // Already getting us one.
+ _vm->_dialogs->displayScrollChain('D', 15);
+ return;
+ }
+
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 6);
+ return;
+ }
+
+ if (_alcoholLevel == 0)
+ _vm->incScore(3);
+
+ _vm->_background->draw(-1, -1, 11);
+ _vm->_dialogs->displayText(Common::String(booze[_thing - 51]) + ", please." + kControlRegister + '1' + kControlSpeechBubble);
+ _vm->_drinking = _thing;
+
+ _vm->_background->draw(-1, -1, 9);
+ _vm->_malagauche = 177;
+ _vm->_timer->addTimer(27, Timer::kProcBuyDrinks, Timer::kReasonDrinks);
+ break;
+ case 52:
+ examine();
+ break; // We have a right one here - buy Pepsi??!
+ case kObjectWine:
+ if (_vm->_objects[kObjectWine - 1])
+ // We've already got the wine!
+ // 1 bottle's shufishent!
+ _vm->_dialogs->displayScrollChain('D', 2);
+ else {
+ if (_vm->_malagauche == 177) {
+ // Already getting us one.
+ _vm->_dialogs->displayScrollChain('D', 15);
+ return;
+ }
+
+ if (_vm->_carryNum >= kCarryLimit) {
+ _vm->_dialogs->displayText("Your hands are full.");
+ return;
+ }
+
+ _vm->_background->draw(-1, -1, 11);
+ Common::String tmpStr = Common::String::format("Wine, please.%c1%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ if (_alcoholLevel == 0)
+ _vm->incScore(3);
+ _vm->_background->draw(-1, -1, 9);
+ _vm->_malagauche = 177;
+
+ _vm->_timer->addTimer(27, Timer::kProcBuyWine, Timer::kReasonDrinks);
+ }
+ break;
+ }
+ } else
+ // Go to the bar!
+ _vm->_dialogs->displayScrollChain('D', 5);
+ break;
+
+ case kRoomOutsideDucks:
+ if (_vm->_animation->inField(5)) {
+ if (_thing == kObjectOnion) {
+ if (_vm->_objects[kObjectOnion - 1])
+ // Not planning to juggle with the things!
+ _vm->_dialogs->displayScrollChain('D', 10);
+ else if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("Before you ask, you remember that your hands are full.");
+ else {
+ if (_boughtOnion)
+ _vm->_dialogs->displayScrollChain('D', 11);
+ else {
+ _vm->_dialogs->displayScrollChain('D', 9);
+ _vm->incScore(3);
+ }
+ // It costs thruppence.
+ _vm->decreaseMoney(3);
+ _vm->_objects[kObjectOnion - 1] = true;
+ _vm->refreshObjectList();
+ _boughtOnion = true;
+ // It's OK when it leaves the stall!
+ _vm->_rottenOnion = false;
+ _vm->_onionInVinegar = false;
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('D', 0);
+ } else
+ _vm->_dialogs->displayScrollChain('D', 0);
+ break;
+
+ case kRoomNottsPub:
+ // Can't sell to southerners.
+ _vm->_dialogs->displayScrollChain('N', 15);
+ break;
+ default:
+ // Can't buy that.
+ _vm->_dialogs->displayScrollChain('D', 0);
+ }
+ break;
+ case kVerbCodeAttack:
+ if ((_vm->_room == kRoomBrummieRoad) &&
+ ((_person == kPeopleCwytalot) || (_thing == kObjectCrossbow) || (_thing == kObjectBolt)) &&
+ (_vm->getRoom(kPeopleCwytalot) == _vm->_room)) {
+ switch (_vm->_objects[kObjectBolt - 1] + _vm->_objects[kObjectCrossbow - 1] * 2) {
+ // 0 = neither, 1 = only bolt, 2 = only crossbow, 3 = both.
+ case 0:
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ _vm->_dialogs->displayText("(At the very least, don't use your bare hands!)");
+ break;
+ case 1:
+ _vm->_dialogs->displayText("Attack _vm->him with only a crossbow bolt? Are you planning on playing darts?!");
+ break;
+ case 2:
+ _vm->_dialogs->displayText("Come on, Avvy! You're not going to get very far with only a crossbow!");
+ break;
+ case 3:
+ _vm->_dialogs->displayScrollChain('Q', 11);
+ _vm->_cwytalotGone = true;
+ _vm->_objects[kObjectBolt - 1] = false;
+ _vm->_objects[kObjectCrossbow - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_magics[11]._operation = kMagicNothing;
+ _vm->incScore(7);
+ _vm->_animation->_sprites[1]->walkTo(1);
+ _vm->_animation->_sprites[1]->_vanishIfStill = true;
+ _vm->_animation->_sprites[1]->_callEachStepFl = false;
+ _vm->setRoom(kPeopleCwytalot, kRoomDummy);
+ break;
+ default:
+ // Please try not to be so violent!
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ break;
+ case kVerbCodePasswd:
+ if (_vm->_room != kRoomBridge)
+ _vm->_dialogs->displayScrollChain('Q', 12);
+ else {
+ bool ok = true;
+ for (uint i = 0; i < _thats.size(); i++) {
+ Common::String temp = _realWords[i];
+ temp.toUppercase();
+ int pwdId = _vm->_passwordNum + kFirstPassword;
+ for (uint j = 0; j < _vocabulary[pwdId]._word.size(); j++) {
+ if (_vocabulary[pwdId]._word[j] != temp[j])
+ ok = false;
+ }
+ }
+
+ if (ok) {
+ if (_vm->_drawbridgeOpen != 0)
+ _vm->_dialogs->displayText("Contrary to your expectations, the drawbridge fails to close again.");
+ else {
+ _vm->incScore(4);
+ _vm->_dialogs->displayText("The drawbridge opens!");
+ _vm->_timer->addTimer(7, Timer::kProcOpenDrawbridge, Timer::kReasonDrawbridgeFalls);
+ _vm->_drawbridgeOpen = 1;
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 12);
+ }
+ break;
+ case kVerbCodeDie:
+ _vm->gameOver();
+ break;
+ case kVerbCodeScore: {
+ Common::String tmpStr = Common::String::format("Your score is %d,%c%cout of a possible 128.%c%c " \
+ "This gives you a rank of %s.%c%c%s", _vm->_dnascore, kControlCenter, kControlNewLine, kControlNewLine,
+ kControlNewLine, rank().c_str(), kControlNewLine, kControlNewLine, totalTime().c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodePut:
+ putProc();
+ break;
+ case kVerbCodeStand:
+ standUp();
+ break;
+ case kVerbCodeKiss:
+ if (_person == kPeoplePardon)
+ _vm->_dialogs->displayText("Kiss whom?");
+ else if (isPersonHere()) {
+ switch (_person) {
+ case kPeopleArkata:
+ _vm->_dialogs->displayScrollChain('U', 12);
+ break;
+ case kPeopleGeida:
+ _vm->_dialogs->displayScrollChain('U', 13);
+ break;
+ case kPeopleWisewoman:
+ _vm->_dialogs->displayScrollChain('U', 14);
+ break;
+ default:
+ // You WHAT?
+ _vm->_dialogs->displayScrollChain('U', 5);
+ }
+ } else if ((kPeopleAvalot <= _person) && (_person < kPeopleArkata))
+ _vm->_dialogs->displayText("Hey, what kind of a weirdo are you??");
+
+ break;
+ case kVerbCodeClimb:
+ if (_vm->_room == kRoomInsideCardiffCastle)
+ cardiffClimbing();
+ else
+ // In the wrong room!
+ _vm->_dialogs->displayText("Not with your head for heights, Avvy!");
+ break;
+ case kVerbCodeJump:
+ _vm->_timer->addTimer(1, Timer::kProcJump, Timer::kReasonJumping);
+ _vm->_userMovesAvvy = false;
+ break;
+ case kVerbCodeHiscores:
+ // show_highs();
+ warning("STUB: Parser::doThat() - case kVerbCodehighscores");
+ break;
+ case kVerbCodeWake:
+ if (isPersonHere())
+ switch (_person) {
+ case kPeoplePardon:
+ case kPeopleAvalot:
+ case 0:
+ if (!_vm->_avvyIsAwake) {
+ _vm->_avvyIsAwake = true;
+ _vm->incScore(1);
+ _vm->_avvyInBed = true;
+ // Picture of Avvy, awake in bed.
+ _vm->_background->draw(-1, -1, 2);
+ if (_vm->_teetotal)
+ _vm->_dialogs->displayScrollChain('D', 13);
+ } else
+ _vm->_dialogs->displayText("You're already awake, Avvy!");
+ break;
+ case kPeopleAyles:
+ if (!_vm->_aylesIsAwake)
+ _vm->_dialogs->displayText("You can't seem to wake him by yourself.");
+ break;
+ case kPeopleJacques: {
+ Common::String tmpStr = Common::String::format("Brother Jacques, Brother Jacques, are you asleep?%c1%c" \
+ "Hmmm... that doesn't seem to do any good...", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ default:
+ _vm->_dialogs->displayText("It's difficult to awaken people who aren't asleep...!");
+ }
+ break;
+ case kVerbCodeSit:
+ if (_vm->_room == kRoomNottsPub) {
+ if (_vm->_sittingInPub)
+ _vm->_dialogs->displayText("You're already sitting!");
+ else {
+ // Move Avvy to the place, and sit him down.
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_timer->addTimer(1, Timer::kProcAvvySitDown, Timer::kReasonSittingDown);
+ }
+ } else {
+ // Default doodah.
+ _vm->fadeOut();
+ _vm->fadeIn();
+ Common::String tmpStr = Common::String::format("A few hours later...%cnothing much has happened...", kControlParagraph);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeRestart:
+ if (_vm->_dialogs->displayQuestion("Restart game and lose changes?")) {
+ _vm->fadeOut();
+ _vm->newGame();
+ _vm->fadeIn();
+ }
+ break;
+ case kVerbCodePardon:
+ _vm->_dialogs->displayText("Hey, a verb would be helpful!");
+ break;
+ case kVerbCodeHello:
+ _vm->_dialogs->sayHello();
+ break;
+ case kVerbCodeThanks:
+ _vm->_dialogs->sayOK();
+ break;
+ default:
+ Common::String tmpStr = Common::String::format("%cUnhandled verb: %d", kControlBell, _verb);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+}
+
+void Parser::verbOpt(byte verb, Common::String &answer, char &ansKey) {
+ // kVerbCodegive isn't dealt with by this procedure, but by ddm__with.
+ switch (verb) {
+ case kVerbCodeExam:
+ answer = "Examine";
+ ansKey = 'x';
+ break;
+ case kVerbCodeDrink:
+ answer = "Drink";
+ ansKey = 'D';
+ break;
+ case kVerbCodeWear:
+ answer = "Wear";
+ ansKey = 'W';
+ break;
+ case kVerbCodeRing:
+ answer = "Ring";
+ ansKey = 'R';
+ break; // Only the bell!
+ case kVerbCodePlay:
+ answer = "Play";
+ ansKey = 'P';
+ break;
+ case kVerbCodeEat:
+ answer = "Eat";
+ ansKey = 'E';
+ break;
+ default:
+ answer = "? Unknown!"; // Bug!
+ ansKey = '?';
+ }
+}
+
+void Parser::doVerb(VerbCode id) {
+ _weirdWord = false;
+ _polite = true;
+ _verb = id;
+ doThat();
+}
+
+void Parser::resetVariables() {
+ _wearing = kNothing;
+ _sworeNum = 0;
+ _alcoholLevel = 0;
+ _boughtOnion = false;
+}
+
+void Parser::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_wearing);
+ sz.syncAsByte(_sworeNum);
+ sz.syncAsByte(_alcoholLevel);
+ if (sz.isLoading() && sz.getVersion() < 2) {
+ int dummy;
+ sz.syncAsByte(dummy);
+ }
+ sz.syncAsByte(_boughtOnion);
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/parser.h b/engines/avalanche/parser.h
new file mode 100644
index 0000000000..20066329e5
--- /dev/null
+++ b/engines/avalanche/parser.h
@@ -0,0 +1,153 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_PARSER_H
+#define AVALANCHE_PARSER_H
+
+#include "avalanche/enums.h"
+
+#include "common/events.h"
+#include "common/str.h"
+#include "common/serializer.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Parser {
+public:
+ static const int16 kParserWordsNum = 277; // How many words does the parser know?
+ static const int16 kFirstPassword = 88; // words[kFirstPassword] should equal "TIROS".
+ static const byte kPardon = 254; // Didn't understand / wasn't given.
+ static const byte kNothing = 250;
+ static const byte kMoved = 0; // This word was moved. (Usually because it was the subject of conversation.)
+
+ struct VocabEntry {
+ byte _number;
+ Common::String _word;
+
+ void init(byte number, Common::String word) {
+ _number = number;
+ _word = word;
+ }
+ };
+
+ VocabEntry _vocabulary[kParserWordsNum];
+
+ Common::String _realWords[11];
+ VerbCode _verb;
+ byte _thing;
+ People _person;
+ bool _polite;
+ Common::String _inputText;
+ Common::String _inputTextBackup;
+ byte _inputTextPos;
+ bool _quote;
+ bool _cursorState;
+ bool _weirdWord;
+
+ byte _wearing; // what you're wearing
+
+ Parser(AvalancheEngine *vm);
+
+ void init();
+ void parse();
+ void doThat();
+ void verbOpt(byte verb, Common::String &answer, char &ansKey);
+ void drink();
+
+ void handleInputText(const Common::Event &event);
+ void handleBackspace();
+ void handleReturn();
+ void handleFunctionKey(const Common::Event &event);
+ void plotText();
+ void cursorOn();
+ void cursorOff();
+ void tryDropdown();
+ int16 getPos(const Common::String &crit, const Common::String &src);
+ void doVerb(VerbCode id);
+
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+
+private:
+ AvalancheEngine *_vm;
+
+ struct RankType {
+ uint16 _score;
+ char _title[20];
+ };
+
+ static const char *kCopyright;
+ static const char *kVersionNum;
+
+ Common::String _thats;
+ byte _thing2;
+ byte _sworeNum; // number of times you've sworn
+ byte _alcoholLevel; // Your blood alcohol level.
+ bool _boughtOnion; // Have you bought an onion yet?
+
+ byte wordNum(Common::String word);
+ void replace(Common::String oldChars, byte newChar);
+
+ Common::String rank();
+ Common::String totalTime();
+
+ void clearWords();
+ void cheatParse(Common::String codes);
+ void stripPunctuation(Common::String &word);
+ void displayWhat(byte target, bool animate, bool &ambiguous);
+ bool doPronouns();
+ void properNouns();
+ void lookAround();
+ void openDoor();
+ void storeInterrogation(byte interrogation);
+ void examineObject();
+ bool isPersonHere();
+ void exampers();
+ bool isHolding();
+ void openBox(bool isOpening);
+ void examine();
+ void inventory();
+ void swallow();
+ void peopleInRoom();
+ void putProc();
+ void notInOrder();
+ void goToCauldron();
+ bool giveToSpludwick();
+ void cardiffClimbing();
+ void already();
+ void standUp();
+ void getProc(char thing);
+ void giveGeidaTheLute();
+ void playHarp();
+ void winSequence();
+ void wipeText();
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_PARSER_H
diff --git a/engines/avalanche/pingo.cpp b/engines/avalanche/pingo.cpp
new file mode 100644
index 0000000000..433924f594
--- /dev/null
+++ b/engines/avalanche/pingo.cpp
@@ -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 the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* PINGO Full-screen sub-parts of the game. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/pingo.h"
+
+namespace Avalanche {
+
+Pingo::Pingo(AvalancheEngine *vm) {
+ _vm = vm;
+}
+
+void Pingo::dPlot(int16 x, int16 y, Common::String z) {
+ warning("STUB: Pingo::dPlot()");
+}
+
+void Pingo::bossKey() {
+ warning("STUB: Pingo::bossKey()");
+}
+
+void Pingo::copy02() { // taken from Wobble (below)
+ warning("STUB: Pingo::copy02()");
+}
+
+void Pingo::copy03() { // taken from Wobble (below)
+ warning("STUB: Pingo::copy03()");
+}
+
+void Pingo::copyPage(byte frp, byte top) { // taken from Copy02 (above)
+ warning("STUB: Pingo::copyPage()");
+}
+
+void Pingo::wobble() {
+ warning("STUB: Pingo::wobble()");
+}
+
+void Pingo::zl(int16 x1, int16 y1, int16 x2, int16 y2) {
+ warning("STUB: Pingo::zl()");
+}
+
+void Pingo::zonk() {
+ warning("STUB: Pingo::zonk()");
+}
+
+void Pingo::winningPic() {
+ Common::File f;
+ _vm->fadeOut();
+
+ if (!f.open("finale.avd"))
+ error("AVALANCHE: File not found: finale.avd");
+
+#if 0
+ for (int bit = 0; bit <= 3; bit++) {
+ port[0x3c4] = 2;
+ port[0x3ce] = 4;
+ port[0x3c5] = 1 << bit;
+ port[0x3cf] = bit;
+ blockread(f, mem[0xa000 * 0], 16000);
+ }
+#endif
+
+ f.close();
+
+ warning("STUB: Pingo::winningPic()");
+
+ _vm->fadeIn();
+
+#if 0
+ do {
+ _vm->check();
+ } while (!(keypressed() || (mrelease > 0)));
+ while (keypressed())
+ char r = readkey();
+ major_redraw();
+#endif
+
+ warning("STUB: Pingo::winningPic()");
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/pingo.h b/engines/avalanche/pingo.h
new file mode 100644
index 0000000000..72fdb54c2a
--- /dev/null
+++ b/engines/avalanche/pingo.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* PINGO Full-screen sub-parts of the game. */
+
+#ifndef AVALANCHE_PINGO_H
+#define AVALANCHE_PINGO_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Pingo {
+public:
+ Pingo(AvalancheEngine *vm);
+
+ void bossKey();
+ void copy02();
+ void copy03();
+ void copyPage(byte frp, byte top);
+ void wobble();
+ void zonk();
+ void winningPic();
+
+private:
+ AvalancheEngine *_vm;
+
+ void dPlot(int16 x, int16 y, Common::String z);
+ void zl(int16 x1, int16 y1, int16 x2, int16 y2);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_PINGO_H
diff --git a/engines/avalanche/sequence.cpp b/engines/avalanche/sequence.cpp
new file mode 100644
index 0000000000..3a60c4ec1d
--- /dev/null
+++ b/engines/avalanche/sequence.cpp
@@ -0,0 +1,230 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* SEQUENCE The sequencer. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/sequence.h"
+
+namespace Avalanche {
+
+Sequence::Sequence(AvalancheEngine *vm) {
+ _vm = vm;
+
+ resetVariables();
+}
+
+void Sequence::resetVariables() {
+ _flipToWhere = kRoomNowhere;
+ _flipToPed = 0;
+}
+
+void Sequence::init(byte what) {
+ _seq[0] = what;
+
+ for (int i = 1; i < kSeqLength; i++)
+ _seq[i] = 0;
+}
+
+void Sequence::add(byte what) {
+ for (int16 i = 0; i < kSeqLength; i++) {
+ if (_seq[i] == 0) {
+ _seq[i] = what;
+ return;
+ }
+ }
+}
+
+void Sequence::switchRoom(Room where, byte ped) {
+ add(kNowFlip);
+
+ _flipToWhere = where;
+ _flipToPed = ped;
+}
+
+void Sequence::startTimer() {
+ _vm->_timer->loseTimer(Timer::kReasonSequencer);
+ _vm->_timer->addTimer(7, Timer::kProcSequence, Timer::kReasonSequencer);
+}
+
+void Sequence::startTimerImmobilized() {
+ // They can't move.
+ _vm->_userMovesAvvy = false;
+ // And they're not moving now.
+ _vm->_animation->stopWalking();
+ // Apart from that, it's the same thing.
+ startTimer();
+}
+
+void Sequence::shoveLeft() {
+ for (uint i = 0; i < kSeqLength - 1; i++)
+ _seq[i] = _seq[i + 1];
+ _seq[kSeqLength - 1] = 0;
+}
+
+void Sequence::callSequencer() {
+ byte curSeq = _seq[0];
+
+ switch (curSeq) {
+ case 0:
+ // No more routines.
+ return;
+ break;
+ case kNowFlip:
+ // Flip room.
+ _vm->_userMovesAvvy = true;
+ _vm->flipRoom(_flipToWhere, _flipToPed);
+ shoveLeft();
+ break;
+ }
+
+ if (curSeq <= 176) {
+ // Show a frame.
+ _vm->_background->draw(-1, -1, curSeq - 1);
+ shoveLeft();
+ }
+
+ // Make sure this PROC gets called again.
+ startTimer();
+}
+
+void Sequence::startHallSeq(Room whither, byte ped) {
+ init(1);
+ add(2);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startOutsideSeq(Room whither, byte ped) {
+ init(1);
+ add(2);
+ add(3);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startCardiffSeq(Room whither, byte ped) {
+ init(1);
+ add(5);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startNaughtyDukeSeq() {
+ init(2);
+ startTimer();
+}
+
+void Sequence::startGardenSeq() {
+ init(2);
+ add(1);
+ add(3);
+ startTimer();
+}
+
+void Sequence::startDuckSeq() {
+ init(3);
+ add(2);
+ add(1);
+ add(4);
+ startTimer();
+}
+
+void Sequence::startLustiesSeq3(Room whither, byte ped) {
+ init(4);
+ add(5);
+ add(6);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startMusicRoomSeq2(Room whither, byte ped) {
+ init(5);
+ add(6);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startGeidaLuteSeq() {
+ init(5);
+ // He falls asleep...
+ add(6);
+ // Not really closing, but we're using the same procedure.
+ startTimer();
+}
+
+void Sequence::startMusicRoomSeq() {
+ init(6);
+ add(5);
+ add(7);
+ startTimer();
+}
+
+void Sequence::startWinSeq() {
+ init(7);
+ add(8);
+ add(9);
+ startTimer();
+}
+
+void Sequence::startCupboardSeq() {
+ init(8);
+ add(7);
+ startTimer();
+}
+
+void Sequence::startLustiesSeq2(Room whither, byte ped) {
+ init(8);
+ add(9);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startCardiffSeq2() {
+ init(1);
+ if (_vm->_arrowInTheDoor)
+ add(3);
+ else
+ add(2);
+
+ if (_vm->_takenPen)
+ _vm->_background->draw(-1, -1, 3);
+
+ startTimer();
+}
+
+void Sequence::startDummySeq(Room whither, byte ped) {
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::synchronize(Common::Serializer &sz) {
+ sz.syncBytes(_seq, kSeqLength);
+ sz.syncAsByte(_flipToWhere);
+ sz.syncAsByte(_flipToPed);
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/sequence.h b/engines/avalanche/sequence.h
new file mode 100644
index 0000000000..d3c1b54963
--- /dev/null
+++ b/engines/avalanche/sequence.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* SEQUENCE The sequencer. */
+
+#ifndef AVALANCHE_SEQUENCE_H
+#define AVALANCHE_SEQUENCE_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Sequence {
+private:
+ static const int16 kNowFlip = 177;
+ static const int16 kSeqLength = 10;
+
+ byte _seq[kSeqLength];
+
+ Room _flipToWhere;
+ byte _flipToPed;
+
+ AvalancheEngine *_vm;
+
+ void shoveLeft(); // This is called by Timer when it's time to do another frame. It shifts everything to the left.
+ void init(byte what);
+ void add(byte what);
+ void switchRoom(Room where, byte ped);
+ void startTimer();
+ void startTimerImmobilized();
+
+public:
+ Sequence(AvalancheEngine *vm);
+ void synchronize(Common::Serializer &sz);
+ void resetVariables();
+ void callSequencer();
+
+ void startCupboardSeq();
+ void startMusicRoomSeq();
+ void startMusicRoomSeq2(Room whither, byte ped);
+ void startGardenSeq();
+ void startGeidaLuteSeq();
+ void startWinSeq();
+ void startNaughtyDukeSeq();
+ void startLustiesSeq2(Room whither, byte ped);
+ void startLustiesSeq3(Room whither, byte ped);
+ void startHallSeq(Room whither, byte ped);
+ void startCardiffSeq(Room whither, byte ped);
+ void startOutsideSeq(Room whither, byte ped);
+ void startDuckSeq();
+ void startCardiffSeq2();
+ void startDummySeq(Room whither, byte ped);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_SEQUENCE_H
diff --git a/engines/avalanche/sound.cpp b/engines/avalanche/sound.cpp
new file mode 100644
index 0000000000..c324df4713
--- /dev/null
+++ b/engines/avalanche/sound.cpp
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/sound.h"
+
+#include "audio/audiostream.h"
+#include "common/config-manager.h"
+
+namespace Avalanche {
+
+SoundHandler::SoundHandler(AvalancheEngine *vm) : _vm(vm) {
+ _soundFl = true;
+ _speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
+ _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+ _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, true);
+}
+
+SoundHandler::~SoundHandler() {
+ _vm->_mixer->stopHandle(_speakerHandle);
+}
+
+/**
+ * Stop any sound that might be playing
+ */
+void SoundHandler::stopSound() {
+ _vm->_mixer->stopAll();
+}
+
+/**
+ * Turn digitized sound on and off
+ */
+void SoundHandler::toggleSound() {
+ _soundFl = !_soundFl;
+}
+
+void SoundHandler::syncVolume() {
+ int soundVolume;
+
+ if (ConfMan.getBool("sfx_mute") || ConfMan.getBool("mute"))
+ soundVolume = -1;
+ else
+ soundVolume = MIN(255, ConfMan.getInt("sfx_volume"));
+
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolume);
+}
+
+void SoundHandler::playNote(int freq, int length) {
+ // Does the user not want any sound?
+ if (!_soundFl || !_vm->_mixer->isReady())
+ return;
+
+ // Start a note playing (we will stop it when the timer expires).
+ _speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, freq, length);
+}
+
+void SoundHandler::click() {
+ _vm->_mixer->stopAll();
+
+ playNote(7177, 1);
+}
+
+void SoundHandler::blip() {
+ _vm->_mixer->stopAll();
+
+ playNote(177, 77);
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/sound.h b/engines/avalanche/sound.h
new file mode 100644
index 0000000000..25b6b267d3
--- /dev/null
+++ b/engines/avalanche/sound.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AVALANCHE_SOUND_H
+#define AVALANCHE_SOUND_H
+
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
+namespace Avalanche {
+
+class SoundHandler {
+public:
+ bool _soundFl;
+
+ SoundHandler(AvalancheEngine *vm);
+ ~SoundHandler();
+
+ void toggleSound();
+ void playNote(int freq, int length);
+ void click();
+ void blip();
+ void syncVolume();
+ void stopSound();
+
+private:
+ AvalancheEngine *_vm;
+ Audio::PCSpeaker *_speakerStream;
+ Audio::SoundHandle _speakerHandle;
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_SOUND_H
diff --git a/engines/avalanche/timer.cpp b/engines/avalanche/timer.cpp
new file mode 100644
index 0000000000..40f2af529a
--- /dev/null
+++ b/engines/avalanche/timer.cpp
@@ -0,0 +1,693 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TIMEOUT The scheduling unit. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/timer.h"
+
+namespace Avalanche {
+
+Timer::Timer(AvalancheEngine *vm) {
+ _vm = vm;
+
+ resetVariables();
+}
+
+/**
+ * Add a nex timer
+ * @remarks Originally called 'set_up_timer'
+ */
+void Timer::addTimer(int32 duration, byte action, byte reason) {
+ byte i = 0;
+ while ((i < 7) && (_times[i]._timeLeft != 0)) {
+ if (_times[i]._reason == reason) // We only add a timer if it's not already in the array.
+ return;
+ i++;
+ }
+
+ if (i == 7)
+ return; // Oh dear... No timer left
+
+ // Everything's OK here!
+ _times[i]._timeLeft = duration;
+ _times[i]._action = action;
+ _times[i]._reason = reason;
+}
+
+/**
+ * Update the timers
+ * @remarks Originally called 'one_tick'
+ */
+void Timer::updateTimer() {
+ if (_vm->_menu->isActive())
+ return;
+
+ for (int i = 0; i < 7; i++) {
+ if (_times[i]._timeLeft <= 0)
+ continue;
+
+ _times[i]._timeLeft--;
+
+ if (_times[i]._timeLeft == 0) {
+ switch (_times[i]._action) {
+ case kProcOpenDrawbridge :
+ openDrawbridge();
+ break;
+ case kProcAvariciusTalks :
+ avariciusTalks();
+ break;
+ case kProcUrinate :
+ urinate();
+ break;
+ case kProcToilet :
+ toilet();
+ break;
+ case kProcBang:
+ bang();
+ break;
+ case kProcBang2:
+ bang2();
+ break;
+ case kProcStairs:
+ stairs();
+ break;
+ case kProcCardiffSurvey:
+ cardiffSurvey();
+ break;
+ case kProcCardiffReturn:
+ cardiffReturn();
+ break;
+ case kProcCwytalotInHerts:
+ cwytalotInHerts();
+ break;
+ case kProcGetTiedUp:
+ getTiedUp();
+ break;
+ case kProcGetTiedUp2:
+ getTiedUp2();
+ break;
+ case kProcHangAround:
+ hangAround();
+ break;
+ case kProcHangAround2:
+ hangAround2();
+ break;
+ case kProcAfterTheShootemup:
+ afterTheShootemup();
+ break;
+ case kProcJacquesWakesUp:
+ jacquesWakesUp();
+ break;
+ case kProcNaughtyDuke:
+ naughtyDuke();
+ break;
+ case kProcNaughtyDuke2:
+ naughtyDuke2();
+ break;
+ case kProcNaughtyDuke3:
+ naughtyDuke3();
+ break;
+ case kProcJump:
+ jump();
+ break;
+ case kProcSequence:
+ _vm->_sequence->callSequencer();
+ break;
+ case kProcCrapulusSpludOut:
+ crapulusSaysSpludOut();
+ break;
+ case kProcDawnDelay:
+ _vm->fadeIn();
+ break;
+ case kProcBuyDrinks:
+ buyDrinks();
+ break;
+ case kProcBuyWine:
+ buyWine();
+ break;
+ case kProcCallsGuards:
+ callsGuards();
+ break;
+ case kProcGreetsMonk:
+ greetsMonk();
+ break;
+ case kProcFallDownOubliette:
+ fallDownOubliette();
+ break;
+ case kProcMeetAvaroid:
+ meetAvaroid();
+ break;
+ case kProcRiseUpOubliette:
+ riseUpOubliette();
+ break;
+ case kProcRobinHoodAndGeida:
+ robinHoodAndGeida();
+ break;
+ case kProcRobinHoodAndGeidaTalk:
+ robinHoodAndGeidaTalk();
+ break;
+ case kProcAvalotReturns:
+ avalotReturns();
+ break;
+ case kProcAvvySitDown:
+ avvySitDown();
+ break;
+ case kProcGhostRoomPhew:
+ ghostRoomPhew();
+ break;
+ case kProcArkataShouts:
+ arkataShouts();
+ break;
+ case kProcWinning:
+ winning();
+ break;
+ case kProcAvalotFalls:
+ avalotFalls();
+ break;
+ case kProcSpludwickGoesToCauldron:
+ spludwickGoesToCauldron();
+ break;
+ case kProcSpludwickLeavesCauldron:
+ spludwickLeavesCauldron();
+ break;
+ case kProcGiveLuteToGeida:
+ giveLuteToGeida();
+ break;
+ }
+ }
+ }
+
+ _vm->_roomCycles++; // Cycles since you've been in this room.
+}
+
+void Timer::loseTimer(byte which) {
+ for (int i = 0; i < 7; i++) {
+ if (_times[i]._reason == which)
+ _times[i]._timeLeft = 0; // Cancel this one!
+ }
+
+}
+
+void Timer::openDrawbridge() {
+ _vm->_drawbridgeOpen++;
+ _vm->_background->draw(-1, -1, _vm->_drawbridgeOpen - 2);
+
+ if (_vm->_drawbridgeOpen == 4)
+ _vm->_magics[1]._operation = kMagicNothing; // You may enter the drawbridge.
+ else
+ addTimer(7, kProcOpenDrawbridge, kReasonDrawbridgeFalls);
+}
+
+void Timer::avariciusTalks() {
+ _vm->_dialogs->displayScrollChain('Q', _vm->_avariciusTalk);
+ _vm->_avariciusTalk++;
+
+ if (_vm->_avariciusTalk < 17)
+ addTimer(177, kProcAvariciusTalks, kReasonAvariciusTalks);
+ else
+ _vm->incScore(3);
+}
+
+void Timer::urinate() {
+ _vm->_animation->_sprites[0]->turn(kDirUp);
+ _vm->_animation->stopWalking();
+ _vm->drawDirection();
+ addTimer(14, kProcToilet, kReasonGoToToilet);
+}
+
+void Timer::toilet() {
+ _vm->_dialogs->displayText("That's better!");
+}
+
+void Timer::bang() {
+ Common::String tmpStr = Common::String::format("%c< BANG! >", kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+ addTimer(30, kProcBang2, kReasonExplosion);
+}
+
+void Timer::bang2() {
+ _vm->_dialogs->displayText("Hmm... sounds like Spludwick's up to something...");
+}
+
+void Timer::stairs() {
+ _vm->_sound->blip();
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_brummieStairs = 2;
+ _vm->_magics[10]._operation = kMagicSpecial;
+ _vm->_magics[10]._data = 2; // Reached the bottom of the stairs.
+ _vm->_magics[3]._operation = kMagicNothing; // Stop them hitting the sides (or the game will hang.)
+}
+
+void Timer::cardiffSurvey() {
+ if (_vm->_cardiffQuestionNum == 0) {
+ _vm->_cardiffQuestionNum++;
+ _vm->_dialogs->displayScrollChain('Q', 27);
+ }
+
+ _vm->_dialogs->displayScrollChain('Z', _vm->_cardiffQuestionNum);
+ _vm->_interrogation = _vm->_cardiffQuestionNum;
+ addTimer(182, kProcCardiffSurvey, kReasonCardiffsurvey);
+}
+
+void Timer::cardiffReturn() {
+ _vm->_dialogs->displayScrollChain('Q', 28);
+ cardiffSurvey(); // Add end of question.
+}
+
+void Timer::cwytalotInHerts() {
+ _vm->_dialogs->displayScrollChain('Q', 29);
+}
+
+void Timer::getTiedUp() {
+ _vm->_dialogs->displayScrollChain('Q', 34); // ...Trouble!
+ _vm->_userMovesAvvy = false;
+ _vm->_beenTiedUp = true;
+ _vm->_animation->stopWalking();
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->stopWalk();
+ spr->stopHoming();
+ spr->_callEachStepFl = true;
+ spr->_eachStepProc = Animation::kProcGrabAvvy;
+ addTimer(70, kProcGetTiedUp2, kReasonGettingTiedUp);
+}
+
+void Timer::getTiedUp2() {
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_animation->_sprites[1]->walkTo(4);
+ _vm->_magics[3]._operation = kMagicNothing; // No effect when you touch the boundaries.
+ _vm->_friarWillTieYouUp = true;
+}
+
+void Timer::hangAround() {
+ _vm->_animation->_sprites[1]->_doCheck = false;
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->init(7, true); // Robin Hood
+ _vm->setRoom(kPeopleRobinHood, kRoomRobins);
+ _vm->_animation->appearPed(0, 1);
+ _vm->_dialogs->displayScrollChain('Q', 39);
+ avvy->walkTo(6);
+ addTimer(55, kProcHangAround2, kReasonHangingAround);
+}
+
+void Timer::hangAround2() {
+ _vm->_dialogs->displayScrollChain('Q', 40);
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->_vanishIfStill = false;
+ spr->walkTo(3);
+ _vm->setRoom(kPeopleFriarTuck, kRoomRobins);
+ _vm->_dialogs->displayScrollChain('Q', 41);
+ _vm->_animation->_sprites[0]->remove();
+ spr->remove(); // Get rid of Robin Hood and Friar Tuck.
+
+ addTimer(1, kProcAfterTheShootemup, kReasonHangingAround);
+ // Immediately call the following proc (when you have a chance).
+
+ _vm->_tiedUp = false;
+
+ // _vm->_enid->backToBootstrap(1); Call the shoot-'em-up. TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+}
+
+void Timer::afterTheShootemup() {
+ // Only placed this here to replace the minigame. TODO: Remove it when the shoot em' up is implemented!
+ _vm->flipRoom(_vm->_room, 1);
+
+ _vm->_animation->_sprites[0]->init(0, true); // Avalot.
+ _vm->_animation->appearPed(0, 1);
+ _vm->_userMovesAvvy = true;
+ _vm->_objects[kObjectCrossbow - 1] = true;
+ _vm->refreshObjectList();
+
+ // Same as the added line above: TODO: Remove it later!!!
+ _vm->_dialogs->displayText(Common::String("P.S.: There should have been the mini-game called \"shoot em' up\", " \
+ "but I haven't implemented it yet: you get the crossbow automatically.") + kControlNewLine + kControlNewLine + "Peter (uruk)");
+
+#if 0
+ byte shootscore, gain;
+
+ shootscore = mem[storage_seg * storage_ofs];
+ gain = (shootscore + 5) / 10; // Rounding up.
+
+ display(string("\6Your score was ") + strf(shootscore) + '.' + "\r\rYou gain (" +
+ strf(shootscore) + " 0xF6 10) = " + strf(gain) + " points.");
+
+ if (gain > 20) {
+ display("But we won't let you have more than 20 points!");
+ points(20);
+ } else
+ points(gain);
+#endif
+
+ warning("STUB: Timer::after_the_shootemup()");
+
+ _vm->_dialogs->displayScrollChain('Q', 70);
+}
+
+void Timer::jacquesWakesUp() {
+ _vm->_jacquesState++;
+
+ switch (_vm->_jacquesState) { // Additional pictures.
+ case 1 :
+ _vm->_background->draw(-1, -1, 0); // Eyes open.
+ _vm->_dialogs->displayScrollChain('Q', 45);
+ break;
+ case 2 : // Going through the door.
+ _vm->_background->draw(-1, -1, 1); // Not on the floor.
+ _vm->_background->draw(-1, -1, 2); // But going through the door.
+ _vm->_magics[5]._operation = kMagicNothing; // You can't wake him up now.
+ break;
+ case 3 : // Gone through the door.
+ _vm->_background->draw(-1, -1, 1); // Not on the floor, either.
+ _vm->_background->draw(-1, -1, 3); // He's gone... so the door's open.
+ _vm->setRoom(kPeopleJacques, kRoomNowhere); // Gone!
+ break;
+ }
+
+ if (_vm->_jacquesState == 5) {
+ _vm->_bellsAreRinging = true;
+ _vm->_aylesIsAwake = true;
+ _vm->incScore(2);
+ }
+
+ switch (_vm->_jacquesState) {
+ case 1:
+ case 2:
+ case 3:
+ addTimer(12, kProcJacquesWakesUp, kReasonJacquesWakingUp);
+ break;
+ case 4:
+ addTimer(24, kProcJacquesWakesUp, kReasonJacquesWakingUp);
+ break;
+ }
+}
+
+void Timer::naughtyDuke() { // This is when the Duke comes in and takes your money.
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->init(9, false); // Here comes the Duke.
+ _vm->_animation->appearPed(1, 0); // He starts at the door...
+ spr->walkTo(2); // He walks over to you.
+
+ // Let's get the door opening.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_sequence->startNaughtyDukeSeq();
+
+ addTimer(50, kProcNaughtyDuke2, kReasonNaughtyDuke);
+}
+
+void Timer::naughtyDuke2() {
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ _vm->_dialogs->displayScrollChain('Q', 48); // "Ha ha, it worked again!"
+ spr->walkTo(0); // Walk to the door.
+ spr->_vanishIfStill = true; // Then go away!
+
+ addTimer(32, kProcNaughtyDuke3, kReasonNaughtyDuke);
+}
+
+void Timer::naughtyDuke3() {
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_sequence->startNaughtyDukeSeq();
+}
+
+void Timer::jump() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+
+ _vm->_jumpStatus++;
+ switch (_vm->_jumpStatus) {
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ avvy->_y--;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ case 16:
+ case 18:
+ case 19:
+ avvy->_y++;
+ break;
+ }
+
+ if (_vm->_jumpStatus == 20) { // End of jump.
+ _vm->_userMovesAvvy = true;
+ _vm->_jumpStatus = 0;
+ } else // Still jumping.
+ addTimer(1, kProcJump, kReasonJumping);
+
+ if ((_vm->_jumpStatus == 10) // You're at the highest point of your jump.
+ && (_vm->_room == kRoomInsideCardiffCastle)
+ && (_vm->_arrowInTheDoor == true)
+ && (_vm->_animation->inField(2))) { // Beside the wall
+ // Grab the arrow!
+ if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("You fail to grab it, because your hands are full.");
+ else {
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_arrowInTheDoor = false; // You've got it.
+ _vm->_objects[kObjectBolt - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayScrollChain('Q', 50);
+ _vm->incScore(3);
+ }
+ }
+}
+
+void Timer::crapulusSaysSpludOut() {
+ _vm->_dialogs->displayScrollChain('Q', 56);
+ _vm->_crapulusWillTell = false;
+}
+
+void Timer::buyDrinks() {
+ _vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
+ _vm->_malagauche = 0;
+
+ _vm->_dialogs->displayScrollChain('D', _vm->_drinking); // Display message about it.
+ _vm->_pingo->wobble(); // Do the special effects.
+ _vm->_dialogs->displayScrollChain('D', 1); // That'll be thruppence.
+ if (_vm->decreaseMoney(3)) // Pay 3d.
+ _vm->_dialogs->displayScrollChain('D', 3); // Tell 'em you paid up.
+ _vm->_parser->drink();
+}
+
+void Timer::buyWine() {
+ _vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
+ _vm->_malagauche = 0;
+
+ _vm->_dialogs->displayScrollChain('D', 50); // You buy the wine.
+ _vm->_dialogs->displayScrollChain('D', 1); // It'll be thruppence.
+ if (_vm->decreaseMoney(3)) {
+ _vm->_dialogs->displayScrollChain('D', 4); // You paid up.
+ _vm->_objects[kObjectWine - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_wineState = 1; // OK Wine.
+ }
+}
+
+void Timer::callsGuards() {
+ _vm->_dialogs->displayScrollChain('Q', 58); // "GUARDS!!!"
+ _vm->gameOver();
+}
+
+void Timer::greetsMonk() {
+ _vm->_dialogs->displayScrollChain('Q', 59);
+ _vm->_enteredLustiesRoomAsMonk = true;
+}
+
+void Timer::fallDownOubliette() {
+ _vm->_magics[8]._operation = kMagicNothing;
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_moveY++; // Increments dx/dy!
+ avvy->_y += avvy->_moveY; // Dowwwn we go...
+ addTimer(3, kProcFallDownOubliette, kReasonFallingDownOubliette);
+}
+
+void Timer::meetAvaroid() {
+ if (_vm->_metAvaroid) {
+ Common::String tmpStr = Common::String::format("You can't expect to be %cthat%c lucky twice in a row!",
+ kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->gameOver();
+ } else {
+ _vm->_dialogs->displayScrollChain('Q', 60);
+ _vm->_metAvaroid = true;
+ addTimer(1, kProcRiseUpOubliette, kReasonRisingUpOubliette);
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_facingDir = kDirLeft;
+ avvy->_x = 151;
+ avvy->_moveX = -3;
+ avvy->_moveY = -5;
+
+ _vm->_graphics->setBackgroundColor(kColorGreen);
+ }
+}
+
+void Timer::riseUpOubliette() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_visible = true;
+ avvy->_moveY++; // Decrements dx/dy!
+ avvy->_y -= avvy->_moveY; // Uuuupppp we go...
+ if (avvy->_moveY > 0)
+ addTimer(3, kProcRiseUpOubliette, kReasonRisingUpOubliette);
+ else
+ _vm->_userMovesAvvy = true;
+}
+
+void Timer::robinHoodAndGeida() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->init(7, true);
+ _vm->_animation->appearPed(0, 6);
+ avvy->walkTo(5);
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->stopWalk();
+ spr->_facingDir = kDirLeft;
+ addTimer(20, kProcRobinHoodAndGeidaTalk, kReasonRobinHoodAndGeida);
+ _vm->_geidaFollows = false;
+}
+
+void Timer::robinHoodAndGeidaTalk() {
+ _vm->_dialogs->displayScrollChain('Q', 66);
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ avvy->walkTo(1);
+ spr->walkTo(1);
+ avvy->_vanishIfStill = true;
+ spr->_vanishIfStill = true;
+
+ addTimer(162, kProcAvalotReturns, kReasonRobinHoodAndGeida);
+}
+
+void Timer::avalotReturns() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ avvy->remove();
+ spr->remove();
+ avvy->init(0, true);
+ _vm->_animation->appearPed(0, 0);
+ _vm->_dialogs->displayScrollChain('Q', 67);
+ _vm->_userMovesAvvy = true;
+}
+
+/**
+ * This is used when you sit down in the pub in Notts. It loops around
+ * so that it will happen when Avvy stops walking.
+ * @remarks Originally called 'avvy_sit_down'
+ */
+void Timer::avvySitDown() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_homing) // Still walking.
+ addTimer(1, kProcAvvySitDown, kReasonSittingDown);
+ else {
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_sittingInPub = true;
+ _vm->_userMovesAvvy = false;
+ avvy->_visible = false;
+ }
+}
+
+void Timer::ghostRoomPhew() {
+ Common::String tmpStr = Common::String::format("%cPHEW!%c You're glad to get out of %cthere!",
+ kControlItalic, kControlRoman, kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+void Timer::arkataShouts() {
+ if (_vm->_teetotal)
+ return;
+
+ _vm->_dialogs->displayScrollChain('Q', 76);
+ addTimer(160, kProcArkataShouts, kReasonArkataShouts);
+}
+
+void Timer::winning() {
+ _vm->_dialogs->displayScrollChain('Q', 79);
+ _vm->_pingo->winningPic();
+
+ warning("STUB: Timer::winning()");
+#if 0
+ do {
+ _vm->checkclick();
+ } while (!(_vm->mrelease == 0));
+#endif
+ // TODO: To be implemented with Pingo::winningPic().
+
+ _vm->callVerb(kVerbCodeScore);
+ _vm->_dialogs->displayText(" T H E E N D ");
+ _vm->_letMeOut = true;
+}
+
+void Timer::avalotFalls() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_stepNum < 5) {
+ avvy->_stepNum++;
+ addTimer(3, kProcAvalotFalls, kReasonFallingOver);
+ } else {
+ Common::String toDisplay = Common::String::format("%c%c%c%c%c%c%c%c%c%c%c%c%cZ%c",
+ kControlNewLine, kControlNewLine, kControlNewLine, kControlNewLine,
+ kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlInsertSpaces,
+ kControlInsertSpaces, kControlInsertSpaces, kControlInsertSpaces,
+ kControlInsertSpaces, kControlRegister, kControlIcon);
+ _vm->_dialogs->displayText(toDisplay);
+ }
+}
+
+void Timer::spludwickGoesToCauldron() {
+ if (_vm->_animation->_sprites[1]->_homing)
+ addTimer(1, kProcSpludwickGoesToCauldron, kReasonSpludwickWalk);
+ else
+ addTimer(17, kProcSpludwickLeavesCauldron, kReasonSpludwickWalk);
+}
+
+void Timer::spludwickLeavesCauldron() {
+ _vm->_animation->_sprites[1]->_callEachStepFl = true; // So that normal procs will continue.
+}
+
+void Timer::giveLuteToGeida() { // Moved here from Acci.
+ _vm->_dialogs->displayScrollChain('Q', 86);
+ _vm->incScore(4);
+ _vm->_lustieIsAsleep = true;
+ _vm->_sequence->startGeidaLuteSeq();
+}
+
+void Timer::resetVariables() {
+ for (int i = 0; i < 7; i++) {
+ _times[i]._timeLeft = 0;
+ _times[i]._action = 0;
+ _times[i]._reason = 0;
+ }
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/timer.h b/engines/avalanche/timer.h
new file mode 100644
index 0000000000..9a91c4d24b
--- /dev/null
+++ b/engines/avalanche/timer.h
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TIMEOUT The scheduling unit. */
+
+#ifndef AVALANCHE_TIMER_H
+#define AVALANCHE_TIMER_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Timer {
+public:
+ // Reason runs between 1 and 28.
+ enum Reason {
+ kReasonDrawbridgeFalls = 2,
+ kReasonAvariciusTalks = 3,
+ kReasonGoToToilet = 4,
+ kReasonExplosion = 5,
+ kReasonBrummieStairs = 6,
+ kReasonCardiffsurvey = 7,
+ kReasonCwytalotInHerts = 8,
+ kReasonGettingTiedUp = 9,
+ kReasonHangingAround = 10, // Tied to the tree in Nottingham.
+ kReasonJacquesWakingUp = 11,
+ kReasonNaughtyDuke = 12,
+ kReasonJumping = 13,
+ kReasonSequencer = 14,
+ kReasonCrapulusSaysSpludwickOut = 15,
+ kReasonDawndelay = 16,
+ kReasonDrinks = 17,
+ kReasonDuLustieTalks = 18,
+ kReasonFallingDownOubliette = 19,
+ kReasonMeetingAvaroid = 20,
+ kReasonRisingUpOubliette = 21,
+ kReasonRobinHoodAndGeida = 22,
+ kReasonSittingDown = 23,
+ kReasonGhostRoomPhew = 1,
+ kReasonArkataShouts = 24,
+ kReasonWinning = 25,
+ kReasonFallingOver = 26,
+ kReasonSpludwickWalk = 27,
+ kReasonGeidaSings = 28
+ };
+
+ // Proc runs between 1 and 41.
+ enum Proc {
+ kProcOpenDrawbridge = 3,
+ kProcAvariciusTalks = 4,
+ kProcUrinate = 5,
+ kProcToilet = 6,
+ kProcBang = 7,
+ kProcBang2 = 8,
+ kProcStairs = 9,
+ kProcCardiffSurvey = 10,
+ kProcCardiffReturn = 11,
+ kProcCwytalotInHerts = 12,
+ kProcGetTiedUp = 13,
+ kProcGetTiedUp2 = 1,
+ kProcHangAround = 14,
+ kProcHangAround2 = 15,
+ kProcAfterTheShootemup = 32,
+ kProcJacquesWakesUp = 16,
+ kProcNaughtyDuke = 17,
+ kProcNaughtyDuke2 = 18,
+ kProcNaughtyDuke3 = 38,
+ kProcJump = 19,
+ kProcSequence = 20,
+ kProcCrapulusSpludOut = 21,
+ kProcDawnDelay = 22,
+ kProcBuyDrinks = 23,
+ kProcBuyWine = 24,
+ kProcCallsGuards = 25,
+ kProcGreetsMonk = 26,
+ kProcFallDownOubliette = 27,
+ kProcMeetAvaroid = 28,
+ kProcRiseUpOubliette = 29,
+ kProcRobinHoodAndGeida = 2,
+ kProcRobinHoodAndGeidaTalk = 30,
+ kProcAvalotReturns = 31,
+ kProcAvvySitDown = 33, // In Nottingham.
+ kProcGhostRoomPhew = 34,
+ kProcArkataShouts = 35,
+ kProcWinning = 36,
+ kProcAvalotFalls = 37,
+ kProcSpludwickGoesToCauldron = 39,
+ kProcSpludwickLeavesCauldron = 40,
+ kProcGiveLuteToGeida = 41
+ };
+
+ struct TimerType {
+ int32 _timeLeft;
+ byte _action;
+ byte _reason;
+ };
+
+ TimerType _times[7];
+
+ Timer(AvalancheEngine *vm);
+
+ void resetVariables();
+ void addTimer(int32 duration, byte action, byte reason);
+ void updateTimer();
+ void loseTimer(byte which);
+
+ // Procedures to do things at the end of amounts of time:
+ void openDrawbridge();
+ void avariciusTalks();
+ void urinate();
+ void toilet();
+ void bang();
+ void bang2();
+ void stairs();
+ void cardiffSurvey();
+ void cardiffReturn();
+ void cwytalotInHerts();
+ void getTiedUp();
+ void getTiedUp2();
+ void hangAround();
+ void hangAround2();
+ void afterTheShootemup();
+ void jacquesWakesUp();
+ void naughtyDuke();
+ void naughtyDuke2();
+ void naughtyDuke3();
+ void jump();
+ void crapulusSaysSpludOut();
+ void buyDrinks();
+ void buyWine();
+ void callsGuards();
+ void greetsMonk();
+ void fallDownOubliette();
+ void meetAvaroid();
+ void riseUpOubliette();
+ void robinHoodAndGeida();
+ void robinHoodAndGeidaTalk();
+ void avalotReturns();
+ void avvySitDown();
+ void ghostRoomPhew();
+ void arkataShouts();
+ void winning();
+ void avalotFalls();
+ void spludwickGoesToCauldron();
+ void spludwickLeavesCauldron();
+ void giveLuteToGeida();
+
+private:
+ AvalancheEngine *_vm;
+
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_TIMER_H
diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp
index 6cc0c45963..af7e91f7eb 100644
--- a/engines/cge/cge.cpp
+++ b/engines/cge/cge.cpp
@@ -25,7 +25,6 @@
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
-#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/fs.h"
#include "engines/advancedDetector.h"
diff --git a/engines/cge/cge.h b/engines/cge/cge.h
index 0e8c5a05bb..61558c0989 100644
--- a/engines/cge/cge.h
+++ b/engines/cge/cge.h
@@ -80,6 +80,12 @@ class Talk;
#define kSayTheEnd 41
+enum GameType {
+ kGameTypeNone = 0,
+ kGameTypeSoltys,
+ kGameTypeSfinx
+};
+
// our engine debug channels
enum {
kCGEDebugBitmap = 1 << 0,
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index f4f1cd3e0b..5325558f8b 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;
@@ -1046,7 +1046,7 @@ void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, i
for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
len = line.size();
lcnt++;
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if (len == 0 || *tmpStr == '.')
continue;
@@ -1132,7 +1132,7 @@ void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, i
_sprite->_flags._bDel = true;
// Extract the filename, without the extension
- strcpy(_sprite->_file, fname);
+ Common::strlcpy(_sprite->_file, fname, sizeof(_sprite->_file));
char *p = strchr(_sprite->_file, '.');
if (p)
*p = '\0';
@@ -1158,7 +1158,7 @@ void CGEEngine::loadScript(const char *fname) {
char *p;
lcnt++;
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((line.size() == 0) || (*tmpStr == '.'))
continue;
diff --git a/engines/cge/configure.engine b/engines/cge/configure.engine
new file mode 100644
index 0000000000..72af1197be
--- /dev/null
+++ b/engines/cge/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cge "CGE" yes
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index 289aede99e..c377970c51 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -36,77 +36,116 @@ static const PlainGameDescriptor CGEGames[] = {
namespace CGE {
-static const ADGameDescription gameDescriptions[] = {
+struct CgeGameDescription {
+ ADGameDescription desc;
+ GameType gameType;
+};
+
+static const CgeGameDescription gameDescriptions[] = {
{
- "soltys", "",
{
- {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
- {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
- AD_LISTEND
+ "soltys", "",
+ {
+ {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
+ {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
},
- Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+ kGameTypeSoltys
},
{
- "soltys", "Soltys Freeware",
{
- {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
- {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
- AD_LISTEND
+ "soltys", "Soltys Freeware",
+ {
+ {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
+ {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
},
- Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+ kGameTypeSoltys
},
{
- "soltys", "Soltys Demo (not supported)",
{
- {"vol.cat", 0, "1e077c8ff58109a187f07ac54b0c873a", 18788},
- {"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
- AD_LISTEND
+ "soltys", "Soltys Demo (not supported)",
+ {
+ {"vol.cat", 0, "1e077c8ff58109a187f07ac54b0c873a", 18788},
+ {"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
+ AD_LISTEND
+ },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO , GUIO0()
},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO , GUIO0()
+ kGameTypeSoltys
},
{
- "soltys", "Soltys Demo (not supported)",
{
- {"vol.cat", 0, "f17987487fab1ebddd781d8d02fedecc", 7168},
- {"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
- AD_LISTEND
+ "soltys", "Soltys Demo (not supported)",
+ {
+ {"vol.cat", 0, "f17987487fab1ebddd781d8d02fedecc", 7168},
+ {"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_DEMO , GUIO0()
},
- Common::PL_POL, Common::kPlatformDOS, ADGF_DEMO , GUIO0()
+ kGameTypeSoltys
},
{
- "soltys", "Soltys Freeware v1.0",
{
- {"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176},
- {"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868},
- AD_LISTEND
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176},
+ {"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868},
+ AD_LISTEND
+ },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO0()
},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO0()
+ kGameTypeSoltys
},
{
- "soltys", "Soltys Freeware v1.0",
{
- {"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176},
- {"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339},
- AD_LISTEND
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176},
+ {"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
},
- Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+ kGameTypeSoltys
},
{
- // Polish version, provided by Strangerke
- "sfinx", "Sfinx Freeware",
{
- {"vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024},
- {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844},
- AD_LISTEND
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "fcae86b20eaa5cedec17b24fa5e85eb4", 50176},
+ {"vol.dat", 0, "ff10d54acc2c95696c57e05819b6906f", 8450151},
+ AD_LISTEND
+ },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO0()
},
- Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+ kGameTypeSoltys
},
- AD_TABLE_END_MARKER
+ {
+ {
+ // Polish version, provided by Strangerke
+ "sfinx", "Sfinx Freeware",
+ {
+ {"vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024},
+ {"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844},
+ AD_LISTEND
+ },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+ },
+ kGameTypeSfinx
+ },
+
+ {AD_TABLE_END_MARKER, kGameTypeNone}
};
static const ADFileBasedFallback fileBasedFallback[] = {
- { &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } },
+ { &gameDescriptions[0].desc, { "vol.cat", "vol.dat", 0 } },
{ 0, { 0 } }
};
@@ -114,7 +153,7 @@ static const ADFileBasedFallback fileBasedFallback[] = {
class CGEMetaEngine : public AdvancedMetaEngine {
public:
- CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(ADGameDescription), CGEGames) {
+ CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(CGE::CgeGameDescription), CGEGames) {
_singleid = "soltys";
}
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/text.cpp b/engines/cge/text.cpp
index 27bb0608fd..08ff005e1e 100644
--- a/engines/cge/text.cpp
+++ b/engines/cge/text.cpp
@@ -69,7 +69,7 @@ int16 Text::count() {
for (line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
char *s;
assert(line.size() <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
if (!Common::isDigit(*s))
@@ -101,8 +101,7 @@ void Text::load() {
for (idx = 0, line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
int n = line.size();
char *s;
- assert(n <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
if (!Common::isDigit(*s))
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index 56a0754527..4954e638ab 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -214,8 +214,7 @@ Sprite *Sprite::expand() {
for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
len = line.size();
- assert(len <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
lcnt++;
if (len == 0 || *tmpStr == '.')
continue;
@@ -826,7 +825,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 +844,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 +897,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/cine/configure.engine b/engines/cine/configure.engine
new file mode 100644
index 0000000000..2b7e2085fa
--- /dev/null
+++ b/engines/cine/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cine "Cinematique evo 1" yes
diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp
index 176380c14f..2abe32f797 100644
--- a/engines/cine/script_fw.cpp
+++ b/engines/cine/script_fw.cpp
@@ -380,8 +380,7 @@ RawScript::RawScript(const FWScriptInfo &info, const byte *data, uint16 s) :
* Copy constructor
*/
RawScript::RawScript(const RawScript &src) : _size(src._size),
- _data(new byte[_size + 1]), _labels(src._labels) {
-
+ _data(new byte[src._size + 1]), _labels(src._labels) {
assert(_data);
memcpy(_data, src._data, _size + 1);
}
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index 10404ae56b..de6f91d8c3 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -281,7 +281,7 @@ void PCSoundDriver::resetChannel(int channel) {
}
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
- : _mixer(mixer) {
+ : _upCb(0), _upRef(0), _mixer(mixer) {
_sampleRate = _mixer->getOutputRate();
_opl = makeAdLibOPL(_sampleRate);
memset(_channelsVolumeTable, 0, sizeof(_channelsVolumeTable));
@@ -309,9 +309,7 @@ void AdLibSoundDriver::setupChannel(int channel, const byte *data, int instrumen
volume = 0;
}
volume += volume / 4;
- if (volume > 127) {
- volume = 127;
- }
+
_channelsVolumeTable[channel] = volume;
setupInstrument(data, channel);
}
diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 5db778dfda..2d7075cba1 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -48,6 +48,15 @@ namespace Composer {
ComposerEngine::ComposerEngine(OSystem *syst, const ComposerGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_rnd = new Common::RandomSource("composer");
_audioStream = NULL;
+ _currSoundPriority = 0;
+ _currentTime = 0;
+ _lastTime = 0;
+ _needsUpdate = true;
+ _directoriesToStrip = 1;
+ _mouseVisible = true;
+ _mouseEnabled = false;
+ _mouseSpriteId = 0;
+ _lastButton = NULL;
}
ComposerEngine::~ComposerEngine() {
@@ -79,12 +88,6 @@ Common::Error ComposerEngine::run() {
_queuedScripts[i]._scriptId = 0;
}
- _mouseVisible = true;
- _mouseEnabled = false;
- _mouseSpriteId = 0;
- _lastButton = NULL;
-
- _directoriesToStrip = 1;
if (!_bookIni.loadFromFile("book.ini")) {
_directoriesToStrip = 0;
if (!_bookIni.loadFromFile("programs/book.ini")) {
@@ -103,7 +106,6 @@ Common::Error ComposerEngine::run() {
height = atoi(getStringFromConfig("Common", "Height").c_str());
initGraphics(width, height, true);
_screen.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- _needsUpdate = true;
Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor();
CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(),
@@ -113,11 +115,12 @@ Common::Error ComposerEngine::run() {
loadLibrary(0);
- _currentTime = 0;
- _lastTime = 0;
-
uint fps = atoi(getStringFromConfig("Common", "FPS").c_str());
- uint frameTime = 1000 / fps;
+ uint frameTime = 125; // Default to 125ms (1000/8)
+ if (fps != 0)
+ frameTime = 1000 / fps;
+ else
+ warning("FPS in book.ini is zero. Defaulting to 8...");
uint32 lastDrawTime = 0;
while (!shouldQuit()) {
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/configure.engine b/engines/composer/configure.engine
new file mode 100644
index 0000000000..71a79acb5d
--- /dev/null
+++ b/engines/composer/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine composer "Magic Composer" yes
diff --git a/engines/composer/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
deleted file mode 100644
index 7325b105ad..0000000000
--- a/engines/configure.engines
+++ /dev/null
@@ -1,54 +0,0 @@
-# This file is included from the main "configure" script
-# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
-add_engine scumm_7_8 "v7 & v8 games" yes
-add_engine he "HE71+ games" yes
-add_engine agi "AGI" yes
-add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
-add_engine agos2 "AGOS 2 games" yes
-add_engine cge "CGE" yes
-add_engine cine "Cinematique evo 1" yes
-add_engine composer "Magic Composer" yes
-add_engine cruise "Cinematique evo 2" yes
-add_engine draci "Dragon History" yes
-add_engine drascula "Drascula: The Vampire Strikes Back" yes
-add_engine dreamweb "Dreamweb" yes
-add_engine gob "Gobli*ns" yes
-add_engine groovie "Groovie" yes "groovie2" "7th Guest"
-add_engine groovie2 "Groovie 2 games" no
-add_engine hopkins "Hopkins FBI" yes "" "" "16bit"
-add_engine hugo "Hugo Trilogy" yes
-add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
-add_engine lol "Lands of Lore" yes
-add_engine eob "Eye of the Beholder" yes
-add_engine lastexpress "The Last Express" no "" "" "16bit"
-add_engine lure "Lure of the Temptress" yes
-add_engine made "MADE" yes
-add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
-add_engine cstime "Where in Time is Carmen Sandiego?" no
-add_engine riven "Riven: The Sequel to Myst" no "" "" "16bit"
-add_engine myst "Myst" no "" "" "16bit"
-add_engine neverhood "Neverhood" no
-add_engine parallaction "Parallaction" yes
-add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
-add_engine queen "Flight of the Amazon Queen" yes
-add_engine saga "SAGA" yes "ihnm saga2" "ITE"
-add_engine ihnm "IHNM" yes
-add_engine saga2 "SAGA 2 games" no
-add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
-add_engine sci32 "SCI32 games" no
-add_engine sky "Beneath a Steel Sky" yes
-add_engine sword1 "Broken Sword" yes
-add_engine sword2 "Broken Sword II" yes
-add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
-add_engine teenagent "Teen Agent" yes
-add_engine testbed "TestBed: the Testing framework" no
-add_engine tinsel "Tinsel" yes
-add_engine toltecs "3 Skulls of the Toltecs" yes
-add_engine toon "Toonstruck" yes
-add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
-add_engine tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
-add_engine tsage "TsAGE" yes
-add_engine tucker "Bud Tucker in Double Trouble" yes
-add_engine voyeur "Voyeur" yes
-add_engine wintermute "Wintermute" no "" "" "png zlib vorbis 16bit"
diff --git a/engines/cruise/POTFILES b/engines/cruise/POTFILES
new file mode 100644
index 0000000000..e3b25bdda8
--- /dev/null
+++ b/engines/cruise/POTFILES
@@ -0,0 +1 @@
+engines/cruise/menu.cpp
diff --git a/engines/cruise/configure.engine b/engines/cruise/configure.engine
new file mode 100644
index 0000000000..925da25370
--- /dev/null
+++ b/engines/cruise/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cruise "Cinematique evo 2" yes
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
index 9782df8f09..3e49e77770 100644
--- a/engines/cruise/cruise.h
+++ b/engines/cruise/cruise.h
@@ -43,10 +43,6 @@
*/
namespace Cruise {
-enum CruiseGameType {
- GType_CRUISE = 1
-};
-
#define GAME_FRAME_DELAY_1 50
#define GAME_FRAME_DELAY_2 100
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index b632e4ea7a..bce3f184db 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -20,8 +20,6 @@
*
*/
-
-
#include "base/plugins.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -34,21 +32,12 @@ namespace Cruise {
struct CRUISEGameDescription {
ADGameDescription desc;
-
- int gameType;
- uint32 features;
};
const char *CruiseEngine::getGameId() const {
return _gameDescription->desc.gameid;
}
-int CruiseEngine::getGameType() const {
- return _gameDescription->gameType;
-}
-uint32 CruiseEngine::getFeatures() const {
- return _gameDescription->features;
-}
Common::Language CruiseEngine::getLanguage() const {
return _gameDescription->desc.language;
}
@@ -77,8 +66,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -90,8 +77,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -103,8 +88,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -116,8 +99,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -129,8 +110,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -142,8 +121,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -155,8 +132,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{ // Amiga English US GOLD edition.
{
@@ -168,8 +143,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{ // Amiga Italian US GOLD edition.
{
@@ -181,8 +154,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{ // AtariST English KixxXL edition.
{
@@ -194,8 +165,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -207,8 +176,6 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
{
{
@@ -220,10 +187,8 @@ static const CRUISEGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO0()
},
- GType_CRUISE,
- 0,
},
- {AD_TABLE_END_MARKER, 0, 0}
+ {AD_TABLE_END_MARKER}
};
}
diff --git a/engines/draci/barchive.cpp b/engines/draci/barchive.cpp
index 31dfe62dee..584367fdfb 100644
--- a/engines/draci/barchive.cpp
+++ b/engines/draci/barchive.cpp
@@ -203,12 +203,12 @@ void BArchive::openArchive(const Common::String &path) {
uint32 fileOffset;
fileOffset = reader.readUint32LE();
- _f.seek(fileOffset); // Seek to next file in archive
+ _f.seek(fileOffset); // Seek to next file in archive
- _files[i]._compLength = _f.readUint16LE(); // Compressed size
+ _files[i]._compLength = _f.readUint16LE(); // Compressed size
// should be the same as uncompressed
- _files[i]._length = _f.readUint16LE(); // Original size
+ _files[i]._length = _f.readUint16LE(); // Original size
_files[i]._offset = fileOffset; // Offset of file from start
@@ -216,9 +216,9 @@ void BArchive::openArchive(const Common::String &path) {
assert(compressionType == 0 &&
"Compression type flag is non-zero (file is compressed)");
- _files[i]._crc = _f.readByte(); // CRC checksum of the file
- _files[i]._data = NULL; // File data will be read in on demand
- _files[i]._stopper = 0; // Dummy value; not used in BAR files, needed in DFW
+ _files[i]._crc = _f.readByte(); // CRC checksum of the file
+ _files[i]._data = NULL; // File data will be read in on demand
+ _files[i]._stopper = 0; // Dummy value; not used in BAR files, needed in DFW
}
// Last footer item should be equal to footerOffset
diff --git a/engines/draci/configure.engine b/engines/draci/configure.engine
new file mode 100644
index 0000000000..09022b06f5
--- /dev/null
+++ b/engines/draci/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine draci "Dragon History" yes
diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp
index 6aa8477887..06730cfba7 100644
--- a/engines/draci/draci.cpp
+++ b/engines/draci/draci.cpp
@@ -92,6 +92,32 @@ DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc)
DebugMan.addDebugChannel(kDraciWalkingDebugLevel, "walking", "Walking debug info");
_console = new DraciConsole(this);
+
+ _screen = 0;
+ _mouse = 0;
+ _game = 0;
+ _script = 0;
+ _anims = 0;
+ _sound = 0;
+ _music = 0;
+ _smallFont = 0;
+ _bigFont = 0;
+ _iconsArchive = 0;
+ _objectsArchive = 0;
+ _spritesArchive = 0;
+ _paletteArchive = 0;
+ _roomsArchive = 0;
+ _overlaysArchive = 0;
+ _animationsArchive = 0;
+ _walkingMapsArchive = 0;
+ _itemsArchive = 0;
+ _itemImagesArchive = 0;
+ _initArchive = 0;
+ _stringsArchive = 0;
+ _soundsArchive = 0;
+ _dubbingArchive = 0;
+ _showWalkingMap = 0;
+ _pauseStartTime = 0;
}
bool DraciEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index c4108cc0c7..009f1bb3d2 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -52,6 +52,55 @@ enum {
Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
uint i;
+ _dialogueLinesNum = 0;
+ _blockNum = 0;
+
+ for (i = 0; i < kDialogueLines; i++)
+ _dialogueAnims[0] = 0;
+
+ _loopStatus = kStatusOrdinary;
+ _loopSubstatus = kOuterLoop;
+ _shouldQuit = 0;
+ _shouldExitLoop = 0;
+ _isReloaded = 0;
+ _speechTick = 0;
+ _speechDuration = 0;
+ _objUnderCursor = 0;
+ _animUnderCursor = 0;
+ _markedAnimationIndex = 0;
+ _scheduledPalette = 0;
+ _fadePhases = 0;
+ _fadePhase = 0;
+ _fadeTick = 0;
+ _mouseChangeTick = 0;
+ _enableQuickHero = 0;
+ _wantQuickHero = 0;
+ _enableSpeedText = 0;
+ _titleAnim = 0;
+ _inventoryAnim = 0;
+ _walkingMapOverlay = 0;
+ _walkingShortestPathOverlay = 0;
+ _walkingObliquePathOverlay = 0;
+ _currentItem = 0;
+ _itemUnderCursor = 0;
+ _previousItemPosition = 0;
+
+ for (i = 0; i < kInventorySlots; i++)
+ _inventory[i] = 0;
+
+ _newRoom = 0;
+ _newGate = 0;
+ _previousRoom = 0;
+ _pushedNewRoom = 0;
+ _pushedNewGate = 0;
+ _currentDialogue = 0;
+ _dialogueArchive = 0;
+ _dialogueBlocks = 0;
+ _dialogueBegin = 0;
+ _dialogueExit = 0;
+ _currentBlock = 0;
+ _lastBlock = 0;
+
BArchive *initArchive = _vm->_initArchive;
const BAFile *file;
@@ -951,9 +1000,9 @@ void Game::dialogueMenu(int dialogueID) {
debugC(7, kDraciLogicDebugLevel,
"hit: %d, _lines[hit]: %d, lastblock: %d, dialogueLines: %d, dialogueExit: %d",
- hit, _lines[hit], _lastBlock, _dialogueLinesNum, _dialogueExit);
+ hit, (hit >= 0 ? _lines[hit] : -1), _lastBlock, _dialogueLinesNum, _dialogueExit);
- if ((!_dialogueExit) && (hit != -1) && (_lines[hit] != -1)) {
+ if ((!_dialogueExit) && (hit >= 0) && (_lines[hit] != -1)) {
if ((oldLines == 1) && (_dialogueLinesNum == 1) && (_lines[hit] == _lastBlock)) {
break;
}
@@ -1361,7 +1410,7 @@ void Game::enterNewRoom() {
// for the dragon in the persons array
if (_newRoom == _info._mapRoom) {
_persons[kDragonObject]._x = 160;
- _persons[kDragonObject]._y = 0;
+ _persons[kDragonObject]._y = 0;
}
// Set the appropriate loop status before loading the room
diff --git a/engines/draci/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/script.cpp b/engines/draci/script.cpp
index 8ff60033ed..504476869e 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -41,65 +41,65 @@ namespace Draci {
void Script::setupCommandList() {
/** A table of all the commands the game player uses */
static const GPL2Command gplCommands[] = {
- { 0, 0, "gplend", 0, { }, NULL },
- { 0, 1, "exit", 0, { }, NULL },
- { 1, 1, "goto", 1, { kGPL2Ident }, &Script::c_Goto },
- { 2, 1, "Let", 2, { kGPL2Ident, kGPL2Math }, &Script::c_Let },
- { 3, 1, "if", 2, { kGPL2Math, kGPL2Ident }, &Script::c_If },
- { 4, 1, "Start", 2, { kGPL2Ident, kGPL2Str }, &Script::start },
- { 5, 1, "Load", 2, { kGPL2Ident, kGPL2Str }, &Script::load },
- { 5, 2, "StartPlay", 2, { kGPL2Ident, kGPL2Str }, &Script::startPlay },
- { 5, 3, "JustTalk", 0, { }, &Script::justTalk },
- { 5, 4, "JustStay", 0, { }, &Script::justStay },
- { 6, 1, "Talk", 2, { kGPL2Ident, kGPL2Str }, &Script::talk },
- { 7, 1, "ObjStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStat },
- { 7, 2, "ObjStat_On", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStatOn },
- { 8, 1, "IcoStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::icoStat },
- { 9, 1, "Dialogue", 1, { kGPL2Str }, &Script::dialogue },
- { 9, 2, "ExitDialogue", 0, { }, &Script::exitDialogue },
- { 9, 3, "ResetDialogue", 0, { }, &Script::resetDialogue },
- { 9, 4, "ResetDialogueFrom", 0, { }, &Script::resetDialogueFrom },
- { 9, 5, "ResetBlock", 1, { kGPL2Ident }, &Script::resetBlock },
- { 10, 1, "WalkOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOn },
- { 10, 2, "StayOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::stayOn },
- { 10, 3, "WalkOnPlay", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOnPlay },
- { 11, 1, "LoadPalette", 1, { kGPL2Str }, &Script::loadPalette },
- { 12, 1, "SetPalette", 0, { }, &Script::setPalette },
- { 12, 2, "BlackPalette", 0, { }, &Script::blackPalette },
- { 13, 1, "FadePalette", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalette },
- { 13, 2, "FadePalettePlay", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalettePlay },
- { 14, 1, "NewRoom", 2, { kGPL2Ident, kGPL2Num }, &Script::newRoom },
- { 15, 1, "ExecInit", 1, { kGPL2Ident }, &Script::execInit },
- { 15, 2, "ExecLook", 1, { kGPL2Ident }, &Script::execLook },
- { 15, 3, "ExecUse", 1, { kGPL2Ident }, &Script::execUse },
- { 18, 1, "LoadMusic", 1, { kGPL2Str }, &Script::loadMusic },
- { 18, 2, "StartMusic", 0, { }, &Script::startMusic },
- { 18, 3, "StopMusic", 0, { }, &Script::stopMusic },
- { 19, 1, "Mark", 0, { }, &Script::mark },
- { 19, 2, "Release", 0, { }, &Script::release },
- { 20, 1, "Play", 0, { }, &Script::play },
- { 21, 1, "LoadMap", 1, { kGPL2Str }, &Script::loadMap },
- { 21, 2, "RoomMap", 0, { }, &Script::roomMap },
- { 22, 1, "DisableQuickHero", 0, { }, &Script::disableQuickHero },
- { 22, 2, "EnableQuickHero", 0, { }, &Script::enableQuickHero },
- { 23, 1, "DisableSpeedText", 0, { }, &Script::disableSpeedText },
- { 23, 2, "EnableSpeedText", 0, { }, &Script::enableSpeedText },
- { 24, 1, "QuitGame", 0, { }, &Script::quitGame },
- { 25, 1, "PushNewRoom", 0, { }, &Script::pushNewRoom },
- { 25, 2, "PopNewRoom", 0, { }, &Script::popNewRoom },
+ { 0, 0, "gplend", 0, { }, NULL },
+ { 0, 1, "exit", 0, { }, NULL },
+ { 1, 1, "goto", 1, { kGPL2Ident }, &Script::c_Goto },
+ { 2, 1, "Let", 2, { kGPL2Ident, kGPL2Math }, &Script::c_Let },
+ { 3, 1, "if", 2, { kGPL2Math, kGPL2Ident }, &Script::c_If },
+ { 4, 1, "Start", 2, { kGPL2Ident, kGPL2Str }, &Script::start },
+ { 5, 1, "Load", 2, { kGPL2Ident, kGPL2Str }, &Script::load },
+ { 5, 2, "StartPlay", 2, { kGPL2Ident, kGPL2Str }, &Script::startPlay },
+ { 5, 3, "JustTalk", 0, { }, &Script::justTalk },
+ { 5, 4, "JustStay", 0, { }, &Script::justStay },
+ { 6, 1, "Talk", 2, { kGPL2Ident, kGPL2Str }, &Script::talk },
+ { 7, 1, "ObjStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStat },
+ { 7, 2, "ObjStat_On", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStatOn },
+ { 8, 1, "IcoStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::icoStat },
+ { 9, 1, "Dialogue", 1, { kGPL2Str }, &Script::dialogue },
+ { 9, 2, "ExitDialogue", 0, { }, &Script::exitDialogue },
+ { 9, 3, "ResetDialogue", 0, { }, &Script::resetDialogue },
+ { 9, 4, "ResetDialogueFrom", 0, { }, &Script::resetDialogueFrom },
+ { 9, 5, "ResetBlock", 1, { kGPL2Ident }, &Script::resetBlock },
+ { 10, 1, "WalkOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOn },
+ { 10, 2, "StayOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::stayOn },
+ { 10, 3, "WalkOnPlay", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOnPlay },
+ { 11, 1, "LoadPalette", 1, { kGPL2Str }, &Script::loadPalette },
+ { 12, 1, "SetPalette", 0, { }, &Script::setPalette },
+ { 12, 2, "BlackPalette", 0, { }, &Script::blackPalette },
+ { 13, 1, "FadePalette", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalette },
+ { 13, 2, "FadePalettePlay", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalettePlay },
+ { 14, 1, "NewRoom", 2, { kGPL2Ident, kGPL2Num }, &Script::newRoom },
+ { 15, 1, "ExecInit", 1, { kGPL2Ident }, &Script::execInit },
+ { 15, 2, "ExecLook", 1, { kGPL2Ident }, &Script::execLook },
+ { 15, 3, "ExecUse", 1, { kGPL2Ident }, &Script::execUse },
+ { 18, 1, "LoadMusic", 1, { kGPL2Str }, &Script::loadMusic },
+ { 18, 2, "StartMusic", 0, { }, &Script::startMusic },
+ { 18, 3, "StopMusic", 0, { }, &Script::stopMusic },
+ { 19, 1, "Mark", 0, { }, &Script::mark },
+ { 19, 2, "Release", 0, { }, &Script::release },
+ { 20, 1, "Play", 0, { }, &Script::play },
+ { 21, 1, "LoadMap", 1, { kGPL2Str }, &Script::loadMap },
+ { 21, 2, "RoomMap", 0, { }, &Script::roomMap },
+ { 22, 1, "DisableQuickHero", 0, { }, &Script::disableQuickHero },
+ { 22, 2, "EnableQuickHero", 0, { }, &Script::enableQuickHero },
+ { 23, 1, "DisableSpeedText", 0, { }, &Script::disableSpeedText },
+ { 23, 2, "EnableSpeedText", 0, { }, &Script::enableSpeedText },
+ { 24, 1, "QuitGame", 0, { }, &Script::quitGame },
+ { 25, 1, "PushNewRoom", 0, { }, &Script::pushNewRoom },
+ { 25, 2, "PopNewRoom", 0, { }, &Script::popNewRoom },
// The following commands are not used in the original game files.
- { 16, 1, "RepaintInventory", 0, { }, NULL },
- { 16, 2, "ExitInventory", 0, { }, NULL },
- { 17, 1, "ExitMap", 0, { }, NULL },
- { 18, 4, "FadeOutMusic", 1, { kGPL2Num }, NULL },
- { 18, 5, "FadeInMusic", 1, { kGPL2Num }, NULL },
+ { 16, 1, "RepaintInventory", 0, { }, NULL },
+ { 16, 2, "ExitInventory", 0, { }, NULL },
+ { 17, 1, "ExitMap", 0, { }, NULL },
+ { 18, 4, "FadeOutMusic", 1, { kGPL2Num }, NULL },
+ { 18, 5, "FadeInMusic", 1, { kGPL2Num }, NULL },
// The following commands are not even defined in the game
// sources, but their numbers are allocated for internal
// purposes of the old player.
- { 26, 1, "ShowCheat", 0, { }, NULL },
- { 26, 2, "HideCheat", 0, { }, NULL },
- { 26, 3, "ClearCheat", 1, { kGPL2Num }, NULL },
- { 27, 1, "FeedPassword", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, NULL }
+ { 26, 1, "ShowCheat", 0, { }, NULL },
+ { 26, 2, "HideCheat", 0, { }, NULL },
+ { 26, 3, "ClearCheat", 1, { kGPL2Num }, NULL },
+ { 27, 1, "FeedPassword", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, NULL }
};
/** Operators used by the mathematical evaluator */
diff --git a/engines/draci/sprite.cpp b/engines/draci/sprite.cpp
index 965cdabf3e..9a78904d25 100644
--- a/engines/draci/sprite.cpp
+++ b/engines/draci/sprite.cpp
@@ -38,9 +38,9 @@ const Displacement kNoDisplacement = { 0, 0, 1.0, 1.0 };
* height height of the image in the buffer
*/
static void transformToRows(byte *img, uint16 width, uint16 height) {
- byte *buf = new byte[width * height];
+ byte *buf = new byte[(uint)(width * height)];
byte *tmp = buf;
- memcpy(buf, img, width * height);
+ memcpy(buf, img, (uint)(width * height));
for (uint16 i = 0; i < width; ++i) {
for (uint16 j = 0; j < height; ++j) {
diff --git a/engines/draci/surface.cpp b/engines/draci/surface.cpp
index 8380f8777b..4156398070 100644
--- a/engines/draci/surface.cpp
+++ b/engines/draci/surface.cpp
@@ -80,9 +80,9 @@ 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);
+ memset(ptr, color, (uint)(w * h));
}
/**
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index f1ae769d80..195b968860 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -556,9 +556,15 @@ bool WalkingState::alignHeroToEdge(const Common::Point &p1, const Common::Point
}
bool reachedEnd;
if (movement == kMoveLeft || movement == kMoveRight) {
+ if (p2Diff.x == 0) {
+ error("Wrong value for horizontal movement");
+ }
reachedEnd = movement == kMoveLeft ? hero->x <= p2.x : hero->x >= p2.x;
hero->y += hero->x * p2Diff.y / p2Diff.x - prevHero.x * p2Diff.y / p2Diff.x;
} else {
+ if (p2Diff.y == 0) {
+ error("Wrong value for vertical movement");
+ }
reachedEnd = movement == kMoveUp ? hero->y <= p2.y : hero->y >= p2.y;
hero->x += hero->y * p2Diff.x / p2Diff.y - prevHero.y * p2Diff.x / p2Diff.y;
}
diff --git a/engines/draci/walking.h b/engines/draci/walking.h
index a43aeb272a..7e4a3184f5 100644
--- a/engines/draci/walking.h
+++ b/engines/draci/walking.h
@@ -103,7 +103,17 @@ struct GPL2Program;
class WalkingState {
public:
- explicit WalkingState(DraciEngine *vm) : _vm(vm) { stopWalking(); }
+ explicit WalkingState(DraciEngine *vm) : _vm(vm) {
+ _dir = kDirectionLast;
+ _startingDirection = kMoveUndefined;
+ _segment = 0;
+ _lastAnimPhase = 0;
+ _turningFinished = 0;
+ _callbackOffset = 0;
+
+ stopWalking();
+ }
+
~WalkingState() {}
void stopWalking();
diff --git a/engines/drascula/POTFILES b/engines/drascula/POTFILES
new file mode 100644
index 0000000000..ea79f9e066
--- /dev/null
+++ b/engines/drascula/POTFILES
@@ -0,0 +1,2 @@
+engines/drascula/detection.cpp
+engines/drascula/saveload.cpp
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..ee981c36da 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();
@@ -1645,10 +1645,10 @@ void DrasculaEngine::animation_9_6() {
int v_cd;
- animate("fin.bin", 14);
+ (void)animate("fin.bin", 14);
playMusic(13);
flags[5] = 1;
- animate("drf.bin", 16);
+ (void)animate("drf.bin", 16);
fadeToBlack(0);
clearRoom();
curX = -1;
@@ -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/configure.engine b/engines/drascula/configure.engine
new file mode 100644
index 0000000000..b9b76638fd
--- /dev/null
+++ b/engines/drascula/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine drascula "Drascula: The Vampire Strikes Back" yes
diff --git a/engines/drascula/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..b3749445ec 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -168,19 +168,19 @@ void DrasculaEngine::converse(int index) {
// delete stream;
if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) {
- strcpy(phrase3, _text[405]);
+ Common::strlcpy(phrase3, _text[405], 128);
strcpy(sound3, "405.als");
answer3 = 31;
}
if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[7] == 1) {
- strcpy(phrase3, _text[273]);
+ Common::strlcpy(phrase3, _text[273], 128);
strcpy(sound3, "273.als");
answer3 = 14;
}
if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[10] == 1) {
- strcpy(phrase3, _text[274]);
+ Common::strlcpy(phrase3, _text[274], 128);
strcpy(sound3, "274.als");
answer3 = 15;
}
@@ -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/detection.cpp b/engines/drascula/detection.cpp
index 8764b82a04..1917bc879d 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -68,33 +68,57 @@ static const PlainGameDescriptor drasculaGames[] = {
namespace Drascula {
static const DrasculaGameDescription gameDescriptions[] = {
+
+ //// Packed versions //////////////////////////////////////////////////////
+
{
- // Drascula English version
+ // Drascula English version (original packed files)
{
"drascula",
0,
- AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595),
+ {
+ {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ // HACK: List packet.001 twice to ensure this detector entry
+ // is ranked just as high as the others (which each have two
+ // detection files).
+ {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ {NULL, 0, NULL, 0}
+ },
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_NO_FLAGS,
+ GF_PACKED,
GUIO0()
},
},
{
- // Drascula English version (original packed files)
+ // Drascula French version (original packed files)
{
"drascula",
0,
{
{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
- // HACK: List packet.001 twice to ensure this detector entry
- // is ranked just as high as the others (which each have two
- // detection files).
+ {"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122},
+ {NULL, 0, NULL, 0}
+ },
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ GF_PACKED,
+ GUIO0()
+ },
+ },
+
+ {
+ // Drascula French version (ScummVM repacked files)
+ {
+ "drascula",
+ 0,
+ {
{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ {"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383},
{NULL, 0, NULL, 0}
},
- Common::EN_ANY,
+ Common::FR_FRA,
Common::kPlatformDOS,
GF_PACKED,
GUIO0()
@@ -119,16 +143,29 @@ static const DrasculaGameDescription gameDescriptions[] = {
},
{
- // Drascula French version (original packed files)
+ // Drascula Italian version (original packed version)
+ {
+ "drascula",
+ 0,
+ AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209),
+ Common::IT_ITA,
+ Common::kPlatformDOS,
+ GF_PACKED,
+ GUIO0()
+ },
+ },
+
+ {
+ // Drascula Italian version (ScummVM repacked files)
{
"drascula",
0,
{
{"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
- {"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122},
+ {"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623},
{NULL, 0, NULL, 0}
},
- Common::FR_FRA,
+ Common::IT_ITA,
Common::kPlatformDOS,
GF_PACKED,
GUIO0()
@@ -149,25 +186,31 @@ static const DrasculaGameDescription gameDescriptions[] = {
},
{
- // Drascula Spanish version
+ // Drascula Spanish version (ScummVM repacked files)
{
"drascula",
0,
- AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059),
+ {
+ {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
+ {"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838},
+ {NULL, 0, NULL, 0}
+ },
Common::ES_ESP,
Common::kPlatformDOS,
- ADGF_NO_FLAGS,
+ GF_PACKED,
GUIO0()
},
},
+ //// Unpacked versions ////////////////////////////////////////////////////
+
{
- // Drascula German version
+ // Drascula English version
{
"drascula",
0,
- AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610),
- Common::DE_DEU,
+ AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595),
+ Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
@@ -188,24 +231,25 @@ static const DrasculaGameDescription gameDescriptions[] = {
},
{
- // Drascula Italian version (original packed version)
+ // Drascula French version (updated - bug #3612236)
{
"drascula",
0,
- AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209),
- Common::IT_ITA,
+ AD_ENTRY1s("14.ald", "1f9fbded768bee061cc22bc5bdeab540", 611),
+ Common::FR_FRA,
Common::kPlatformDOS,
- GF_PACKED,
+ ADGF_NO_FLAGS,
GUIO0()
},
},
+
{
- // Drascula Italian version
+ // Drascula German version
{
"drascula",
0,
- AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098),
- Common::IT_ITA,
+ AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610),
+ Common::DE_DEU,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
@@ -213,52 +257,40 @@ static const DrasculaGameDescription gameDescriptions[] = {
},
{
- // Drascula Spanish version (ScummVM repacked files)
+ // Drascula Italian version
{
"drascula",
0,
- {
- {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
- {"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838},
- {NULL, 0, NULL, 0}
- },
- Common::ES_ESP,
+ AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098),
+ Common::IT_ITA,
Common::kPlatformDOS,
- GF_PACKED,
+ ADGF_NO_FLAGS,
GUIO0()
},
},
{
- // Drascula Italian version (ScummVM repacked files)
+ // Drascula Italian version (updated - bug #3612236)
{
"drascula",
0,
- {
- {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
- {"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623},
- {NULL, 0, NULL, 0}
- },
+ AD_ENTRY1s("14.ald", "ccaee939bb3b344c048f28f9205710d1", 2925),
Common::IT_ITA,
Common::kPlatformDOS,
- GF_PACKED,
+ ADGF_NO_FLAGS,
GUIO0()
},
},
{
- // Drascula French version (ScummVM repacked files)
+ // Drascula Spanish version
{
"drascula",
0,
- {
- {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563},
- {"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383},
- {NULL, 0, NULL, 0}
- },
- Common::FR_FRA,
+ AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059),
+ Common::ES_ESP,
Common::kPlatformDOS,
- GF_PACKED,
+ ADGF_NO_FLAGS,
GUIO0()
},
},
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 804881cf9a..163f0077fc 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -89,14 +89,107 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_talkSequences = 0;
_currentSaveSlot = 0;
+ bjX = 0;
+ bjY = 0;
+ trackBJ = 0;
+ framesWithoutAction = 0;
+ term_int = 0;
+ currentChapter = 0;
+ _loadedDifferentChapter = 0;
+ musicStopped = 0;
+ FrameSSN = 0;
+ globalSpeed = 0;
+ LastFrame = 0;
+ flag_tv = 0;
+ _charMapSize = 0;
+ _itemLocationsSize = 0;
+ _polXSize = 0;
+ _verbBarXSize = 0;
+ _x1dMenuSize = 0;
+ _frameXSize = 0;
+ _candleXSize = 0;
+ _pianistXSize = 0;
+ _drunkXSize = 0;
+ _roomPreUpdatesSize = 0;
+ _roomUpdatesSize = 0;
+ _roomActionsSize = 0;
+ _talkSequencesSize = 0;
+ _numLangs = 0;
+ feetHeight = 0;
+ floorX1 = 0;
+ floorY1 = 0;
+ floorX2 = 0;
+ floorY2 = 0;
+ lowerLimit = 0;
+ upperLimit = 0;
+ trackFinal = 0;
+ walkToObject = 0;
+ objExit = 0;
+ _startTime = 0;
+ hasAnswer = 0;
+ savedTime = 0;
+ breakOut = 0;
+ vonBraunX = 0;
+ trackVonBraun = 0;
+ vonBraunHasMoved = 0;
+ newHeight = 0;
+ newWidth = 0;
+ color_solo = 0;
+ igorX = 0;
+ igorY = 0;
+ trackIgor = 0;
+ drasculaX = 0;
+ drasculaY = 0;
+ trackDrascula = 0;
+ _roomNumber = 0;
+ numRoomObjs = 0;
+ takeObject = 0;
+ pickedObject = 0;
+ _subtitlesDisabled = 0;
+ _menuBar = 0;
+ _menuScreen = 0;
+ _hasName = 0;
+ curExcuseLook = 0;
+ curExcuseAction = 0;
+ frame_y = 0;
+ curX = 0;
+ curY = 0;
+ characterMoved = 0;
+ curDirection = 0;
+ trackProtagonist = 0;
+ _characterFrame = 0;
+ hare_se_ve = 0;
+ roomX = 0;
+ roomY = 0;
+ checkFlags = 0;
+ doBreak = 0;
+ stepX = 0;
+ stepY = 0;
+ curHeight = 0;
+ curWidth = 0;
+
_color = 0;
blinking = 0;
- mouseX = 0;
- mouseY = 0;
- leftMouseButton = 0;
- rightMouseButton = 0;
+ _mouseX = 0;
+ _mouseY = 0;
+ _leftMouseButton = 0;
+ _rightMouseButton = 0;
*textName = 0;
+ crosshairCursor = 0;
+ mouseCursor = 0;
+ bgSurface = 0;
+ backSurface = 0;
+ cursorSurface = 0;
+ drawSurface3 = 0;
+ drawSurface2 = 0;
+ tableSurface = 0;
+ extraSurface = 0;
+ screenSurface = 0;
+ frontSurface = 0;
+ previousMusic = 0;
+ roomMusic = 0;
+
_rnd = new Common::RandomSource("drascula");
_console = 0;
@@ -197,7 +290,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 +311,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 +324,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 +336,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 +358,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();
@@ -300,7 +390,7 @@ Common::Error DrasculaEngine::run() {
memset(iconName, 0, sizeof(iconName));
for (i = 0; i < 6; i++)
- strcpy(iconName[i + 1], _textverbs[i]);
+ Common::strlcpy(iconName[i + 1], _textverbs[i], 13);
assignPalette(defaultPalette);
@@ -330,7 +420,7 @@ void DrasculaEngine::endChapter() {
bool DrasculaEngine::runCurrentChapter() {
int n;
- rightMouseButton = 0;
+ _rightMouseButton = 0;
previousMusic = -1;
@@ -360,14 +450,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 +473,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemPhone);
trackProtagonist = 3;
objExit = 162;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(14);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -401,7 +491,7 @@ bool DrasculaEngine::runCurrentChapter() {
flags[1] = 1;
trackProtagonist = 1;
objExit = 99;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(20);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -415,7 +505,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemReefer2);
addObject(kItemOneCoin2);
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(21);
trackProtagonist = 0;
curX = 235;
@@ -437,7 +527,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(20);
trackProtagonist = 1;
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(45);
} else {
if (!loadGame(_currentSaveSlot)) {
@@ -450,7 +540,7 @@ bool DrasculaEngine::runCurrentChapter() {
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(58);
animation_1_6();
} else {
@@ -480,13 +570,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 +608,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 +639,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 +670,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 +734,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 +760,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 +769,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 +786,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 +808,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 +869,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..fe954279c3 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);
@@ -336,7 +336,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
// original starts printing 4 lines above textY
int y = CLIP<int>(textY - (4 * CHAR_HEIGHT), 0, 320);
- strcpy(msg, message);
+ Common::strlcpy(msg, message, 200);
// If the message fits on screen as-is, just print it here
if (textFitsCentered(msg, textX)) {
@@ -363,8 +363,8 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
while (curWord != NULL) {
// Check if the word and the current line fit on screen
if (tmpMessageLine[0] != '\0')
- strcat(tmpMessageLine, " ");
- strcat(tmpMessageLine, curWord);
+ Common::strlcat(tmpMessageLine, " ", 200);
+ Common::strlcat(tmpMessageLine, curWord, 200);
if (textFitsCentered(tmpMessageLine, textX)) {
// Line fits, so add the word to the current message line
strcpy(messageLine, tmpMessageLine);
@@ -374,8 +374,8 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
// If it goes off screen, print_abc will adjust it
x = CLIP<int>(textX - strlen(messageLine) * CHAR_WIDTH / 2, 60, 255);
print_abc(messageLine, x, y + curLine * CHAR_HEIGHT);
- strcpy(messageLine, curWord);
- strcpy(tmpMessageLine, curWord);
+ Common::strlcpy(messageLine, curWord, 200);
+ Common::strlcpy(tmpMessageLine, curWord, 200);
curLine++;
}
@@ -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..519e919433 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,70 @@ 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)
- strcpy(objName[2], _textmisc[0]);
- if (roomNumber == 26 && flags[18] == 1)
+ if (_roomNumber == 26 && flags[21] == 0) {
+ Common::strlcpy(objName[2], _textmisc[0], 20);
+ }
+ if (_roomNumber == 26 && flags[18] == 1)
visible[2] = 0;
- if (roomNumber == 26 && flags[12] == 1)
+ 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/POTFILES b/engines/dreamweb/POTFILES
new file mode 100644
index 0000000000..d05d239bb7
--- /dev/null
+++ b/engines/dreamweb/POTFILES
@@ -0,0 +1 @@
+engines/dreamweb/detection.cpp
diff --git a/engines/dreamweb/configure.engine b/engines/dreamweb/configure.engine
new file mode 100644
index 0000000000..27506e650f
--- /dev/null
+++ b/engines/dreamweb/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine dreamweb "Dreamweb" yes
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index c3ede46df2..7323dfc4a8 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -23,7 +23,6 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/events.h"
-#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/func.h"
#include "common/system.h"
@@ -226,6 +225,49 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_linePointer = 0;
_lineDirection = 0;
_lineLength = 0;
+
+ _subtitles = 0;
+ _foreignRelease = 0;
+ _wonGame = 0;
+ _hasSpeech = 0;
+ _roomsSample = 0;
+ _copyProtection = 0;
+
+ for (uint i = 0; i < 128; i++)
+ memset(&_setDat[i], 0, sizeof(SetObject));
+
+ for (uint i = 0; i < 80; i++)
+ memset(&_freeDat[i], 0, sizeof(DynObject));
+
+ for (uint i = 0; i < kNumExObjects; i++)
+ memset(&_exData[i], 0, sizeof(DynObject));
+
+ memset(&_vars, 0, sizeof(GameVars));
+
+ for (uint i = 0; i < 96; i++)
+ memset(&_backdropFlags[i], 0, sizeof(BackdropMapFlag));
+
+ for (uint i = 0; i < kNumReelRoutines+1; i++)
+ memset(&_reelRoutines[i], 0, sizeof(ReelRoutine));
+
+ _personData = 0;
+
+ for (uint i = 0; i < 16; i++)
+ memset(&_openInvList[i], 0, sizeof(ObjectRef));
+
+ for (uint i = 0; i < 30; i++)
+ memset(&_ryanInvList[i], 0, sizeof(ObjectRef));
+
+ for (uint i = 0; i < 11*10; i++)
+ memset(&_mapFlags[i], 0, sizeof(MapFlag));
+
+ for (uint i = 0; i < kNumChanges; i++)
+ memset(&_listOfChanges[i], 0, sizeof(Change));
+
+ _currentCharset = 0;
+
+ for (uint i = 0; i < 36; i++)
+ memset(&_pathData[i], 0, sizeof(RoomPaths));
}
DreamWebEngine::~DreamWebEngine() {
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index 5746568e4e..010f3883b0 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -144,8 +144,6 @@ public:
bool loadSpeech(const Common::String &filename);
- void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; }
-
Common::Language getLanguage() const;
uint8 modifyChar(uint8 c) const;
Common::String modifyFileName(const char *);
@@ -171,7 +169,6 @@ private:
uint _speed;
bool _turbo;
uint _oldMouseState;
- bool _enableSavingOrLoading;
protected:
GameVars _vars; // saved variables
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/engine.cpp b/engines/engine.cpp
index c84404cc68..52020c772e 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -183,7 +183,7 @@ void initCommonGFX(bool defaultTo1XScaler) {
g_system->setGraphicsMode(gfxMode.c_str());
// HACK: For OpenGL modes, we will still honor the graphics scale override
- if (defaultTo1XScaler && (gfxMode.equalsIgnoreCase("gl1") || gfxMode.equalsIgnoreCase("gl2") || gfxMode.equalsIgnoreCase("gl4")))
+ if (defaultTo1XScaler && (gfxMode.equalsIgnoreCase("opengl_linear") || gfxMode.equalsIgnoreCase("opengl_nearest")))
g_system->resetGraphicsScale();
}
}
diff --git a/engines/engines.mk b/engines/engines.mk
deleted file mode 100644
index 595b0ae3a2..0000000000
--- a/engines/engines.mk
+++ /dev/null
@@ -1,248 +0,0 @@
-ifdef ENABLE_SCUMM
-DEFINES += -DENABLE_SCUMM=$(ENABLE_SCUMM)
-MODULES += engines/scumm
-
-ifdef ENABLE_SCUMM_7_8
-DEFINES += -DENABLE_SCUMM_7_8
-endif
-
-ifdef ENABLE_HE
-DEFINES += -DENABLE_HE
-endif
-
-endif
-
-ifdef ENABLE_AGI
-DEFINES += -DENABLE_AGI=$(ENABLE_AGI)
-MODULES += engines/agi
-endif
-
-ifdef ENABLE_AGOS
-DEFINES += -DENABLE_AGOS=$(ENABLE_AGOS)
-MODULES += engines/agos
-
-ifdef ENABLE_AGOS2
-DEFINES += -DENABLE_AGOS2
-endif
-endif
-
-ifdef ENABLE_CGE
-DEFINES += -DENABLE_CGE=$(ENABLE_CGE)
-MODULES += engines/cge
-endif
-
-ifdef ENABLE_CINE
-DEFINES += -DENABLE_CINE=$(ENABLE_CINE)
-MODULES += engines/cine
-endif
-
-ifdef ENABLE_COMPOSER
-DEFINES += -DENABLE_COMPOSER=$(ENABLE_COMPOSER)
-MODULES += engines/composer
-endif
-
-ifdef ENABLE_CRUISE
-DEFINES += -DENABLE_CRUISE=$(ENABLE_CRUISE)
-MODULES += engines/cruise
-endif
-
-ifdef ENABLE_DRACI
-DEFINES += -DENABLE_DRACI=$(ENABLE_DRACI)
-MODULES += engines/draci
-endif
-
-ifdef ENABLE_DRASCULA
-DEFINES += -DENABLE_DRASCULA=$(ENABLE_DRASCULA)
-MODULES += engines/drascula
-endif
-
-ifdef ENABLE_DREAMWEB
-DEFINES += -DENABLE_DREAMWEB=$(ENABLE_DREAMWEB)
-MODULES += engines/dreamweb
-endif
-
-ifdef ENABLE_GOB
-DEFINES += -DENABLE_GOB=$(ENABLE_GOB)
-MODULES += engines/gob
-endif
-
-ifdef ENABLE_GROOVIE
-DEFINES += -DENABLE_GROOVIE=$(ENABLE_GROOVIE)
-MODULES += engines/groovie
-
-ifdef ENABLE_GROOVIE2
-DEFINES += -DENABLE_GROOVIE2
-endif
-endif
-
-ifdef ENABLE_HOPKINS
-DEFINES += -DENABLE_HOPKINS=$(ENABLE_HOPKINS)
-MODULES += engines/hopkins
-endif
-
-ifdef ENABLE_HUGO
-DEFINES += -DENABLE_HUGO=$(ENABLE_HUGO)
-MODULES += engines/hugo
-endif
-
-ifdef ENABLE_KYRA
-DEFINES += -DENABLE_KYRA=$(ENABLE_KYRA)
-MODULES += engines/kyra
-
-ifdef ENABLE_LOL
-DEFINES += -DENABLE_LOL
-endif
-
-ifdef ENABLE_EOB
-DEFINES += -DENABLE_EOB
-endif
-endif
-
-ifdef ENABLE_LASTEXPRESS
-DEFINES += -DENABLE_LASTEXPRESS=$(ENABLE_LASTEXPRESS)
-MODULES += engines/lastexpress
-endif
-
-ifdef ENABLE_LURE
-DEFINES += -DENABLE_LURE=$(ENABLE_LURE)
-MODULES += engines/lure
-endif
-
-ifdef ENABLE_MADE
-DEFINES += -DENABLE_MADE=$(ENABLE_MADE)
-MODULES += engines/made
-endif
-
-ifdef ENABLE_MOHAWK
-DEFINES += -DENABLE_MOHAWK=$(ENABLE_MOHAWK)
-MODULES += engines/mohawk
-
-ifdef ENABLE_CSTIME
-DEFINES += -DENABLE_CSTIME
-endif
-
-ifdef ENABLE_MYST
-DEFINES += -DENABLE_MYST
-endif
-
-ifdef ENABLE_RIVEN
-DEFINES += -DENABLE_RIVEN
-endif
-endif
-
-ifdef ENABLE_NEVERHOOD
-DEFINES += -DENABLE_NEVERHOOD=$(ENABLE_NEVERHOOD)
-MODULES += engines/neverhood
-endif
-
-ifdef ENABLE_PARALLACTION
-DEFINES += -DENABLE_PARALLACTION=$(ENABLE_PARALLACTION)
-MODULES += engines/parallaction
-endif
-
-ifdef ENABLE_PEGASUS
-DEFINES += -DENABLE_PEGASUS=$(ENABLE_PEGASUS)
-MODULES += engines/pegasus
-endif
-
-ifdef ENABLE_QUEEN
-DEFINES += -DENABLE_QUEEN=$(ENABLE_QUEEN)
-MODULES += engines/queen
-endif
-
-ifdef ENABLE_SAGA
-DEFINES += -DENABLE_SAGA=$(ENABLE_SAGA)
-MODULES += engines/saga
-
-ifdef ENABLE_IHNM
-DEFINES += -DENABLE_IHNM
-endif
-
-ifdef ENABLE_SAGA2
-DEFINES += -DENABLE_SAGA2
-endif
-endif
-
-ifdef ENABLE_SCI
-DEFINES += -DENABLE_SCI=$(ENABLE_SCI)
-MODULES += engines/sci
-
-ifdef ENABLE_SCI32
-DEFINES += -DENABLE_SCI32
-endif
-endif
-
-ifdef ENABLE_SKY
-DEFINES += -DENABLE_SKY=$(ENABLE_SKY)
-MODULES += engines/sky
-endif
-
-ifdef ENABLE_SWORD1
-DEFINES += -DENABLE_SWORD1=$(ENABLE_SWORD1)
-MODULES += engines/sword1
-endif
-
-ifdef ENABLE_SWORD2
-DEFINES += -DENABLE_SWORD2=$(ENABLE_SWORD2)
-MODULES += engines/sword2
-endif
-
-ifdef ENABLE_SWORD25
-DEFINES += -DENABLE_SWORD25=$(ENABLE_SWORD25)
-MODULES += engines/sword25
-endif
-
-ifdef ENABLE_TESTBED
-DEFINES += -DENABLE_TESTBED=$(ENABLE_TESTBED)
-MODULES += engines/testbed
-endif
-
-ifdef ENABLE_TEENAGENT
-DEFINES += -DENABLE_TEENAGENT=$(ENABLE_TEENAGENT)
-MODULES += engines/teenagent
-endif
-
-ifdef ENABLE_TINSEL
-DEFINES += -DENABLE_TINSEL=$(ENABLE_TINSEL)
-MODULES += engines/tinsel
-endif
-
-ifdef ENABLE_TOLTECS
-DEFINES += -DENABLE_TOLTECS=$(ENABLE_TOLTECS)
-MODULES += engines/toltecs
-endif
-
-ifdef ENABLE_TONY
-DEFINES += -DENABLE_TONY=$(ENABLE_TONY)
-MODULES += engines/tony
-endif
-
-ifdef ENABLE_TOON
-DEFINES += -DENABLE_TOON=$(ENABLE_TOON)
-MODULES += engines/toon
-endif
-
-ifdef ENABLE_TOUCHE
-DEFINES += -DENABLE_TOUCHE=$(ENABLE_TOUCHE)
-MODULES += engines/touche
-endif
-
-ifdef ENABLE_TSAGE
-DEFINES += -DENABLE_TSAGE=$(ENABLE_TSAGE)
-MODULES += engines/tsage
-endif
-
-ifdef ENABLE_TUCKER
-DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
-MODULES += engines/tucker
-endif
-
-ifdef ENABLE_WINTERMUTE
-DEFINES += -DENABLE_WINTERMUTE=$(ENABLE_WINTERMUTE)
-MODULES += engines/wintermute
-endif
-
-ifdef ENABLE_VOYEUR
-DEFINES += -DENABLE_VOYEUR=$(ENABLE_VOYEUR)
-MODULES += engines/voyeur
-endif
diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
new file mode 100644
index 0000000000..c27f1082f5
--- /dev/null
+++ b/engines/fullpipe/behavior.cpp
@@ -0,0 +1,334 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+
+namespace Fullpipe {
+
+BehaviorManager::BehaviorManager() {
+ _scene = 0;
+ _isActive = 1;
+}
+
+BehaviorManager::~BehaviorManager() {
+ clear();
+}
+
+void BehaviorManager::clear() {
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ for (int j = 0; j < _behaviors[i]->_itemsCount; j++)
+ delete _behaviors[i]->_bheItems[j];
+
+ delete _behaviors[i];
+ }
+ _behaviors.clear();
+}
+
+void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
+ clear();
+ _scene = sc;
+
+ BehaviorInfo *behinfo;
+
+ GameVar *behvar = var->getSubVarByName("BEHAVIOR");
+ if (!behvar)
+ return;
+
+ for (GameVar *subvar = behvar->_subVars; subvar; subvar = subvar->_nextVarObj) {
+ if (!strcmp(subvar->_varName, "AMBIENT")) {
+ behinfo = new BehaviorInfo;
+ behinfo->initAmbientBehavior(subvar, sc);
+
+ _behaviors.push_back(behinfo);
+ } else {
+ StaticANIObject *ani = sc->getStaticANIObject1ByName(subvar->_varName, -1);
+ if (ani)
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++)
+ if (((StaticANIObject *)sc->_staticANIObjectList1[i])->_id == ani->_id) {
+ behinfo = new BehaviorInfo;
+ behinfo->initObjectBehavior(subvar, sc, ani);
+ behinfo->_ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+
+ _behaviors.push_back(behinfo);
+ }
+ }
+ }
+}
+
+void BehaviorManager::updateBehaviors() {
+ if (!_isActive)
+ return;
+
+ debug(0, "BehaviorManager::updateBehaviors()");
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ BehaviorInfo *beh = _behaviors[i];
+
+ if (!beh->_ani) {
+ beh->_counter++;
+ if (beh->_counter >= beh->_counterMax)
+ updateBehavior(beh, beh->_bheItems[0]);
+
+ continue;
+ }
+
+ if (beh->_ani->_movement || !(beh->_ani->_flags & 4) || (beh->_ani->_flags & 2)) {
+ beh->_staticsId = 0;
+ continue;
+ }
+
+ if (beh->_ani->_statics->_staticsId == beh->_staticsId) {
+ beh->_counter++;
+ if (beh->_counter >= beh->_counterMax) {
+ if (beh->_subIndex >= 0 && !(beh->_flags & 1) && beh->_ani->_messageQueueId <= 0)
+ updateStaticAniBehavior(beh->_ani, beh->_counter, beh->_bheItems[beh->_subIndex]);
+ }
+ } else {
+ beh->_staticsId = beh->_ani->_statics->_staticsId;
+ beh->_counter = 0;
+ beh->_subIndex = -1;
+
+ for (int j = 0; j < beh->_itemsCount; j++)
+ if (beh->_bheItems[j]->_staticsId == beh->_staticsId) {
+ beh->_subIndex = j;
+ break;
+ }
+
+ }
+ }
+}
+
+void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry) {
+ debug(0, "BehaviorManager::updateBehavior() %d", entry->_itemsCount);
+ for (int i = 0; i < entry->_itemsCount; i++) {
+ BehaviorEntryInfo *bhi = entry->_items[i];
+ if (!(bhi->_flags & 1)) {
+ if (bhi->_flags & 2) {
+ MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+
+ mq->sendNextCommand();
+
+ bhi->_flags &= 0xFFFFFFFD;
+ } else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fullpipe->_rnd->getRandomNumber(32767) <= entry->_items[i]->_percent) {
+ MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+
+ mq->sendNextCommand();
+
+ behaviorInfo->_counter = 0;
+ }
+ }
+ }
+}
+
+void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *bhe) {
+ debug(0, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName));
+
+ MessageQueue *mq = 0;
+
+ if (bhe->_flags & 1) {
+ uint rnd = g_fullpipe->_rnd->getRandomNumber(32767);
+ uint runPercent = 0;
+ for (int i = 0; i < bhe->_itemsCount; i++) {
+ if (!(bhe->_items[i]->_flags & 1) && bhe->_items[i]->_percent) {
+ if ((rnd >= runPercent && rnd <= runPercent + bhe->_items[i]->_percent) || i == bhe->_itemsCount - 1) {
+ mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1);
+ break;
+ }
+ runPercent += bhe->_items[i]->_percent;
+ }
+ }
+ } else {
+ for (int i = 0; i < bhe->_itemsCount; i++) {
+ if (!(bhe->_items[i]->_flags & 1) && delay >= bhe->_items[i]->_delay) {
+ if (bhe->_items[i]->_percent) {
+ if (g_fullpipe->_rnd->getRandomNumber(32767) <= bhe->_items[i]->_percent) {
+ mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (mq) {
+ mq->replaceKeyCode(-1, ani->_okeyCode);
+ mq->chain(ani);
+ }
+}
+
+bool BehaviorManager::setBehaviorEnabled(StaticANIObject *obj, int aniId, int quId, int flag) {
+ warning("STUB: BehaviorManager::setBehaviorEnabled()");
+
+ return true;
+}
+
+void BehaviorManager::setFlagByStaticAniObject(StaticANIObject *ani, int flag) {
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ BehaviorInfo *beh = _behaviors[i];
+
+ if (ani == beh->_ani) {
+ if (flag)
+ beh->_flags &= 0xfe;
+ else
+ beh->_flags |= 1;
+ }
+ }
+}
+
+void BehaviorInfo::clear() {
+ _ani = 0;
+ _staticsId = 0;
+ _counter = 0;
+ _counterMax = 0;
+ _flags = 0;
+ _subIndex = 0;
+ _itemsCount = 0;
+
+ _bheItems.clear();
+}
+
+void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) {
+ debug(0, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName));
+
+ clear();
+ _itemsCount = 1;
+ _counterMax = -1;
+
+ BehaviorEntry *bi = new BehaviorEntry();
+
+ _bheItems.push_back(bi);
+
+ bi->_itemsCount = var->getSubVarsCount();
+
+ bi->_items = (BehaviorEntryInfo**)calloc(bi->_itemsCount, sizeof(BehaviorEntryInfo *));
+
+ for (int i = 0; i < bi->_itemsCount; i++) {
+ int delay;
+ bi->_items[i] = new BehaviorEntryInfo(var->getSubVarByIndex(i), sc, &delay);
+
+ if (bi->_items[i]->_delay <_counterMax)
+ _counterMax = bi->_items[i]->_delay;
+ }
+}
+
+void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *ani) {
+ debug(0, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName));
+
+ clear();
+
+ _itemsCount = var->getSubVarsCount();
+ _counterMax = -1;
+
+ while (var->_varType == 2) {
+ if (strcmp(var->_value.stringValue, "ROOT"))
+ break;
+
+ GameVar *v1 = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("BEHAVIOR")->getSubVarByName(ani->getName());
+ if (v1 == var)
+ return;
+
+ sc = g_fullpipe->accessScene(ani->_sceneId);
+ clear();
+ var = v1;
+ _itemsCount = var->getSubVarsCount();
+ _counterMax = -1;
+ }
+
+ for (int i = 0; i < _itemsCount; i++) {
+ int maxDelay = 0;
+
+ _bheItems.push_back(new BehaviorEntry(var->getSubVarByIndex(i), sc, ani, &maxDelay));
+
+ if (maxDelay < _counterMax)
+ _counterMax = maxDelay;
+ }
+}
+
+BehaviorEntry::BehaviorEntry() {
+ _staticsId = 0;
+ _itemsCount = 0;
+ _flags = 0;
+ _items = 0;
+}
+
+BehaviorEntry::BehaviorEntry(GameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay) {
+ _staticsId = 0;
+ _itemsCount = 0;
+
+ *minDelay = 100000000;
+
+ int totalPercent = 0;
+ _flags = 0;
+ _items = 0;
+
+ Statics *st = ani->getStaticsByName(var->_varName);
+ if (st)
+ _staticsId = st->_staticsId;
+
+ _itemsCount = var->getSubVarsCount();
+ if (_itemsCount) {
+ _items = (BehaviorEntryInfo**)calloc(_itemsCount, sizeof(BehaviorEntryInfo *));
+
+ for (int i = 0; i < _itemsCount; i++) {
+ GameVar *subvar = var->getSubVarByIndex(i);
+ int delay = 0;
+
+ _items[i] = new BehaviorEntryInfo(subvar, sc, &delay);
+ totalPercent += delay;
+
+ if (_items[i]->_delay < *minDelay)
+ *minDelay = _items[i]->_delay;
+ }
+
+ if (!*minDelay && totalPercent == 1000)
+ _flags |= 1;
+ }
+}
+
+BehaviorEntryInfo::BehaviorEntryInfo(GameVar *subvar, Scene *sc, int *delay) {
+ _messageQueue = 0;
+ _delay = 0;
+ _percent = 0;
+ _flags = 0;
+ _messageQueue = sc->getMessageQueueByName(subvar->_varName);
+
+ GameVar *vart = subvar->getSubVarByName("dwDelay");
+ if (vart)
+ _delay = vart->_value.intValue;
+
+ *delay = 0;
+ vart = subvar->getSubVarByName("dwPercent");
+ if (vart) {
+ _percent = 0x7FFF * vart->_value.intValue / 1000;
+ *delay = vart->_value.intValue;
+ }
+
+ vart = subvar->getSubVarByName("dwFlags");
+ if (vart && vart->_varType == 2 && strstr(vart->_value.stringValue, "QDESC_AUTOSTART"))
+ _flags |= 2;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/behavior.h b/engines/fullpipe/behavior.h
new file mode 100644
index 0000000000..1ac0b5bbfe
--- /dev/null
+++ b/engines/fullpipe/behavior.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_BEHAVIOR_H
+#define FULLPIPE_BEHAVIOR_H
+
+namespace Fullpipe {
+
+struct BehaviorEntryInfo {
+ MessageQueue *_messageQueue;
+ int _delay;
+ uint32 _percent;
+ int _flags;
+
+ BehaviorEntryInfo(GameVar *subvar, Scene *sc, int *delay);
+};
+
+struct BehaviorEntry {
+ int _staticsId;
+ int _itemsCount;
+ int _flags;
+ BehaviorEntryInfo **_items;
+
+ BehaviorEntry();
+ BehaviorEntry(GameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay);
+};
+
+struct BehaviorInfo {
+ StaticANIObject *_ani;
+ int _staticsId;
+ int _counter;
+ int _counterMax;
+ int _flags;
+ int _subIndex;
+ int _itemsCount;
+ Common::Array<BehaviorEntry *> _bheItems;
+
+ BehaviorInfo() { clear(); }
+
+ void clear();
+ void initAmbientBehavior(GameVar *var, Scene *sc);
+ void initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *ani);
+};
+
+class BehaviorManager : public CObject {
+ Common::Array<BehaviorInfo *> _behaviors;
+ Scene *_scene;
+ bool _isActive;
+
+ public:
+ BehaviorManager();
+ ~BehaviorManager();
+
+ void clear();
+
+ void initBehavior(Scene *scene, GameVar *var);
+
+ void updateBehaviors();
+ void updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry);
+ void updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *beh);
+
+ bool setBehaviorEnabled(StaticANIObject *obj, int aniId, int quId, int flag);
+
+ void setFlagByStaticAniObject(StaticANIObject *ani, int flag);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_BEHAVIOR_H */
diff --git a/engines/fullpipe/configure.engine b/engines/fullpipe/configure.engine
new file mode 100644
index 0000000000..fce5951e26
--- /dev/null
+++ b/engines/fullpipe/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine fullpipe "Full Pipe" no
diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h
new file mode 100644
index 0000000000..e1ec51a947
--- /dev/null
+++ b/engines/fullpipe/constants.h
@@ -0,0 +1,296 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_CONSTANTS_H
+#define FULLPIPE_CONSTANTS_H
+
+namespace Fullpipe {
+
+#define ANI_BIGBALL 4923
+#define ANI_BOOT_1 4231
+#define ANI_BUTTON 598
+#define ANI_CLOCK 588
+#define ANI_DOMINO_3 2732
+#define ANI_DADAYASHIK 306
+#define ANI_EGGEATER 334
+#define ANI_HAND 601
+#define ANI_IN1MAN 5110
+#define ANI_INV_COIN 875
+#define ANI_INV_EGGAPL 1564
+#define ANI_INV_EGGBOOT 1570
+#define ANI_INV_EGGCOIN 1567
+#define ANI_INV_EGGDOM 1561
+#define ANI_INV_EGGGLS 1573
+#define ANI_INV_MAP 5321
+#define ANI_KOZAWKA 495
+#define ANI_LIFTBUTTON 2751
+#define ANI_MAMASHA_4 660
+#define ANI_MAN 322
+#define ANI_PLANK 501
+#define ANI_SC2_BOX 1020
+#define ANI_SC4_BOOT 1035
+#define ANI_SC4_COIN 690
+#define ANI_SPEAKER_4 3275
+#define ANI_SPRING 542
+#define MSG_CLICKBOTTLE 569
+#define MSG_CLICKBUTTON 609
+#define MSG_CLICKPLANK 549
+#define MSG_CMN_WINARCADE 4778
+#define MSG_DISABLESAVES 5201
+#define MSG_ENABLESAVES 5202
+#define MSG_HMRKICK_METAL 4764
+#define MSG_HMRKICK_STUCCO 4765
+#define MSG_INTR_ENDINTRO 5139
+#define MSG_INTR_GETUPMAN 5135
+#define MSG_INTR_SWITCHTO1 5145
+#define MSG_INTR_SWITCHTO2 5134
+#define MSG_KOZAWRESTART 546
+#define MSG_LIFT_CLICKBUTTON 2780
+#define MSG_LIFT_CLOSEDOOR 5194
+#define MSG_LIFT_EXITLIFT 5187
+#define MSG_LIFT_GO 1065
+#define MSG_LIFT_STARTEXITQUEUE 5186
+#define MSG_LOWERPLANK 540
+#define MSG_MANSHADOWSOFF 5196
+#define MSG_MANSHADOWSON 5197
+#define MSG_RAISEPLANK 547
+#define MSG_RESTARTGAME 4767
+#define MSG_SC1_SHOWOSK 1019
+#define MSG_SC1_SHOWOSK2 468
+#define MSG_SC1_UTRUBACLICK 1100
+#define MSG_SC2_HIDELADDER 1023
+#define MSG_SC2_LADDERCLICK 1101
+#define MSG_SC2_PUTMANUP 1026
+#define MSG_SC2_SHOWLADDER 1027
+#define MSG_SC3_HIDEDOMINO 3177
+#define MSG_SC3_ONTAKECOIN 5338
+#define MSG_SC3_RELEASEEGG 2681
+#define MSG_SC3_TAKEEGG 1583
+#define MSG_SC3_TESTFAT 1582
+#define MSG_SC3_UTRUBACLICK 1103
+#define MSG_SC4_COINOUT 2895
+#define MSG_SC4_COINPUT 1032
+#define MSG_SC4_CLICKLADDER 1439
+#define MSG_SC4_DROPBOTTLE 2896
+#define MSG_SC4_HANDOVER 2960
+#define MSG_SC4_HIDEBOOT 4563
+#define MSG_SC4_KOZAWFALL 2858
+#define MSG_SC4_MANFROMBOTTLE 2854
+#define MSG_SC4_MANTOBOTTLE 2852
+#define PIC_SC4_LADDER 1438
+#define MSG_GOTOLADDER 618
+#define MSG_SHAKEBOTTLE 584
+#define MSG_SHOOTKOZAW 557
+#define MSG_SHOWCOIN 1033
+#define MSG_STARTHAND 612
+#define MSG_TAKEBOTTLE 614
+#define MSG_TAKEKOZAW 611
+#define MSG_TESTPLANK 538
+#define MSG_UPDATEBOTTLE 613
+#define MV_EGTR_FATASK 5332
+#define MV_IN1MAN_SLEEP 5111
+#define MV_KZW_JUMP 558
+#define MV_KZW_JUMPROTATE 561
+#define MV_BDG_OPEN 1379
+#define MV_BTN_CLICK 599
+#define MV_CLK_GO 589
+#define MV_HND_POINT 602
+#define MV_MAN_GOD 481
+#define MV_MAN_GOLADDER 451
+#define MV_MAN_GOLADDER2 2844
+#define MV_MAN_GOU 460
+#define MV_MAN_LOOKUP 4773
+#define MV_MAN_STARTLADDER 452
+#define MV_MAN_STARTLADDER2 2842
+#define MV_MAN_STOPLADDER 454
+#define MV_MAN_STOPLADDER2 2845
+#define MV_MAN_TOLADDER 448
+#define MV_MAN_TOLADDER2 2841
+#define MV_MAN_TURN_LU 486
+#define MV_PNK_WEIGHTLEFT 541
+#define MV_PNK_WEIGHTRIGHT 502
+#define MV_SC4_COIN_default 1029
+#define MV_SPK4_PLAY 3276
+#define PIC_CMN_EVAL 3468
+#define PIC_CSR_DEFAULT 4891
+#define PIC_CSR_DEFAULT_INV 4892
+#define PIC_CSR_ITN 4893
+#define PIC_CSR_ITN_INV 4894
+#define PIC_CSR_GOFAR_L 4895
+#define PIC_CSR_GOFAR_R 4896
+#define PIC_CSR_ARCADE1 4901
+#define PIC_CSR_ARCADE2 4902
+#define PIC_CSR_ARCADE2_D 4903
+#define PIC_CSR_ARCADE3 4904
+#define PIC_CSR_ARCADE4 4905
+#define PIC_CSR_ARCADE5 4906
+#define PIC_CSR_ARCADE6 4907
+#define PIC_CSR_ARCADE6_D 4908
+#define PIC_CSR_ARCADE7 4909
+#define PIC_CSR_ARCADE7_D 4910
+#define PIC_CSR_ARCADE8 4911
+#define PIC_CSR_DEFAULT 4891
+#define PIC_CSR_DEFAULT_INV 4892
+#define PIC_CSR_GOD 4900
+#define PIC_CSR_GOFAR_L 4895
+#define PIC_CSR_GOFAR_R 4896
+#define PIC_CSR_GOL 4897
+#define PIC_CSR_GOR 4898
+#define PIC_CSR_GOU 4899
+#define PIC_CSR_HELPERBGR 5331
+#define PIC_CSR_ITN 4893
+#define PIC_CSR_ITN_GREEN 5330
+#define PIC_CSR_ITN_INV 4894
+#define PIC_CSR_ITN_RED 5329
+#define PIC_CSR_LIFT 5176
+#define PIC_CSR_MAP 5339
+#define PIC_IN1_GAMETITLE 5169
+#define PIC_IN1_PIPETITLE 5167
+#define PIC_INV_MENU 991
+#define PIC_MAP_A13 5275
+#define PIC_MAP_S01 5223
+#define PIC_SC1_KUCHKA 1321
+#define PIC_SC1_LADDER 1091
+#define PIC_SC1_OSK 1018
+#define PIC_SC1_OSK2 2932
+#define PIC_SC2_DTRUBA 841
+#define PIC_SC2_LADDER 412
+#define PIC_SC3_DOMIN 5182
+#define PIC_SC3_LADDER 1102
+#define PIC_SC4_BOTTLE 568
+#define PIC_SC4_BOTTLE2 2936
+#define PIC_SC4_DOWNTRUBA 619
+#define PIC_SC4_LADDER 1438
+#define PIC_SC4_LRTRUBA 616
+#define PIC_SC4_MASK 585
+#define PIC_SC4_PLANK 5183
+#define PIC_SCD_SEL 734
+#define QU_EGTR_MD2_SHOW 4698
+#define QU_EGTR_MD1_SHOW 4697
+#define QU_EGTR_SLIMSHOW 4883
+#define QU_IN2_DO 5144
+#define QU_INTR_FINISH 5138
+#define QU_INTR_GETUPMAN 5136
+#define QU_INTR_STARTINTRO 5133
+#define QU_KOZAW_WALK 505
+#define QU_PNK_CLICK 550
+#define QU_SC3_ENTERLIFT 2779
+#define QU_SC3_EXITLIFT 2808
+#define QU_SC4_MANFROMBOTTLE 2851
+#define SC_1 301
+#define SC_10 653
+#define SC_11 654
+#define SC_12 655
+#define SC_13 1137
+#define SC_14 1138
+#define SC_15 1139
+#define SC_16 1140
+#define SC_17 1141
+#define SC_18 1142
+#define SC_19 1143
+#define SC_2 302
+#define SC_20 1144
+#define SC_21 1546
+#define SC_22 1547
+#define SC_23 1548
+#define SC_24 1549
+#define SC_25 1550
+#define SC_26 1551
+#define SC_27 1552
+#define SC_28 2062
+#define SC_29 2063
+#define SC_3 303
+#define SC_30 2064
+#define SC_31 2065
+#define SC_32 2066
+#define SC_33 2067
+#define SC_34 2068
+#define SC_35 2069
+#define SC_36 2070
+#define SC_37 2071
+#define SC_38 2072
+#define SC_4 304
+#define SC_5 305
+#define SC_6 649
+#define SC_7 650
+#define SC_8 651
+#define SC_9 652
+#define SC_COMMON 321
+#define SC_DBGMENU 726
+#define SC_FINAL1 4999
+#define SC_FINAL2 5000
+#define SC_FINAL3 5001
+#define SC_FINAL4 2460
+#define SC_INTRO1 3896
+#define SC_INTRO2 3907
+#define SC_INV 858
+#define SC_LDR 635
+#define SC_MAINMENU 4620
+#define SC_MAP 5222
+#define SC_TEST 903
+#define SC_TITLES 5166
+#define SND_4_010 3125
+#define SND_4_012 3127
+#define SND_4_033 4990
+#define SND_CMN_031 3516
+#define SND_CMN_070 5199
+#define SND_INTR_019 5220
+#define ST_CLK_CLOSED 590
+#define ST_DYAS_LIES 318
+#define ST_EGTR_MID1 2863
+#define ST_EGTR_MID2 2869
+#define ST_EGTR_SLIM 336
+#define ST_HND_EMPTY 603
+#define ST_IN1MAN_SLEEP 5112
+#define ST_KZW_EMPTY 498
+#define ST_LBN_0N 2832
+#define ST_LBN_0P 2833
+#define ST_LBN_1N 2753
+#define ST_LBN_1P 2754
+#define ST_LBN_2N 2756
+#define ST_LBN_2P 2757
+#define ST_LBN_3N 2759
+#define ST_LBN_3P 2760
+#define ST_LBN_4N 2762
+#define ST_LBN_4P 2763
+#define ST_LBN_5N 2765
+#define ST_LBN_5P 2766
+#define ST_LBN_6N 2768
+#define ST_LBN_6P 2769
+#define ST_LBN_7N 2771
+#define ST_LBN_7P 2772
+#define ST_LBN_8N 2774
+#define ST_LBN_8P 2775
+#define ST_LBN_9N 2777
+#define ST_LBN_9P 2778
+#define ST_MAN_EMPTY 476
+#define ST_MAN_RIGHT 325
+#define ST_MAN_SIT 1164
+#define TrubaDown 697
+#define TrubaLeft 474
+#define TrubaRight 696
+#define TrubaUp 680
+#define rMV_MAN_LOOKUP 4775
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_CONSTANTS_H */
diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
new file mode 100644
index 0000000000..8c4a422333
--- /dev/null
+++ b/engines/fullpipe/detection.cpp
@@ -0,0 +1,112 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "engines/advancedDetector.h"
+#include "common/file.h"
+
+#include "fullpipe/fullpipe.h"
+
+
+namespace Fullpipe {
+
+const char *FullpipeEngine::getGameId() const {
+ return _gameDescription->gameid;
+}
+
+}
+
+static const PlainGameDescriptor fullpipeGames[] = {
+ {"fullpipe", "Full Pipe"},
+ {0, 0}
+};
+
+namespace Fullpipe {
+
+static const ADGameDescription gameDescriptions[] = {
+
+ // Fullpipe Russian version
+ {
+ "fullpipe",
+ 0,
+ AD_ENTRY1s("0654.sc2", "099f54f86d33ad2395f3b854b7e05058", 2272),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ // Fullpipe German version
+ {
+ "fullpipe",
+ 0,
+ AD_ENTRY1s("0654.sc2", "d8743351fc53d205f42d91f6d791e51b", 2272),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+} // End of namespace Fullpipe
+
+class FullpipeMetaEngine : public AdvancedMetaEngine {
+public:
+ FullpipeMetaEngine() : AdvancedMetaEngine(Fullpipe::gameDescriptions, sizeof(ADGameDescription), fullpipeGames) {
+ _singleid = "fullpipe";
+ }
+
+ virtual const char *getName() const {
+ return "Fullpipe Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Fullpipe Engine (C) Pipe Studio";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+};
+
+bool FullpipeMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return false;
+}
+
+bool Fullpipe::FullpipeEngine::hasFeature(EngineFeature f) const {
+ return false;
+}
+
+bool FullpipeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new Fullpipe::FullpipeEngine(syst, desc);
+ }
+ return desc != 0;
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(FULLPIPE)
+ REGISTER_PLUGIN_DYNAMIC(FULLPIPE, PLUGIN_TYPE_ENGINE, FullpipeMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(FULLPIPE, PLUGIN_TYPE_ENGINE, FullpipeMetaEngine);
+#endif
diff --git a/engines/fullpipe/floaters.cpp b/engines/fullpipe/floaters.cpp
new file mode 100644
index 0000000000..384bfa2150
--- /dev/null
+++ b/engines/fullpipe/floaters.cpp
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void Floaters::init(GameVar *var) {
+ warning("STUB: Floaters::init()");
+}
+
+void Floaters::genFlies(Scene *sc, int x, int y, int a5, int a6) {
+ warning("STUB: Floaters::genFlies()");
+}
+
+void Floaters::update() {
+ warning("STUB: Floaters::update()");
+}
+
+void Floaters::stopAll() {
+ warning("STUB: Floaters::stopAll()");
+}
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/floaters.h b/engines/fullpipe/floaters.h
new file mode 100644
index 0000000000..a4d64dd79d
--- /dev/null
+++ b/engines/fullpipe/floaters.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_FLOATERS_H
+#define FULLPIPE_FLOATERS_H
+
+namespace Fullpipe {
+
+class StaticANIObject;
+class Scene;
+
+struct FloaterArray1 {
+ int val1;
+ int val2;
+};
+
+struct FloaterArray2 {
+ StaticANIObject *ani;
+ int val2;
+ int val3;
+ int val4;
+ int val5;
+ int val6;
+ int val7;
+ int val8;
+ double val9;
+ double val11;
+ int val13;
+ int countdown;
+ int val15;
+ int fflags;
+};
+
+class Floaters {
+public:
+ //HRGN hRgn;
+ Common::Array<FloaterArray1 *> _array1;
+ Common::Array<FloaterArray2 *> _array2;
+
+ void init(GameVar *var);
+ void genFlies(Scene *sc, int x, int y, int a5, int a6);
+ void update();
+ void stopAll();
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_FLOATERS_H */
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
new file mode 100644
index 0000000000..7dedaf3109
--- /dev/null
+++ b/engines/fullpipe/fullpipe.cpp
@@ -0,0 +1,451 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * 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 "common/archive.h"
+#include "common/config-manager.h"
+
+#include "engines/util.h"
+
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/input.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+FullpipeEngine *g_fullpipe = 0;
+Vars *g_vars = 0;
+
+FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+ // Setup mixer
+ if (!_mixer->isReady()) {
+ warning("Sound initialization failed.");
+ }
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+ _rnd = new Common::RandomSource("fullpipe");
+
+ _gameProjectVersion = 0;
+ _pictureScale = 8;
+ _scrollSpeed = 0;
+ _currSoundListCount = 0;
+ _globalPalette = 0;
+
+ _updateTicks = 0;
+ _lastInputTicks = 0;
+ _lastButtonUpTicks = 0;
+
+ _currArchive = 0;
+
+ _soundEnabled = true;
+ _flgSoundList = true;
+
+ _sfxVolume = 0;
+
+ _inputController = 0;
+ _inputDisabled = false;
+
+ _normalSpeed = true;
+
+ _currentCheat = -1;
+ _currentCheatPos = 0;
+
+ _modalObject = 0;
+
+ _gameContinue = true;
+ _needRestart = false;
+ _flgPlayIntro = true;
+ _gamePaused = false;
+ _inputArFlag = false;
+ _recordEvents = false;
+
+ _flgGameIsRunning = true;
+
+ _isProcessingMessages = false;
+
+ _musicAllowed = -1;
+
+ _aniMan = 0;
+ _aniMan2 = 0;
+ _currentScene = 0;
+ _scene2 = 0;
+ _movTable = 0;
+ _floaters = 0;
+
+ _globalMessageQueueList = 0;
+ _messageHandlers = 0;
+
+ _updateScreenCallback = 0;
+ _updateCursorCallback = 0;
+
+ _msgX = 0;
+ _msgY = 0;
+ _msgObjectId2 = 0;
+ _msgId = 0;
+ _mouseVirtX = 0;
+ _mouseVirtY = 0;
+
+ _currSelectedInventoryItemId = 0;
+
+ _behaviorManager = 0;
+
+ _cursorId = 0;
+
+ _keyState = Common::KEYCODE_INVALID;
+ _buttonState = 0;
+
+ _gameLoader = 0;
+ _gameProject = 0;
+
+ _updateFlag = true;
+ _flgCanOpenMap = true;
+
+ _sceneWidth = 1;
+ _sceneHeight = 1;
+
+ for (int i = 0; i < 11; i++)
+ _currSoundList1[i] = 0;
+
+ for (int i = 0; i < 200; i++)
+ _mapTable[i] = 0;
+
+ _inventoryScene = 0;
+ _inventory = 0;
+
+ _minCursorId = 0xffff;
+ _maxCursorId = 0;
+ _objectAtCursor = 0;
+ _objectIdAtCursor = 0;
+
+ _isSaveAllowed = true;
+
+ g_fullpipe = this;
+ g_vars = new Vars;
+}
+
+FullpipeEngine::~FullpipeEngine() {
+ delete _rnd;
+ delete _globalMessageQueueList;
+}
+
+void FullpipeEngine::initialize() {
+ _globalMessageQueueList = new GlobalMessageQueueList;
+ _behaviorManager = new BehaviorManager;
+
+ _sceneRect.left = 0;
+ _sceneRect.top = 0;
+ _sceneRect.right = 799;
+ _sceneRect.bottom = 599;
+
+ _floaters = new Floaters;
+}
+
+Common::Error FullpipeEngine::run() {
+ const Graphics::PixelFormat format(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ // Initialize backend
+ initGraphics(800, 600, true, &format);
+
+ _backgroundSurface.create(800, 600, format);
+
+ initialize();
+
+ _isSaveAllowed = false;
+
+ int scene = 0;
+ if (ConfMan.hasKey("boot_param"))
+ scene = convertScene(ConfMan.getInt("boot_param"));
+
+ if (!loadGam("fullpipe.gam", scene))
+ return Common::kNoGameDataFoundError;
+
+#if 0
+ loadAllScenes();
+#endif
+
+ _gameContinue = true;
+
+ while (_gameContinue) {
+ updateEvents();
+
+ updateScreen();
+
+ if (_needRestart) {
+ if (_modalObject) {
+ delete _modalObject;
+ _modalObject = 0;
+ }
+
+ freeGameLoader();
+ _currentScene = 0;
+ _updateTicks = 0;
+
+ loadGam("fullpipe.gam");
+ _needRestart = false;
+ }
+
+ if (_normalSpeed)
+ _system->delayMillis(10);
+ _system->updateScreen();
+ }
+
+ freeGameLoader();
+
+ cleanup();
+
+ return Common::kNoError;
+}
+
+void FullpipeEngine::updateEvents() {
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ ExCommand *ex;
+
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ _keyState = event.kbd.keycode;
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_SPACE:
+ if (_gamePaused) {
+ if (_modalObject) {
+ if (_modalObject->init(42)) {
+ _modalObject->update();
+ } else {
+ _modalObject->saveload();
+ BaseModalObject *obj = _modalObject->_parentObj;
+ if (obj)
+ delete _modalObject;
+ _modalObject = obj;
+ }
+ } else {
+ _gameLoader->updateSystems(42);
+ }
+ return;
+ }
+
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = 32;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ case Common::KEYCODE_s:
+ if (_gamePaused) {
+ _gamePaused = 0;
+ _flgGameIsRunning = true;
+ return;
+ }
+
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = event.kbd.keycode;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ case Common::KEYCODE_q:
+ return;
+ break;
+ default:
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = event.kbd.keycode;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ }
+ break;
+ case Common::EVENT_KEYUP:
+ if (!_inputArFlag) {
+ ex = new ExCommand(0, 17, 37, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->handle();
+ }
+ _keyState = Common::KEYCODE_INVALID;
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ if (_recordEvents) {
+ ex = new ExCommand(0, 17, 31, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->handle();
+ }
+
+ _mouseScreenPos = event.mouse;
+ break;
+ case Common::EVENT_QUIT:
+ _gameContinue = false;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
+ ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ _lastInputTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
+ ex = new ExCommand(0, 17, 29, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+
+ ex->_sceneClickX = _sceneRect.left + ex->_x;
+ ex->_sceneClickY = _sceneRect.top + ex->_y;
+ ex->_keyCode = getGameLoaderInventory()->getSelectedItemId();
+ ex->_excFlags |= 3;
+ _lastInputTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ case Common::EVENT_LBUTTONUP:
+ if (!_inputArFlag && (_updateTicks - _lastButtonUpTicks) >= 2) {
+ ex = new ExCommand(0, 17, 30, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ _lastButtonUpTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+
+#if 0
+ warning("STUB: FullpipeEngine::updateEvents() <mainWindowProc>");
+ if (Msg == MSG_SC11_SHOWSWING && _modalObject) {
+ _modalObject->method14();
+ }
+#endif
+}
+
+void FullpipeEngine::freeGameLoader() {
+ warning("STUB: FullpipeEngine::freeGameLoader()");
+}
+
+void FullpipeEngine::cleanup() {
+ warning("STUB: FullpipeEngine::cleanup()");
+}
+
+void FullpipeEngine::updateScreen() {
+ debug(4, "FullpipeEngine::updateScreen()");
+
+ _mouseVirtX = _mouseScreenPos.x + _sceneRect.left;
+ _mouseVirtY = _mouseScreenPos.y + _sceneRect.top;
+
+ //if (inputArFlag)
+ // updateGame_inputArFlag();
+
+ if (_modalObject || (_flgGameIsRunning && (_gameLoader->updateSystems(42), _modalObject != 0))) {
+ if (_flgGameIsRunning) {
+ if (_modalObject->init(42)) {
+ _modalObject->update();
+ } else {
+ _modalObject->saveload();
+ BaseModalObject *tmp = _modalObject->_parentObj;
+
+ delete _modalObject;
+
+ _modalObject = tmp;
+ }
+ }
+ } else if (_currentScene) {
+ _currentScene->draw();
+
+ if (_inventoryScene)
+ _inventory->draw();
+
+ if (_updateScreenCallback)
+ _updateScreenCallback();
+
+ //if (inputArFlag && _currentScene) {
+ // vrtTextOut(*(_DWORD *)g_vrtHandle, smallNftData, "DEMO", 4, 380, 580);
+ // vrtTextOut(*(_DWORD *)g_vrtHandle, smallNftData, "Alt+F4 - exit", 14, 695, 580);
+ //}
+ } else {
+ //vrtRectangle(*(_DWORD *)g_vrtHandle, 0, 0, 0, 800, 600);
+ }
+ _inputController->drawCursor(_mouseScreenPos.x, _mouseScreenPos.y);
+
+ ++_updateTicks;
+}
+
+int FullpipeEngine::getObjectEnumState(const char *name, const char *state) {
+ GameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (!var) {
+ var = _gameLoader->_gameVar->addSubVarAsInt("OBJSTATES", 0);
+ }
+
+ var = var->getSubVarByName(name);
+ if (var) {
+ var = var->getSubVarByName("ENUMSTATES");
+ if (var)
+ return var->getSubVarAsInt(state);
+ }
+
+ return 0;
+}
+
+int FullpipeEngine::getObjectState(const char *objname) {
+ GameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (var)
+ return var->getSubVarAsInt(objname);
+
+ return 0;
+}
+
+void FullpipeEngine::setObjectState(const char *name, int state) {
+ GameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (!var) {
+ var = _gameLoader->_gameVar->addSubVarAsInt("OBJSTATES", 0);
+ }
+
+ var->setSubVarAsInt(name, state);
+}
+
+void FullpipeEngine::updateMapPiece(int mapId, int update) {
+ for (int i = 0; i < 200; i++) {
+ int hiWord = (_mapTable[i] >> 16) & 0xffff;
+
+ if (hiWord == mapId) {
+ _mapTable[i] |= update;
+ return;
+ }
+ if (!hiWord) {
+ _mapTable[i] = (mapId << 16) | update;
+ return;
+ }
+ }
+}
+
+void FullpipeEngine::disableSaves(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::disableSaves()");
+}
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
new file mode 100644
index 0000000000..63dde5042b
--- /dev/null
+++ b/engines/fullpipe/fullpipe.h
@@ -0,0 +1,262 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_FULLPIPE_H
+#define FULLPIPE_FULLPIPE_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/random.h"
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "audio/mixer.h"
+
+#include "graphics/surface.h"
+
+#include "engines/engine.h"
+
+struct ADGameDescription;
+
+namespace Fullpipe {
+
+enum FullpipeGameFeatures {
+};
+
+class BehaviorManager;
+class BaseModalObject;
+class GameLoader;
+class GameVar;
+class InputController;
+class Inventory2;
+struct CursorInfo;
+struct EntranceInfo;
+class ExCommand;
+class Floaters;
+class GameProject;
+class GameObject;
+class GlobalMessageQueueList;
+struct MessageHandler;
+struct MovTable;
+class NGIArchive;
+class Scene;
+class SoundList;
+class StaticANIObject;
+class Vars;
+
+int global_messageHandler1(ExCommand *cmd);
+int global_messageHandler2(ExCommand *cmd);
+int global_messageHandler3(ExCommand *cmd);
+int global_messageHandler4(ExCommand *cmd);
+void global_messageHandler_handleSound(ExCommand *cmd);
+
+
+class FullpipeEngine : public ::Engine {
+protected:
+
+ Common::Error run();
+
+public:
+ FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc);
+ virtual ~FullpipeEngine();
+
+ void initialize();
+
+ void setMusicAllowed(int val) { _musicAllowed = val; }
+
+ // Detection related functions
+ const ADGameDescription *_gameDescription;
+ const char *getGameId() const;
+ Common::Platform getPlatform() const;
+ bool hasFeature(EngineFeature f) const;
+
+ Common::RandomSource *_rnd;
+
+ Common::KeyCode _keyState;
+ uint16 _buttonState;
+
+ void updateEvents();
+
+ Graphics::Surface _backgroundSurface;
+
+ GameLoader *_gameLoader;
+ GameProject *_gameProject;
+ bool loadGam(const char *fname, int scene = 0);
+
+ GameVar *getGameLoaderGameVar();
+ InputController *getGameLoaderInputController();
+
+ int _gameProjectVersion;
+ int _pictureScale;
+ int _scrollSpeed;
+ bool _updateFlag;
+ bool _flgCanOpenMap;
+ bool _gamePaused;
+ bool _flgGameIsRunning;
+ bool _inputArFlag;
+ bool _recordEvents;
+
+ Common::Rect _sceneRect;
+ int _sceneWidth;
+ int _sceneHeight;
+ Scene *_currentScene;
+ Scene *_scene2;
+ StaticANIObject *_aniMan;
+ StaticANIObject *_aniMan2;
+ byte *_globalPalette;
+
+ InputController *_inputController;
+ bool _inputDisabled;
+
+ int _currentCheat;
+ int _currentCheatPos;
+
+ void defHandleKeyDown(int key);
+
+ SoundList *_currSoundList1[11];
+ int _currSoundListCount;
+ bool _soundEnabled;
+ bool _flgSoundList;
+
+ void stopAllSounds();
+ void toggleMute();
+ void playSound(int id, int flag);
+ void startSceneTrack();
+
+ int _sfxVolume;
+
+ GlobalMessageQueueList *_globalMessageQueueList;
+ MessageHandler *_messageHandlers;
+
+ int _msgX;
+ int _msgY;
+ int _msgObjectId2;
+ int _msgId;
+
+ Common::List<ExCommand *> _exCommandList;
+ bool _isProcessingMessages;
+
+ int _mouseVirtX;
+ int _mouseVirtY;
+ Common::Point _mouseScreenPos;
+
+ BehaviorManager *_behaviorManager;
+
+ MovTable *_movTable;
+
+ Floaters *_floaters;
+
+ void initMap();
+ void updateMapPiece(int mapId, int update);
+ void updateScreen();
+
+ void freeGameLoader();
+ void cleanup();
+
+ bool _gameContinue;
+ bool _needRestart;
+ bool _flgPlayIntro;
+ int _musicAllowed;
+ bool _normalSpeed;
+
+ void enableSaves() { _isSaveAllowed = true; }
+ void disableSaves(ExCommand *ex);
+
+ void initObjectStates();
+ void setLevelStates();
+ void setSwallowedEggsState();
+ void loadAllScenes();
+
+ void initCursors();
+ void addCursor(CursorInfo *cursorInfo, Scene *inv, int pictureId, int hotspotX, int hotspotY, int itemPictureOffsX, int itemPictureOffsY);
+
+ int32 _mapTable[200];
+
+ Scene *_inventoryScene;
+ Inventory2 *_inventory;
+ int _currSelectedInventoryItemId;
+
+ int32 _updateTicks;
+ int32 _lastInputTicks;
+ int32 _lastButtonUpTicks;
+
+ BaseModalObject *_modalObject;
+
+ int (*_updateScreenCallback)();
+ int (*_updateCursorCallback)();
+
+ int _cursorId;
+ int _minCursorId;
+ int _maxCursorId;
+ Common::Array<int> _objectIdCursors;
+ GameObject *_objectAtCursor;
+ int _objectIdAtCursor;
+
+ void setCursor(int id);
+ void updateCursorCommon();
+
+ int getObjectState(const char *objname);
+ void setObjectState(const char *name, int state);
+ int getObjectEnumState(const char *name, const char *state);
+
+ bool sceneSwitcher(EntranceInfo *entrance);
+ Scene *accessScene(int sceneId);
+ void setSceneMusicParameters(GameVar *var);
+ int convertScene(int scene);
+
+ NGIArchive *_currArchive;
+
+ void openMap();
+ void openHelp();
+ void openMainMenu();
+
+ void initArcadeKeys(const char *varname);
+ void winArcade();
+ void getAllInventory();
+
+ int lift_getButtonIdP(int objid);
+ void lift_setButton(const char *name, int state);
+ void lift_sub5(Scene *sc, int qu1, int qu2);
+ void lift_exitSeq(ExCommand *ex);
+ void lift_closedoorSeq();
+ void lift_animation3();
+ void lift_goAnimation();
+ void lift_sub1(StaticANIObject *ani);
+ void lift_startExitQueue();
+ void lift_sub05(ExCommand *ex);
+
+public:
+
+ bool _isSaveAllowed;
+
+ bool canLoadGameStateCurrently() { return _isSaveAllowed; }
+ bool canSaveGameStateCurrently() { return _isSaveAllowed; }
+
+};
+
+extern FullpipeEngine *g_fullpipe;
+extern Vars *g_vars;
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_FULLPIPE_H */
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
new file mode 100644
index 0000000000..a2ab71d7e3
--- /dev/null
+++ b/engines/fullpipe/gameloader.cpp
@@ -0,0 +1,513 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/input.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/motion.h"
+
+namespace Fullpipe {
+
+Inventory2 *getGameLoaderInventory() {
+ return &g_fullpipe->_gameLoader->_inventory;
+}
+
+MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) {
+ for (uint i = 0; i < g_fullpipe->_gameLoader->_sc2array.size(); i++)
+ if (g_fullpipe->_gameLoader->_sc2array[i]._sceneId == sceneId)
+ return (MctlCompound *)g_fullpipe->_gameLoader->_sc2array[i]._motionController;
+
+ return 0;
+}
+
+InteractionController *getGameLoaderInteractionController() {
+ return g_fullpipe->_gameLoader->_interactionController;
+}
+
+GameLoader::GameLoader() {
+ _interactionController = new InteractionController();
+ _inputController = new InputController();
+
+ _gameProject = 0;
+ _gameName = 0;
+
+ addMessageHandlerByIndex(global_messageHandler2, 0, 0);
+ insertMessageHandler(global_messageHandler3, 0, 128);
+ insertMessageHandler(global_messageHandler4, 0, 1);
+
+ _field_FA = 0;
+ _field_F8 = 0;
+ _sceneSwitcher = 0;
+ _preloadCallback = 0;
+ _readSavegameCallback = 0;
+ _gameVar = 0;
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+ _updateCounter = 0;
+
+ g_fullpipe->_msgX = 0;
+ g_fullpipe->_msgY = 0;
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgId = 0;
+}
+
+GameLoader::~GameLoader() {
+ free(_gameName);
+ delete _gameProject;
+ delete _interactionController;
+ delete _inputController;
+}
+
+bool GameLoader::load(MfcArchive &file) {
+ debug(5, "GameLoader::load()");
+
+ _gameName = file.readPascalString();
+ debug(6, "_gameName: %s", _gameName);
+
+ _gameProject = new GameProject();
+
+ _gameProject->load(file);
+
+ g_fullpipe->_gameProject = _gameProject;
+
+ if (g_fullpipe->_gameProjectVersion < 12) {
+ error("Old gameProjectVersion: %d", g_fullpipe->_gameProjectVersion);
+ }
+
+ _gameName = file.readPascalString();
+ debug(6, "_gameName: %s", _gameName);
+
+ _inventory.load(file);
+
+ _interactionController->load(file);
+
+ debug(6, "sceneTag count: %d", _gameProject->_sceneTagList->size());
+
+ _sc2array.resize(_gameProject->_sceneTagList->size());
+
+ int i = 0;
+ for (SceneTagList::const_iterator it = _gameProject->_sceneTagList->begin(); it != _gameProject->_sceneTagList->end(); ++it, i++) {
+ char tmp[12];
+
+ snprintf(tmp, 11, "%04d.sc2", it->_sceneId);
+
+ debug(2, "sc: %s", tmp);
+
+ _sc2array[i].loadFile((const char *)tmp);
+ }
+
+ _preloadItems.load(file);
+
+ _field_FA = file.readUint16LE();
+ _field_F8 = file.readUint16LE();
+
+ _gameVar = (GameVar *)file.readClass();
+
+ return true;
+}
+
+bool GameLoader::loadScene(int sceneId) {
+ SceneTag *st;
+
+ int idx = getSceneTagBySceneId(sceneId, &st);
+
+ if (idx < 0)
+ return false;
+
+ if (!st->_scene)
+ st->loadScene();
+
+ if (st->_scene) {
+ st->_scene->init();
+
+ applyPicAniInfos(st->_scene, _sc2array[idx]._defPicAniInfos, _sc2array[idx]._defPicAniInfosCount);
+ applyPicAniInfos(st->_scene, _sc2array[idx]._picAniInfos, _sc2array[idx]._picAniInfosCount);
+
+ _sc2array[idx]._scene = st->_scene;
+ _sc2array[idx]._isLoaded = 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool GameLoader::gotoScene(int sceneId, int entranceId) {
+ SceneTag *st;
+
+ int sc2idx = getSceneTagBySceneId(sceneId, &st);
+
+ if (sc2idx < 0)
+ return false;
+
+ if (!_sc2array[sc2idx]._isLoaded)
+ return false;
+
+ if (_sc2array[sc2idx]._entranceDataCount < 1) {
+ g_fullpipe->_currentScene = st->_scene;
+ return true;
+ }
+
+ if (_sc2array[sc2idx]._entranceDataCount <= 0)
+ return false;
+
+ int entranceIdx = 0;
+ if (sceneId != 726) // WORKAROUND
+ for (entranceIdx = 0; _sc2array[sc2idx]._entranceData[entranceIdx]->_field_4 != entranceId; entranceIdx++) {
+ if (entranceIdx >= _sc2array[sc2idx]._entranceDataCount)
+ return false;
+ }
+
+ GameVar *sg = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+
+ if (sg || (sg = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0)) != 0)
+ sg->setSubVarAsInt("Entrance", entranceId);
+
+ if (!g_fullpipe->sceneSwitcher(_sc2array[sc2idx]._entranceData[entranceIdx]))
+ return false;
+
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgY = -1;
+ g_fullpipe->_msgX = -1;
+
+ g_fullpipe->_currentScene = st->_scene;
+
+ MessageQueue *mq1 = g_fullpipe->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId);
+ if (mq1) {
+ MessageQueue *mq = new MessageQueue(mq1, 0, 0);
+
+ StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ if (stobj) {
+ stobj->_flags &= 0x100;
+
+ ExCommand *ex = new ExCommand(stobj->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = 256;
+ ex->_messageNum = 0;
+ ex->_excFlags |= 3;
+
+ mq->_exCommands.push_back(ex);
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ if (!mq->chain(0)) {
+ delete mq;
+
+ return false;
+ }
+ } else {
+ StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ if (stobj)
+ stobj->_flags &= 0xfeff;
+ }
+
+ return true;
+}
+
+bool preloadCallback(const PreloadItem &pre, int flag) {
+ warning("STUB: preloadCallback");
+
+ return true;
+}
+
+bool GameLoader::preloadScene(int sceneId, int entranceId) {
+ debug(0, "preloadScene(%d, %d), ", sceneId, entranceId);
+
+ if (_preloadSceneId != sceneId || _preloadEntranceId != entranceId) {
+ _preloadSceneId = sceneId;
+ _preloadEntranceId = entranceId;
+ return true;
+ }
+
+ int idx = -1;
+
+ for (uint i = 0; i < _preloadItems.size(); i++)
+ if (_preloadItems[i]->preloadId1 == sceneId && _preloadItems[i]->preloadId2 == entranceId) {
+ idx = i;
+ break;
+ }
+
+ if (idx == -1) {
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+ return false;
+ }
+
+ if (_preloadCallback) {
+ if (!_preloadCallback(*_preloadItems[idx], 0))
+ return false;
+ }
+
+ if (g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId == sceneId)
+ g_fullpipe->_currentScene = 0;
+
+ saveScenePicAniInfos(sceneId);
+ clearGlobalMessageQueueList1();
+ unloadScene(sceneId);
+
+ if (_preloadCallback)
+ _preloadCallback(*_preloadItems[idx], 50);
+
+ loadScene(_preloadItems[idx]->sceneId);
+
+ ExCommand *ex = new ExCommand(_preloadItems[idx]->sceneId, 17, 62, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+ ex->_keyCode = _preloadItems[idx]->keyCode;
+
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+
+ if (_preloadCallback)
+ _preloadCallback(*_preloadItems[idx], 100);
+
+ ex->postMessage();
+
+ return true;
+}
+
+bool GameLoader::unloadScene(int sceneId) {
+ SceneTag *tag;
+ int sceneTag = getSceneTagBySceneId(sceneId, &tag);
+
+ if (sceneTag < 0)
+ return false;
+
+ if (_sc2array[sceneTag]._isLoaded)
+ saveScenePicAniInfos(sceneId);
+
+ _sc2array[sceneTag]._motionController->freeItems();
+
+ delete tag->_scene;
+ tag->_scene = 0;
+
+ _sc2array[sceneTag]._isLoaded = 0;
+ _sc2array[sceneTag]._scene = 0;
+
+ return true;
+}
+
+int GameLoader::getSceneTagBySceneId(int sceneId, SceneTag **st) {
+ if (_sc2array.size() > 0 && _gameProject->_sceneTagList->size() > 0) {
+ for (uint i = 0; i < _sc2array.size(); i++) {
+ if (_sc2array[i]._sceneId == sceneId) {
+ int num = 0;
+ for (SceneTagList::iterator s = _gameProject->_sceneTagList->begin(); s != _gameProject->_sceneTagList->end(); ++s, num++) {
+ if (s->_sceneId == sceneId) {
+ *st = &(*s);
+ return num;
+ }
+ }
+ }
+ }
+ }
+
+ *st = 0;
+ return -1;
+}
+
+void GameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount) {
+ if (picAniInfoCount <= 0)
+ return;
+
+ debug(0, "GameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount);
+
+ PictureObject *pict;
+ StaticANIObject *ani;
+
+ for (int i = 0; i < picAniInfoCount; i++) {
+ debug(7, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type);
+ if (picAniInfo[i]->type & 2) {
+ pict = sc->getPictureObjectById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+ if (pict) {
+ pict->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ pict = sc->getPictureObjectById(picAniInfo[i]->objectId, 0);
+ if (pict) {
+ PictureObject *pictNew = new PictureObject(pict);
+
+ sc->_picObjList.push_back(pictNew);
+ pictNew->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ } else {
+ if (!(picAniInfo[i]->type & 1))
+ continue;
+
+ Scene *scNew = g_fullpipe->accessScene(picAniInfo[i]->sceneId);
+ if (!scNew)
+ continue;
+
+ ani = sc->getStaticANIObject1ById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+ if (ani) {
+ ani->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+
+ ani = scNew->getStaticANIObject1ById(picAniInfo[i]->objectId, 0);
+ if (ani) {
+ StaticANIObject *aniNew = new StaticANIObject(ani);
+
+ sc->addStaticANIObject(aniNew, 1);
+
+ aniNew->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ }
+ }
+}
+
+void GameLoader::saveScenePicAniInfos(int sceneId) {
+ warning("STUB: GameLoader::saveScenePicAniInfos(%d)", sceneId);
+}
+
+void GameLoader::updateSystems(int counterdiff) {
+ if (g_fullpipe->_currentScene) {
+ g_fullpipe->_currentScene->update(counterdiff);
+
+ _exCommand._messageKind = 17;
+ _updateCounter++;
+ _exCommand._messageNum = 33;
+ _exCommand._excFlags = 0;
+ _exCommand.postMessage();
+ }
+
+ processMessages();
+
+ if (_preloadSceneId) {
+ processMessages();
+ preloadScene(_preloadSceneId, _preloadEntranceId);
+ }
+}
+
+Sc2::Sc2() {
+ _sceneId = 0;
+ _field_2 = 0;
+ _scene = 0;
+ _motionController = 0;
+ _data1 = 0;
+ _count1 = 0;
+ _defPicAniInfos = 0;
+ _defPicAniInfosCount = 0;
+ _picAniInfos = 0;
+ _picAniInfosCount = 0;
+ _isLoaded = 0;
+ _entranceData = 0;
+ _entranceDataCount = 0;
+}
+
+bool Sc2::load(MfcArchive &file) {
+ debug(5, "Sc2::load()");
+
+ _sceneId = file.readUint16LE();
+
+ _motionController = (MotionController *)file.readClass();
+
+ _count1 = file.readUint32LE();
+ debug(4, "count1: %d", _count1);
+ if (_count1 > 0) {
+ _data1 = (int32 *)malloc(_count1 * sizeof(int32));
+
+ for (int i = 0; i < _count1; i++) {
+ _data1[i] = file.readUint32LE();
+ }
+ } else {
+ _data1 = 0;
+ }
+
+ _defPicAniInfosCount = file.readUint32LE();
+ debug(4, "defPicAniInfos: %d", _defPicAniInfosCount);
+ if (_defPicAniInfosCount > 0) {
+ _defPicAniInfos = (PicAniInfo **)malloc(_defPicAniInfosCount * sizeof(PicAniInfo *));
+
+ for (int i = 0; i < _defPicAniInfosCount; i++) {
+ _defPicAniInfos[i] = new PicAniInfo();
+
+ _defPicAniInfos[i]->load(file);
+ }
+ } else {
+ _defPicAniInfos = 0;
+ }
+
+ _picAniInfos = 0;
+ _picAniInfosCount = 0;
+
+ _entranceDataCount = file.readUint32LE();
+ debug(4, "_entranceData: %d", _entranceDataCount);
+
+ if (_entranceDataCount > 0) {
+ _entranceData = (EntranceInfo **)malloc(_entranceDataCount * sizeof(EntranceInfo *));
+
+ for (int i = 0; i < _entranceDataCount; i++) {
+ _entranceData[i] = new EntranceInfo();
+ _entranceData[i]->load(file);
+ }
+ } else {
+ _entranceData = 0;
+ }
+
+ if (file.size() - file.pos() > 0)
+ error("Sc2::load(): (%d bytes left)", file.size() - file.pos());
+
+ return true;
+}
+
+bool PreloadItems::load(MfcArchive &file) {
+ debug(5, "PreloadItems::load()");
+
+ int count = file.readCount();
+
+ clear();
+
+ for (int i = 0; i < count; i++) {
+ PreloadItem *t = new PreloadItem();
+ t->preloadId1 = file.readUint32LE();
+ t->preloadId2 = file.readUint32LE();
+ t->sceneId = file.readUint32LE();
+ t->keyCode = file.readUint32LE();
+
+ push_back(t);
+ }
+
+ return true;
+}
+
+GameVar *FullpipeEngine::getGameLoaderGameVar() {
+ if (_gameLoader)
+ return _gameLoader->_gameVar;
+ else
+ return 0;
+}
+
+InputController *FullpipeEngine::getGameLoaderInputController() {
+ if (_gameLoader)
+ return _gameLoader->_inputController;
+ else
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
new file mode 100644
index 0000000000..4f5462671d
--- /dev/null
+++ b/engines/fullpipe/gameloader.h
@@ -0,0 +1,117 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_GAMELOADER_H
+#define FULLPIPE_GAMELOADER_H
+
+#include "fullpipe/objects.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/messages.h"
+
+namespace Fullpipe {
+
+class SceneTag;
+class MctlCompound;
+class InputController;
+class InteractionController;
+class MotionController;
+
+class Sc2 : public CObject {
+ public:
+ int16 _sceneId;
+ int16 _field_2;
+ Scene *_scene;
+ MotionController *_motionController;
+ int32 *_data1; // FIXME, could be a struct
+ int _count1;
+ PicAniInfo **_defPicAniInfos;
+ int _defPicAniInfosCount;
+ PicAniInfo **_picAniInfos;
+ int _picAniInfosCount;
+ int _isLoaded;
+ EntranceInfo **_entranceData;
+ int _entranceDataCount;
+
+ public:
+ Sc2();
+ virtual bool load(MfcArchive &file);
+};
+
+typedef Common::Array<Sc2> Sc2Array;
+
+struct PreloadItem {
+ int preloadId1;
+ int preloadId2;
+ int sceneId;
+ int keyCode;
+};
+
+bool preloadCallback(const PreloadItem &pre, int flag);
+
+class PreloadItems : public Common::Array<PreloadItem *>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class GameLoader : public CObject {
+ public:
+ GameLoader();
+ virtual ~GameLoader();
+
+ virtual bool load(MfcArchive &file);
+ bool loadScene(int sceneId);
+ bool gotoScene(int sceneId, int entranceId);
+ bool preloadScene(int sceneId, int entranceId);
+ bool unloadScene(int sceneId);
+
+ void updateSystems(int counterdiff);
+
+ int getSceneTagBySceneId(int sceneId, SceneTag **st);
+ void applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount);
+ void saveScenePicAniInfos(int sceneId);
+
+ GameProject *_gameProject;
+ InteractionController *_interactionController;
+ InputController *_inputController;
+ Inventory2 _inventory;
+ Sc2Array _sc2array;
+ void *_sceneSwitcher;
+ bool (*_preloadCallback)(const PreloadItem &pre, int flag);
+ void *_readSavegameCallback;
+ int16 _field_F8;
+ int16 _field_FA;
+ PreloadItems _preloadItems;
+ GameVar *_gameVar;
+ char *_gameName;
+ ExCommand _exCommand;
+ int _updateCounter;
+ int _preloadSceneId;
+ int _preloadEntranceId;
+};
+
+Inventory2 *getGameLoaderInventory();
+InteractionController *getGameLoaderInteractionController();
+MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId);
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_GAMELOADER_H */
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
new file mode 100644
index 0000000000..fba7e402d2
--- /dev/null
+++ b/engines/fullpipe/gfx.cpp
@@ -0,0 +1,1250 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+
+#include "common/memstream.h"
+
+namespace Fullpipe {
+
+Bitmap::Bitmap() {
+ _x = 0;
+ _y = 0;
+ _width = 0;
+ _height = 0;
+ _pixels = 0;
+ _type = 0;
+ _dataSize = 0;
+ _flags = 0;
+}
+
+Bitmap::Bitmap(Bitmap *src) {
+ _x = src->_x;
+ _y = src->_y;
+ _flags = src->_flags;
+ _dataSize = src->_dataSize;
+ _type = src->_type;
+ _width = src->_width;
+ _height = src->_height;
+ _pixels = src->_pixels;
+}
+
+Bitmap::~Bitmap() {
+ if (_pixels)
+ free(_pixels);
+}
+
+void Bitmap::load(Common::ReadStream *s) {
+ debug(5, "Bitmap::load()");
+
+ _x = s->readUint32LE();
+ _y = s->readUint32LE();
+ _width = s->readUint32LE();
+ _height = s->readUint32LE();
+ s->readUint32LE(); // pixels
+ _type = s->readUint32LE();
+ _dataSize = s->readUint32LE();
+ _flags = s->readUint32LE();
+
+ debug(8, "Bitmap: x: %d y: %d w: %d h: %d dataSize: 0x%x", _x, _y, _width, _height, _dataSize);
+ debug(8, "Bitmap: type: %s (0x%04x) flags: 0x%x", Common::tag2string(_type).c_str(), _type, _flags);
+}
+
+Background::Background() {
+ _x = 0;
+ _y = 0;
+ _messageQueueId = 0;
+ _bigPictureArray1Count = 0;
+ _bigPictureArray2Count = 0;
+ _bigPictureArray = 0;
+ _bgname = 0;
+ _palette = 0;
+}
+
+bool Background::load(MfcArchive &file) {
+ debug(5, "Background::load()");
+ _bgname = file.readPascalString();
+
+ int count = file.readUint16LE();
+
+ for (int i = 0; i < count; i++) {
+ PictureObject *pct = new PictureObject();
+
+ pct->load(file, i == 0);
+ addPictureObject(pct);
+ }
+
+ assert(g_fullpipe->_gameProjectVersion >= 4);
+
+ _bigPictureArray1Count = file.readUint32LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 5);
+
+ _bigPictureArray2Count = file.readUint32LE();
+
+ _bigPictureArray = (BigPicture ***)calloc(_bigPictureArray1Count, sizeof(BigPicture **));
+
+ debug(6, "bigPictureArray[%d][%d]", _bigPictureArray1Count, _bigPictureArray2Count);
+
+ for (int i = 0; i < _bigPictureArray1Count; i++) {
+ _bigPictureArray[i] = (BigPicture **)calloc(_bigPictureArray2Count, sizeof(BigPicture *));
+ for (int j = 0; j < _bigPictureArray2Count; j++) {
+ _bigPictureArray[i][j] = new BigPicture();
+
+ _bigPictureArray[i][j]->load(file);
+ }
+ }
+
+ return true;
+}
+
+void Background::addPictureObject(PictureObject *pct) {
+ if (pct->_okeyCode)
+ pct->renumPictures(&_picObjList);
+
+ bool inserted = false;
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i])->_priority == pct->_priority) {
+ _picObjList.insert_at(i, pct);
+ inserted = true;
+ break;
+ }
+ }
+
+ if (!inserted) {
+ _picObjList.push_back(pct);
+ }
+}
+
+PictureObject::PictureObject() {
+ _ox = 0;
+ _oy = 0;
+ _picture = 0;
+ _ox2 = 0;
+ _oy2 = 0;
+ _pictureObject2List = 0;
+ _objtype = kObjTypePictureObject;
+}
+
+PictureObject::PictureObject(PictureObject *src) : GameObject(src) {
+ _picture = src->_picture;
+ _ox2 = _ox;
+ _oy2 = _oy;
+ _pictureObject2List = src->_pictureObject2List;
+ _objtype = kObjTypePictureObject;
+}
+
+bool PictureObject::load(MfcArchive &file, bool bigPicture) {
+ debug(5, "PictureObject::load()");
+ GameObject::load(file);
+
+ if (bigPicture)
+ _picture = new BigPicture();
+ else
+ _picture = new Picture();
+
+ _picture->load(file);
+
+ _pictureObject2List = new PtrList();
+
+ int count = file.readUint16LE();
+
+ if (count > 0) {
+ GameObject *o = new GameObject();
+
+ o->load(file);
+ _pictureObject2List->push_back(o);
+ }
+
+ _ox2 = _ox;
+ _oy2 = _oy;
+
+#if 0
+ _picture->displayPicture();
+#endif
+
+ return true;
+}
+
+Common::Point *PictureObject::getDimensions(Common::Point *p) {
+ _picture->getDimensions(p);
+
+ return p;
+}
+
+void PictureObject::draw() {
+ if (_flags & 1)
+ _picture->draw(_ox, _oy, 2, 0);
+ else
+ _picture->draw(_ox, _oy, 0, 0);
+}
+
+void PictureObject::drawAt(int x, int y) {
+ if (x == -1)
+ x = _ox;
+ if (y == -1)
+ y = _oy;
+
+ _picture->_x = x;
+ _picture->_y = y;
+
+ if (_flags & 1)
+ _picture->draw(x, y, 2, 0);
+ else
+ _picture->draw(x, y, 0, 0);
+}
+
+bool PictureObject::setPicAniInfo(PicAniInfo *picAniInfo) {
+ if (!(picAniInfo->type & 2) || (picAniInfo->type & 1)) {
+ error("Picture::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+
+ return false;
+ }
+
+ if (picAniInfo->type & 2) {
+ setOXY(picAniInfo->ox, picAniInfo->oy);
+ _priority = picAniInfo->priority;
+ _okeyCode = picAniInfo->field_8;
+ setFlags(picAniInfo->flags);
+ _field_8 = picAniInfo->field_24;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool PictureObject::isPointInside(int x, int y) {
+ bool res;
+ int oldx = _picture->_x;
+ int oldy = _picture->_y;
+
+ _picture->_x = _ox;
+ _picture->_y = _oy;
+
+ res = _picture->isPointInside(x, y);
+
+ _picture->_x = oldx;
+ _picture->_y = oldy;
+
+ return res;
+}
+
+bool PictureObject::isPixelHitAtPos(int x, int y) {
+ int oldx = _picture->_x;
+ int oldy = _picture->_y;
+
+ _picture->_x = _ox;
+ _picture->_y = _oy;
+ bool res = _picture->isPixelHitAtPos(x, y);
+ _picture->_x = oldx;
+ _picture->_y = oldy;
+
+ return res;
+}
+
+GameObject::GameObject() {
+ _okeyCode = 0;
+ _flags = 0;
+ _id = 0;
+ _ox = 0;
+ _oy = 0;
+ _priority = 0;
+ _field_20 = 0;
+ _field_8 = 0;
+ _objectName = 0;
+}
+
+GameObject::GameObject(GameObject *src) {
+ _okeyCode = 1;
+ _flags = 0;
+ _id = src->_id;
+
+ _objectName = (char *)calloc(strlen(src->_objectName) + 1, 1);
+ strncpy(_objectName, src->_objectName, strlen(src->_objectName));
+
+ _ox = src->_ox;
+ _oy = src->_oy;
+ _priority = src->_priority;
+ _field_20 = 1;
+ _field_8 = src->_field_8;
+}
+
+GameObject::~GameObject() {
+ free(_objectName);
+}
+
+bool GameObject::load(MfcArchive &file) {
+ debug(5, "GameObject::load()");
+ _okeyCode = 0;
+ _flags = 0;
+ _field_20 = 0;
+
+ _id = file.readUint16LE();
+
+ _objectName = file.readPascalString();
+ _ox = file.readUint32LE();
+ _oy = file.readUint32LE();
+ _priority = file.readUint16LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 11) {
+ _field_8 = file.readUint32LE();
+ }
+
+ return true;
+}
+
+void GameObject::setOXY(int x, int y) {
+ _ox = x;
+ _oy = y;
+}
+
+void GameObject::renumPictures(PtrList *lst) {
+ int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
+
+ for (uint i = 0; i < lst->size(); i++) {
+ if (_id == ((PictureObject *)((*lst)[i]))->_id)
+ buf[((PictureObject *)((*lst)[i]))->_okeyCode] = 1;
+ }
+
+ if (buf[_okeyCode]) {
+ uint count;
+ for (count = 1; buf[count] && count < lst->size() + 2; count++)
+ ;
+ _okeyCode = count;
+ }
+
+ free(buf);
+}
+
+bool GameObject::getPicAniInfo(PicAniInfo *info) {
+ if (_objtype == kObjTypePictureObject) {
+ info->type = 2;
+ info->objectId = _id;
+ info->sceneId = 0;
+ info->field_8 = _okeyCode;
+ info->flags = _flags;
+ info->field_24 = _field_8;
+ info->ox = _ox;
+ info->oy = _oy;
+ info->priority = _priority;
+
+ return true;
+ }
+
+ if (_objtype == kObjTypeStaticANIObject) {
+ StaticANIObject *ani = (StaticANIObject *)this;
+
+ info->type = (ani->_messageQueueId << 16) | 1;
+ info->objectId = ani->_id;
+ info->field_8 = ani->_okeyCode;
+ info->sceneId = ani->_sceneId;
+ info->flags = ani->_flags;
+ info->field_24 = ani->_field_8;
+ if (ani->_movement) {
+ info->ox = ani->_movement->_ox;
+ info->oy = ani->_movement->_oy;
+ } else {
+ info->ox = ani->_ox;
+ info->oy = ani->_oy;
+ }
+ info->priority = ani->_priority;
+
+ if (ani->_statics)
+ info->staticsId = ani->_statics->_staticsId;
+
+ if (ani->_movement) {
+ info->movementId = ani->_movement->_id;
+ info->dynamicPhaseIndex = ani->_movement->_currDynamicPhaseIndex;
+ }
+
+ info->someDynamicPhaseIndex = ani->_someDynamicPhaseIndex;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool GameObject::setPicAniInfo(PicAniInfo *picAniInfo) {
+ if (!(picAniInfo->type & 3)) {
+ warning("StaticANIObject::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+
+ return false;
+ }
+
+ if (picAniInfo->type & 3) {
+ setOXY(picAniInfo->ox, picAniInfo->oy);
+ _priority = picAniInfo->priority;
+ _okeyCode = picAniInfo->field_8;
+ setFlags(picAniInfo->flags);
+ _field_8 = picAniInfo->field_24;
+ }
+
+ if (picAniInfo->type & 1) {
+ StaticANIObject *ani = (StaticANIObject *)this;
+
+ ani->_messageQueueId = (picAniInfo->type >> 16) & 0xffff;
+
+ if (picAniInfo->staticsId) {
+ ani->_statics = ani->getStaticsById(picAniInfo->staticsId);
+ } else {
+ ani->_statics = 0;
+ }
+
+ if (picAniInfo->movementId) {
+ ani->_movement = ani->getMovementById(picAniInfo->movementId);
+ if (ani->_movement)
+ ani->_movement->setDynamicPhaseIndex(picAniInfo->dynamicPhaseIndex);
+ } else {
+ ani->_movement = 0;
+ }
+
+ ani->setSomeDynamicPhaseIndex(picAniInfo->someDynamicPhaseIndex);
+ }
+
+ return true;
+}
+
+Picture::Picture() {
+ _x = 0;
+ _y = 0;
+ _field_44 = 0;
+ _field_54 = 0;
+ _bitmap = 0;
+ _alpha = -1;
+ _paletteData = 0;
+ _convertedBitmap = 0;
+ _memoryObject2 = 0;
+ _width = 0;
+ _height = 0;
+}
+
+Picture::~Picture() {
+ freePicture();
+
+ _bitmap = 0;
+
+ if (_memoryObject2)
+ delete _memoryObject2;
+
+ if (_paletteData)
+ free(_paletteData);
+
+ if (_convertedBitmap) {
+ delete _convertedBitmap;
+ _convertedBitmap = 0;
+ }
+}
+
+void Picture::freePicture() {
+ debug(5, "Picture::freePicture(): file: %s", _memfilename);
+
+ if (_bitmap) {
+ if (testFlags() && !_field_54) {
+ freeData();
+ delete _bitmap;
+ _bitmap = 0;
+ }
+ }
+
+ if (_bitmap) {
+ _bitmap = 0;
+ _data = 0;
+ }
+
+ if (_convertedBitmap) {
+ free(_convertedBitmap->_pixels);
+ delete _convertedBitmap;
+ _convertedBitmap = 0;
+ }
+}
+
+bool Picture::load(MfcArchive &file) {
+ debug(5, "Picture::load()");
+ MemoryObject::load(file);
+
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _field_44 = file.readUint16LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 2);
+
+ _width = file.readUint32LE();
+ _height = file.readUint32LE();
+
+ _mflags |= 1;
+
+ _memoryObject2 = new MemoryObject2;
+ _memoryObject2->load(file);
+
+ if (_memoryObject2->_data) {
+ setAOIDs();
+ }
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ _alpha = file.readUint32LE() & 0xff;
+
+ int havePal = file.readUint32LE();
+
+ if (havePal > 0) {
+ _paletteData = (byte *)calloc(1024, 1);
+ file.read(_paletteData, 1024);
+ }
+
+ getData();
+
+ debug(5, "Picture::load: loaded <%s>", _memfilename);
+
+ return true;
+}
+
+void Picture::setAOIDs() {
+ int w = (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale;
+ int h = (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale;
+
+ _memoryObject2->_rows = (byte **)malloc(w * sizeof(int *));
+
+ int pitch = 2 * h;
+ byte *ptr = _memoryObject2->getData();
+ for (int i = 0; i < w; i++) {
+ _memoryObject2->_rows[i] = ptr;
+ ptr += pitch;
+ }
+}
+
+void Picture::init() {
+ debug(5, "Picture::init(), %s", _memfilename);
+
+ MemoryObject::getData();
+
+ _bitmap = new Bitmap();
+
+ getDibInfo();
+
+ _bitmap->_flags |= 0x1000000;
+}
+
+Common::Point *Picture::getDimensions(Common::Point *p) {
+ p->x = _width;
+ p->y = _height;
+
+ return p;
+}
+
+void Picture::getDibInfo() {
+ int off = _dataSize & ~0xf;
+
+ debug(9, "Picture::getDibInfo: _dataSize: %d", _dataSize);
+
+ if (!_dataSize) {
+ warning("Picture::getDibInfo(): Empty data size");
+ return;
+ }
+
+ if (_dataSize != off) {
+ warning("Uneven data size: 0x%x", _dataSize);
+ }
+
+ if (!_data) {
+ warning("Picture::getDibInfo: data is empty <%s>", _memfilename);
+
+ MemoryObject::load();
+ }
+
+ Common::MemoryReadStream *s = new Common::MemoryReadStream(_data + off - 32, 32);
+
+ _bitmap->load(s);
+ _bitmap->_pixels = _data;
+}
+
+Bitmap *Picture::getPixelData() {
+ if (!_bitmap)
+ init();
+
+ return _bitmap;
+}
+
+void Picture::draw(int x, int y, int style, int angle) {
+ int x1 = x;
+ int y1 = y;
+
+ debug(0, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename);
+
+ if (x != -1)
+ x1 = x;
+
+ if (y != -1)
+ y1 = y;
+
+ if (!_bitmap)
+ init();
+
+ if (!_bitmap)
+ return;
+
+ if ((_alpha & 0xff) < 0xff) {
+ debug(0, "Picture:draw: alpha = %0x", _alpha);
+ }
+
+ byte *pal = _paletteData;
+
+ if (!pal) {
+ //warning("Picture:draw: using global palette");
+ pal = g_fullpipe->_globalPalette;
+ }
+
+ Common::Point point;
+
+ switch (style) {
+ case 1:
+ //flip
+ getDimensions(&point);
+ _bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + point.y, pal);
+ break;
+ case 2:
+ //vrtSetFadeRatio(g_vrtDrawHandle, 0.34999999);
+ //vrtSetFadeTable(g_vrtDrawHandle, &unk_477F88, 1.0, 1000.0, 0, 0);
+ _bitmap->drawShaded(2, x1, y1, pal);
+ //vrtSetFadeRatio(g_vrtDrawHandle, 0.0);
+ //vrtSetFadeTable(g_vrtDrawHandle, &unk_477F90, 1.0, 1000.0, 0, 0);
+ break;
+ default:
+ if (angle)
+ drawRotated(x1, y1, angle);
+ else {
+ _bitmap->putDib(x1, y1, (int32 *)pal);
+ }
+ }
+}
+
+void Picture::drawRotated(int x, int y, int angle) {
+ warning("STUB: Picture::drawRotated(%d, %d, %d)", x, y, angle);
+}
+
+void Picture::displayPicture() {
+ if (!g_fullpipe->_gameContinue)
+ return;
+
+ getData();
+ init();
+
+ if (!_dataSize)
+ return;
+
+ g_fullpipe->_backgroundSurface.fillRect(Common::Rect(0, 0, 799, 599), 0);
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(0, 0), g_fullpipe->_backgroundSurface.pitch, 0, 0, 799, 599);
+
+ draw(0, 0, 0, 0);
+
+ g_fullpipe->updateEvents();
+ g_fullpipe->_system->delayMillis(10);
+ g_fullpipe->_system->updateScreen();
+
+ while (g_fullpipe->_gameContinue) {
+ g_fullpipe->updateEvents();
+ g_fullpipe->_system->delayMillis(10);
+ g_fullpipe->_system->updateScreen();
+
+ if (g_fullpipe->_keyState == ' ') {
+ g_fullpipe->_keyState = Common::KEYCODE_INVALID;
+ break;
+ }
+ }
+}
+
+void Picture::setPaletteData(byte *pal) {
+ if (_paletteData)
+ free(_paletteData);
+
+ if (pal) {
+ _paletteData = (byte *)malloc(1024);
+ memcpy(_paletteData, pal, 1024);
+ }
+}
+
+void Picture::copyMemoryObject2(Picture *src) {
+ if (_width == src->_width && _height == src->_height) {
+ if (src->_memoryObject2 && src->_memoryObject2->_rows && _memoryObject2) {
+ byte *data = loadData();
+ _memoryObject2->copyData(data, _dataSize);
+ setAOIDs();
+ }
+ }
+}
+
+bool Picture::isPointInside(int x, int y) {
+ if (x >= _x) {
+ if (y >= _y && x < _x + _width && y < _y + _height)
+ return true;
+ }
+ return false;
+}
+
+bool Picture::isPixelHitAtPos(int x, int y) {
+ if (x < _x || y < _y || x >= _x + _width || y >= _y + _height)
+ return false;
+
+ if (!_bitmap)
+ init();
+
+ _bitmap->_x = _x;
+ _bitmap->_y = _y;
+
+ return _bitmap->isPixelHitAtPos(x, y);
+}
+
+int Picture::getPixelAtPos(int x, int y) {
+ return getPixelAtPosEx(x / g_fullpipe->_pictureScale, y / g_fullpipe->_pictureScale);
+
+ return false;
+}
+
+int Picture::getPixelAtPosEx(int x, int y) {
+ if (x < 0 || y < 0)
+ return 0;
+
+ if (x < (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale &&
+ y < (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale &&
+ _memoryObject2 != 0 && _memoryObject2->_rows != 0)
+ return _memoryObject2->_rows[x][2 * y];
+
+ return 0;
+}
+
+bool Bitmap::isPixelHitAtPos(int x, int y) {
+ if (x < _x || x >= _width + _x || y < _y || y >= _y + _height)
+ return false;
+
+ int off;
+
+ if (_type == 'CB\x05e')
+ off = 2 * ((_width + 1) / 2);
+ else
+ off = 4 * ((_width + 3) / 4);
+
+ off = x + off * (_y + _height - y - 1) - _x;
+
+ if (_flags & 0x1000000) {
+ switch (_type) {
+ case 'CB\0\0':
+ if (_pixels[off] == (_flags & 0xff))
+ return false;
+ break;
+ case 'CB\x05e':
+ if (!*(int16 *)&_pixels[2 * off])
+ return false;
+ break;
+ case 'RB\0\0':
+ return isPixelAtHitPosRB(x, y);
+ }
+ }
+ return true;
+}
+
+bool Bitmap::isPixelAtHitPosRB(int x, int y) {
+ int ox = _x;
+ int oy = _y;
+
+ _x = _y = 0;
+
+ bool res = putDibRB(0, x, y);
+ _x = ox;
+ _y = oy;
+
+ return res;
+}
+
+void Bitmap::putDib(int x, int y, int32 *palette) {
+ debug(0, "Bitmap::putDib(%d, %d)", x, y);
+
+ _x = x - g_fullpipe->_sceneRect.left;
+ _y = y - g_fullpipe->_sceneRect.top;
+
+ if (_type == MKTAG('R', 'B', '\0', '\0'))
+ putDibRB(palette);
+ else
+ putDibCB(palette);
+}
+
+bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
+ uint16 *curDestPtr;
+ int endy;
+ int x;
+ int start1;
+ int fillLen;
+ uint16 pixel;
+ int endx;
+ int y;
+ uint16 *srcPtr2;
+ uint16 *srcPtr;
+
+ if (!palette && pX == -1) {
+ warning("Bitmap::putDibRB(): Both global and local palettes are empty");
+ return false;
+ }
+
+ debug(8, "Bitmap::putDibRB()");
+
+ endx = _width + _x - 1;
+ endy = _height + _y - 1;
+
+ if (_x > 799 || endx < 0 || _y > 599 || endy < 0)
+ return false;
+
+ if (pX == -1) {
+ if (endy > 599)
+ endy = 599;
+
+ if (endx > 799)
+ endx = 799;
+ }
+
+ int startx = _x;
+ if (startx < 0)
+ startx = 0;
+
+ int starty = _y;
+ if (starty < 0)
+ starty = 0;
+
+ y = endy;
+
+ srcPtr = (uint16 *)_pixels;
+
+ bool breakup = false;
+ for (y = endy; y >= starty && !breakup; y--) {
+ x = startx;
+
+ while ((pixel = *srcPtr++) != 0) {
+ if (pixel == 0x100) {
+ breakup = true;
+ break;
+ }
+
+ while (pixel == 0x200 && y >= starty) {
+ uint16 value = *srcPtr++;
+
+ x += (byte)(value & 0xff);
+ y -= (byte)((value >> 8) & 0xff);
+
+ pixel = *srcPtr++;
+ }
+
+ if (y < starty || pixel == 0)
+ break;
+
+ start1 = x;
+ fillLen = (byte)(pixel & 0xff);
+
+ if (fillLen) {
+ x += fillLen;
+
+ if (start1 < 0) {
+ fillLen += start1;
+
+ if (fillLen > 0)
+ start1 = 0;
+ }
+
+ if (fillLen > 0 || start1 >= 0) {
+ if (x <= 799 + 1 || (fillLen += 799 - x + 1, fillLen > 0)) {
+ if (y <= endy) {
+ if (pX == -1) {
+ int bgcolor = palette[(pixel >> 8) & 0xff];
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ colorFill(curDestPtr, fillLen, bgcolor);
+ } else {
+ if (y == pY && pX >= start1 && pX < start1 + fillLen)
+ return true;
+ }
+ }
+ }
+ }
+ } else {
+ fillLen = (pixel >> 8) & 0xff;
+ srcPtr2 = srcPtr;
+ x += fillLen;
+ srcPtr += (fillLen + 1) >> 1;
+
+ if (start1 < 0) {
+ fillLen += start1;
+ if (fillLen > 0) {
+ srcPtr2 = (uint16 *)((byte *)srcPtr2 - start1);
+ start1 = 0;
+ }
+ }
+
+ if (x > 799 + 1) {
+ fillLen += 799 - x + 1;
+ if (fillLen <= 0)
+ continue;
+ }
+
+ if (y <= endy) {
+ if (pX == -1) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ paletteFill(curDestPtr, (byte *)srcPtr2, fillLen, (int32 *)palette);
+ } else {
+ if (y == pY && pX >= start1 && pX < start1 + fillLen)
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ if (pX == -1)
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+
+ return false;
+}
+
+void Bitmap::putDibCB(int32 *palette) {
+ uint16 *curDestPtr;
+ int endx;
+ int endy;
+ int bpp;
+ uint pitch;
+ bool cb05_format;
+
+ endx = _width + _x - 1;
+ endy = _height + _y - 1;
+
+ debug(8, "Bitmap::putDibCB(): %d, %d, %d, %d [%d, %d]", _x, _y, endx, endy, _width, _height);
+
+ if (_x > 799 || endx < 0 || _y > 599 || endy < 0)
+ return;
+
+ if (endy > 599)
+ endy = 599;
+
+ if (endx > 799)
+ endx = 799;
+
+ cb05_format = (_type == MKTAG('C', 'B', '\05', 'e'));
+
+ if (!palette && !cb05_format)
+ error("Bitmap::putDibCB(): Both global and local palettes are empty");
+
+ bpp = cb05_format ? 2 : 1;
+ pitch = (bpp * _width + 3) & 0xFFFFFFFC;
+
+ byte *srcPtr = &_pixels[pitch * (endy - _y)];
+
+ int starty = _y;
+ if (starty < 0) {
+ starty = 0;
+ srcPtr = &_pixels[pitch * (_height + _y)];
+ }
+
+ int startx = _x;
+ if (startx < 0) {
+ srcPtr += bpp * -_x;
+ startx = 0;
+ }
+
+ if (_flags & 0x1000000) {
+ for (int y = starty; y < endy; srcPtr -= pitch, y++) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ copierKeyColor(curDestPtr, srcPtr, endx - startx + 1, _flags & 0xff, (int32 *)palette, cb05_format);
+ }
+ } else {
+ for (int y = starty; y <= endy; srcPtr -= pitch, y++) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ copier(curDestPtr, srcPtr, endx - startx + 1, (int32 *)palette, cb05_format);
+ }
+ }
+
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+}
+
+void Bitmap::colorFill(uint16 *dest, int len, int32 color) {
+#if 0
+ if (blendMode) {
+ if (blendMode != 1)
+ error("vrtPutDib : RLE Fill : Invalid alpha blend mode");
+
+ colorFill = ptralphaFillColor16bit;
+ } else {
+ colorFill = ptrfillColor16bit;
+ }
+#endif
+
+ for (int i = 0; i < len; i++)
+ *dest++ = (int16)(color & 0xffff);
+}
+
+void Bitmap::paletteFill(uint16 *dest, byte *src, int len, int32 *palette) {
+#if 0
+ if (blendMode) {
+ if (blendMode != 1)
+ error("vrtPutDib : RLE Fill : Invalid alpha blend mode");
+
+ paletteFill = ptrcopierWithPaletteAlpha;
+ } else {
+ paletteFill = ptrcopierWithPalette;
+ }
+#endif
+
+ for (int i = 0; i < len; i++)
+ *dest++ = READ_LE_UINT32(&palette[*src++]) & 0xffff;
+}
+
+void Bitmap::copierKeyColor(uint16 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format) {
+#if 0
+ if (blendMode) {
+ if (blendMode == 1) {
+ if (cb05_format)
+ copierKeyColor = ptrcopier16bitKeycolorAlpha;
+ else
+ copierKeyColor = ptrcopierKeycolorAlpha;
+ } else {
+ copier = 0;
+ }
+ } else if (cb05_format) {
+ copierKeyColor = ptrcopier16bitKeycolor;
+ } else {
+ copierKeyColor = ptrkeyColor16bit;
+ }
+#endif
+
+ if (!cb05_format) {
+ for (int i = 0; i < len; i++) {
+ if (*src != keyColor)
+ *dest = READ_LE_UINT32(&palette[*src]) & 0xffff;
+
+ dest++;
+ src++;
+ }
+ } else {
+ int16 *src16 = (int16 *)src;
+
+ for (int i = 0; i < len; i++) {
+ if (*src16 != 0)
+ *dest = *src16;
+
+ dest++;
+ src16++;
+ }
+ }
+}
+
+void Bitmap::copier(uint16 *dest, byte *src, int len, int32 *palette, bool cb05_format) {
+#if 0
+ if (blendMode) {
+ if (blendMode == 1) {
+ if (cb05_format)
+ copier = ptrcopier16bitAlpha;
+ else
+ copier = ptrcopierWithPaletteAlpha;
+ } else {
+ copier = 0;
+ }
+ } else if (cb05_format) {
+ copier = ptrcopier16bit;
+ } else {
+ copier = ptrcopierWithPalette;
+ }
+#endif
+
+ if (!cb05_format) {
+ for (int i = 0; i < len; i++)
+ *dest++ = READ_LE_UINT32(&palette[*src++]) & 0xffff;
+ } else {
+ int16 *src16 = (int16 *)src;
+
+ for (int i = 0; i < len; i++)
+ *dest++ = *src16++;
+ }
+}
+
+Bitmap *Bitmap::reverseImage() {
+ switch (_type) {
+ case MKTAG('R', 'B', '\0', '\0'):
+ return reverseImageRB();
+ case MKTAG('C', 'B', '\0', '\0'):
+ return reverseImageCB();
+ case MKTAG('C', 'B', '\05', 'e'):
+ return reverseImageCB05();
+ default:
+ error("Bitmap::reverseImage: Unknown image type: %x", _type);
+ }
+
+ return 0;
+}
+
+Bitmap *Bitmap::reverseImageRB() {
+ uint16 *newpixels = (uint16 *)calloc(((_dataSize + 15) & 0xfffffff0) + sizeof(Bitmap), 1);
+ uint16 *srcPtr = (uint16 *)_pixels;
+
+ int idx = 0;
+ while (srcPtr[idx] != 0x100) {
+ uint16 *srcPtr2 = &srcPtr[idx];
+
+ int prevIdx = idx;
+ int i = idx;
+
+ while (*srcPtr2) {
+ ++srcPtr2;
+ ++idx;
+ }
+
+ int idx2 = idx;
+
+ newpixels[idx] = srcPtr[idx];
+
+ while (i != idx) {
+ int fillLen = 2 - ((srcPtr[prevIdx] & 0xff) != 0 ? 1 : 0);
+ idx2 -= fillLen;
+ memcpy(&newpixels[idx2], &srcPtr[prevIdx], 2 * fillLen);
+ prevIdx = fillLen + i;
+ i += fillLen;
+ }
+ ++idx;
+ }
+ newpixels[idx] = 256;
+
+ int oldBmp = ((_dataSize + 15) >> 1) & 0x7FFFFFF8;
+ memcpy(&newpixels[oldBmp], &srcPtr[oldBmp], sizeof(Bitmap));
+
+ Bitmap *res = new Bitmap(this);
+ res->_pixels = (byte *)newpixels;
+
+ return res;
+}
+
+Bitmap *Bitmap::reverseImageCB() {
+ warning("STUB: Bitmap::reverseImageCB()");
+
+ return this;
+}
+
+Bitmap *Bitmap::reverseImageCB05() {
+ warning("STUB: Bitmap::reverseImageCB05()");
+
+ return this;
+}
+
+Bitmap *Bitmap::flipVertical() {
+ warning("STUB: Bitmap::flipVertical()");
+
+ return this;
+}
+
+void Bitmap::drawShaded(int type, int x, int y, byte *palette) {
+ warning("STUB: Bitmap::drawShaded(%d, %d, %d)", type, x, y);
+
+ putDib(x, y, (int32 *)palette);
+}
+
+ void Bitmap::drawRotated(int x, int y, int angle, byte *palette) {
+ warning("STUB: Bitmap::drawShaded(%d, %d, %d)", x, y, angle);
+
+ putDib(x, y, (int32 *)palette);
+}
+
+bool BigPicture::load(MfcArchive &file) {
+ debug(5, "BigPicture::load()");
+ Picture::load(file);
+
+ return true;
+}
+
+Shadows::Shadows() {
+ _staticAniObjectId = 0;
+ _movementId = 0;
+ _sceneId = 0;
+}
+
+bool Shadows::load(MfcArchive &file) {
+ debug(5, "Shadows::load()");
+ _sceneId = file.readUint32LE();
+ _staticAniObjectId = file.readUint32LE();
+ _movementId = file.readUint32LE();
+
+ return true;
+}
+
+void Shadows::init() {
+ Scene *scene = g_fullpipe->accessScene(_sceneId);
+
+ StaticANIObject *st;
+ Movement *mov;
+
+ if (scene && (st = scene->getStaticANIObject1ById(_staticAniObjectId, -1)) != 0
+ && ((mov = st->getMovementById(_movementId)) != 0))
+ initMovement(mov);
+}
+
+void Shadows::initMovement(Movement *mov) {
+ uint num;
+
+ if (mov->_currMovement)
+ num = mov->_currMovement->_dynamicPhases.size();
+ else
+ num = mov->_dynamicPhases.size();
+
+ _items.clear();
+ _items.resize(num);
+
+ Common::Point point;
+
+ _items[0].dynPhase = (DynamicPhase *)mov->_staticsObj1;
+ _items[0].dynPhase->getDimensions(&point);
+ _items[0].width = point.x;
+ _items[0].height = point.y;
+
+ for (uint i = 1; i < num; i++) {
+ _items[i].dynPhase = mov->getDynamicPhaseByIndex(i - 1);
+ _items[i].dynPhase->getDimensions(&point);
+ _items[i].width = point.x;
+ _items[i].height = point.y;
+ }
+}
+
+DynamicPhase *Shadows::findSize(int width, int height) {
+ int idx = 0;
+ int min = 1000;
+
+ if (!_items.size())
+ return 0;
+
+ for (uint i = 0; i < _items.size(); i++) {
+ int w = abs(width - _items[i].width);
+ if (w < min) {
+ min = w;
+ idx = i;
+ }
+ }
+ return _items[idx].dynPhase;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
new file mode 100644
index 0000000000..9d5c45de0b
--- /dev/null
+++ b/engines/fullpipe/gfx.h
@@ -0,0 +1,218 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_GFX_H
+#define FULLPIPE_GFX_H
+
+namespace Fullpipe {
+
+class DynamicPhase;
+class Movement;
+struct PicAniInfo;
+
+struct Bitmap {
+ int _x;
+ int _y;
+ int _width;
+ int _height;
+ byte *_pixels;
+ int _type;
+ int _dataSize;
+ int _flags;
+
+ Bitmap();
+ Bitmap(Bitmap *src);
+ ~Bitmap();
+
+ void load(Common::ReadStream *s);
+ void putDib(int x, int y, int32 *palette);
+ bool putDibRB(int32 *palette, int x = -1, int y = -1);
+ void putDibCB(int32 *palette);
+
+ void colorFill(uint16 *dest, int len, int32 color);
+ void paletteFill(uint16 *dest, byte *src, int len, int32 *palette);
+ void copierKeyColor(uint16 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format);
+ void copier(uint16 *dest, byte *src, int len, int32 *palette, bool cb05_format);
+
+ Bitmap *reverseImage();
+ Bitmap *reverseImageRB();
+ Bitmap *reverseImageCB();
+ Bitmap *reverseImageCB05();
+ Bitmap *flipVertical();
+
+ void drawShaded(int type, int x, int y, byte *palette);
+ void drawRotated(int x, int y, int angle, byte *palette);
+
+ bool isPixelHitAtPos(int x, int y);
+ bool isPixelAtHitPosRB(int x, int y);
+};
+
+class Picture : public MemoryObject {
+ public:
+ Common::Rect _rect;
+ Bitmap *_convertedBitmap;
+ int _x;
+ int _y;
+ int _field_44;
+ int _width;
+ int _height;
+ Bitmap *_bitmap;
+ int _field_54;
+ MemoryObject2 *_memoryObject2;
+ int _alpha;
+ byte *_paletteData;
+
+ void displayPicture();
+
+ public:
+ Picture();
+ virtual ~Picture();
+
+ void freePicture();
+
+ virtual bool load(MfcArchive &file);
+ void setAOIDs();
+ void init();
+ void getDibInfo();
+ Bitmap *getPixelData();
+ void draw(int x, int y, int style, int angle);
+ void drawRotated(int x, int y, int angle);
+
+ byte getAlpha() { return (byte)_alpha; }
+ void setAlpha(byte alpha) { _alpha = alpha; }
+
+ Common::Point *getDimensions(Common::Point *p);
+ bool isPointInside(int x, int y);
+ bool isPixelHitAtPos(int x, int y);
+ int getPixelAtPos(int x, int y);
+ int getPixelAtPosEx(int x, int y);
+
+ byte *getPaletteData() { return _paletteData; }
+ void setPaletteData(byte *pal);
+
+ void copyMemoryObject2(Picture *src);
+};
+
+class BigPicture : public Picture {
+ public:
+ BigPicture() {}
+ virtual bool load(MfcArchive &file);
+};
+
+class GameObject : public CObject {
+ public:
+ int16 _okeyCode;
+ int _field_8;
+ int16 _flags;
+ int16 _id;
+ char *_objectName;
+ int _ox;
+ int _oy;
+ int _priority;
+ int _field_20;
+
+ public:
+ GameObject();
+ GameObject(GameObject *src);
+ ~GameObject();
+
+ virtual bool load(MfcArchive &file);
+ void setOXY(int x, int y);
+ void renumPictures(PtrList *lst);
+ void setFlags(int16 flags) { _flags = flags; }
+ void clearFlags() { _flags = 0; }
+ const char *getName() { return _objectName; }
+
+ bool getPicAniInfo(PicAniInfo *info);
+ bool setPicAniInfo(PicAniInfo *info);
+};
+
+class PictureObject : public GameObject {
+ public:
+ Picture *_picture;
+ PtrList *_pictureObject2List;
+ int _ox2;
+ int _oy2;
+
+ public:
+ PictureObject();
+ PictureObject(PictureObject *src);
+
+ virtual bool load(MfcArchive &file, bool bigPicture);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
+
+ Common::Point *getDimensions(Common::Point *p);
+ void draw();
+ void drawAt(int x, int y);
+
+ bool setPicAniInfo(PicAniInfo *picAniInfo);
+ bool isPointInside(int x, int y);
+ bool isPixelHitAtPos(int x, int y);
+};
+
+class Background : public CObject {
+ public:
+ PtrList _picObjList;
+
+ char *_bgname;
+ int _x;
+ int _y;
+ int16 _messageQueueId;
+ MemoryObject *_palette;
+ int _bigPictureArray1Count;
+ int _bigPictureArray2Count;
+ BigPicture ***_bigPictureArray;
+
+ public:
+ Background();
+ virtual bool load(MfcArchive &file);
+ void addPictureObject(PictureObject *pct);
+
+ BigPicture *getBigPicture(int x, int y) { return _bigPictureArray[x][y]; }
+};
+
+struct ShadowsItem {
+ int width;
+ int height;
+ DynamicPhase *dynPhase;
+};
+
+typedef Common::Array<ShadowsItem> ShadowsItemArray;
+
+class Shadows : public CObject {
+ int _sceneId;
+ int _staticAniObjectId;
+ int _movementId;
+ ShadowsItemArray _items;
+
+ public:
+ Shadows();
+ virtual bool load(MfcArchive &file);
+ void init();
+
+ void initMovement(Movement *mov);
+ DynamicPhase *findSize(int width, int height);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_GFX_H */
diff --git a/engines/fullpipe/init.cpp b/engines/fullpipe/init.cpp
new file mode 100644
index 0000000000..49bf72ac91
--- /dev/null
+++ b/engines/fullpipe/init.cpp
@@ -0,0 +1,247 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+void FullpipeEngine::initObjectStates() {
+ setLevelStates();
+
+ setObjectState(sO_Dude, getObjectEnumState(sO_Dude, sO_NotCarryingEgg));
+ setObjectState(sO_EggCracker, getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg));
+ setObjectState(sO_GuvTheDrawer, getObjectEnumState(sO_GuvTheDrawer, sO_Awaken));
+ setObjectState(sO_EggGulper, getObjectEnumState(sO_EggGulper, sO_First));
+ setObjectState(sO_EggGulperGaveCoin, getObjectEnumState(sO_EggGulperGaveCoin, sO_No));
+ setObjectState(sO_Jar_4, getObjectEnumState(sO_Jar_4, sO_OnTheSpring));
+ setObjectState(sO_GulpedEggs, getObjectEnumState(sO_GulpedEgg, sO_NotPresent));
+
+ setSwallowedEggsState();
+
+ setObjectState(sO_WeirdWacko, getObjectEnumState(sO_WeirdWacko, sO_InGlasses));
+ setObjectState(sO_TumyTrampie, getObjectEnumState(sO_TumyTrampie, sO_Drinking));
+ setObjectState(sO_StairsUp_8, getObjectEnumState(sO_StairsUp_8, sO_NotBroken));
+ setObjectState(sO_HareTheNooksiter, getObjectEnumState(sO_HareTheNooksiter, sO_WithHandle));
+ setObjectState(sO_Elephantine, getObjectEnumState(sO_Elephantine, sO_WithBoot));
+ setObjectState(sO_Fly_12, 0);
+ setObjectState(sO_ClockAxis, getObjectEnumState(sO_ClockAxis, sO_NotAvailable));
+ setObjectState(sO_ClockHandle, getObjectEnumState(sO_ClockHandle, sO_In_7));
+ setObjectState(sO_BigMumsy, getObjectEnumState(sO_BigMumsy, sO_Sleeping));
+ setObjectState(sO_CoinSlot_1, getObjectEnumState(sO_CoinSlot_1, sO_Empty));
+ setObjectState(sO_FriesPit, getObjectEnumState(sO_FriesPit, sO_WithApple));
+ setObjectState(sO_Jug, getObjectEnumState(sO_Jug, sO_Blocked));
+ setObjectState(sO_RightStairs_9, getObjectEnumState(sO_RightStairs_9, sO_IsClosed));
+ setObjectState(sO_Pipe_9, getObjectEnumState(sO_Pipe_9, sO_WithJug));
+ setObjectState(sO_Inflater, getObjectEnumState(sO_Inflater, sO_WithGum));
+ setObjectState(sO_Swingie, getObjectEnumState(sO_Swingie, sO_Swinging));
+ setObjectState(sO_DudeJumped, getObjectEnumState(sO_DudeJumped, sO_No));
+ setObjectState(sO_Bridge, getObjectEnumState(sO_Bridge, sO_Convoluted));
+ setObjectState(sO_Guardian, getObjectEnumState(sO_Guardian, sO_OnRight));
+ setObjectState(sO_Grandma, getObjectEnumState(sO_Grandma, sO_In_14));
+ setObjectState(sO_Boot_15, getObjectEnumState(sO_Boot_15, sO_NotPresent));
+ setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_OpenedShe));
+ setObjectState(sO_Pedestal_16, getObjectEnumState(sO_Pedestal_16, sO_IsFree));
+ setObjectState(sO_Cup, getObjectEnumState(sO_Cup, sO_InSmokeRoom));
+ setObjectState(sO_Pedestal_17, getObjectEnumState(sO_Pedestal_17, sO_IsFree));
+ setObjectState(sO_UsherHand, getObjectEnumState(sO_UsherHand, sO_WithoutCoin));
+ setObjectState(sO_RightPipe_17, getObjectEnumState(sO_RightPipe_17, sO_IsClosed));
+ setObjectState(sO_Fly_17, 1);
+ setObjectState(sO_DudeSwinged, 0);
+ setObjectState(sO_Girl, getObjectEnumState(sO_Girl, sO_Swinging));
+ setObjectState(sO_Sugar, getObjectEnumState(sO_Sugar, sO_Present));
+ setObjectState(sO_Janitors, getObjectEnumState(sO_Janitors, sO_Together));
+ setObjectState(sO_Bag_22, getObjectEnumState(sO_Bag_22, sO_NotFallen));
+ setObjectState(sO_Grandpa, getObjectEnumState(sO_Grandpa, sO_InSock));
+ setObjectState(sO_CoinSlot_22, getObjectEnumState(sO_CoinSlot_22, sO_Empty));
+ setObjectState(sO_UpperHatch_23, getObjectEnumState(sO_UpperHatch_23, sO_Closed));
+ setObjectState(sO_LowerHatch_23, getObjectEnumState(sO_LowerHatch_23, sO_Closed));
+ setObjectState(sO_Lever_23, getObjectEnumState(sO_Lever_23, sO_NotTaken));
+ setObjectState(sO_LeverHandle_23, getObjectEnumState(sO_LeverHandle_23, sO_WithoutStool));
+ setObjectState(sO_LowerPipe_21, getObjectEnumState(sO_LowerPipe_21, sO_IsClosed));
+ setObjectState(sO_StarsDown_24, getObjectEnumState(sO_StarsDown_24, sO_OpenedShe));
+ setObjectState(sO_Hatch_26, getObjectEnumState(sO_Hatch_26, sO_Closed));
+ setObjectState(sO_Sock_26, getObjectEnumState(sO_Sock_26, sO_NotHanging));
+ setObjectState(sO_LeftPipe_26, getObjectEnumState(sO_LeftPipe_26, sO_IsClosed));
+ setObjectState(sO_Valve1_26, getObjectEnumState(sO_Valve1_26, sO_Opened));
+ setObjectState(sO_Valve2_26, getObjectEnumState(sO_Valve2_26, sO_Closed));
+ setObjectState(sO_Valve3_26, getObjectEnumState(sO_Valve3_26, sO_Closed));
+ setObjectState(sO_Valve4_26, getObjectEnumState(sO_Valve4_26, sO_Closed));
+ setObjectState(sO_Valve5_26, getObjectEnumState(sO_Valve5_26, sO_Opened));
+ setObjectState(sO_Pool, getObjectEnumState(sO_Pool, sO_Overfull));
+ setObjectState(sO_Plank_25, getObjectEnumState(sO_Plank_25, sO_NearDudesStairs));
+ setObjectState(sO_Driver, getObjectEnumState(sO_Driver, sO_WithSteering));
+ setObjectState(sO_Janitress, getObjectEnumState(sO_Janitress, sO_WithMop));
+ setObjectState(sO_LeftPipe_29, getObjectEnumState(sO_LeftPipe_29, sO_IsClosed));
+ setObjectState(sO_LeftPipe_30, getObjectEnumState(sO_LeftPipe_30, sO_IsClosed));
+ setObjectState(sO_Leg, getObjectEnumState(sO_Leg, sO_ShowingHeel));
+ setObjectState(sO_Tub, getObjectEnumState(sO_Tub, sO_EmptyShe));
+ setObjectState(sO_Cactus, getObjectEnumState(sO_Cactus, sO_NotGrown));
+ setObjectState(sO_Fireman, getObjectEnumState(sO_Fireman, sO_WithHose));
+ setObjectState(sO_Cube, getObjectEnumState(sO_Cube, sO_In_33));
+ setObjectState(sO_MommyOfHandle_32, getObjectEnumState(sO_MommyOfHandle_32, sO_WithoutHandle));
+ setObjectState(sO_Pedestal_33, getObjectEnumState(sO_Pedestal_33, sO_IsFree));
+ setObjectState(sO_Valve_34, getObjectEnumState(sO_Valve_34, sO_WithNothing));
+ setObjectState(sO_Stool_34, getObjectEnumState(sO_Stool_34, sO_WithoutDrawer));
+ setObjectState(sO_Plank_34, getObjectEnumState(sO_Plank_34, sO_Passive));
+ setObjectState(sO_Hatch_34, getObjectEnumState(sO_Hatch_34, sO_Closed));
+ setObjectState(sO_Valve_35, getObjectEnumState(sO_Valve_35, sO_TurnedOff));
+ setObjectState(sO_Carpet_35, getObjectEnumState(sO_Carpet_35, sO_CannotTake));
+ setObjectState(sO_CoinSlot_35, getObjectEnumState(sO_CoinSlot_35, sO_WithCoin));
+ setObjectState(sO_BellyInflater, getObjectEnumState(sO_BellyInflater, sO_WithCork));
+ setObjectState(sO_Jawcrucnher, getObjectEnumState(sO_Jawcrucnher, sO_WithoutCarpet));
+ setObjectState(sO_Guard_1, getObjectEnumState(sO_Guard_1, sO_On));
+ setObjectState(sO_Gurad_2, getObjectEnumState(sO_Gurad_2, sO_On));
+ setObjectState(sO_Guard_3, getObjectEnumState(sO_Guard_3, sO_On));
+ setObjectState(sO_Bottle_38, getObjectEnumState(sO_Bottle_38, sO_OnTheTable));
+ setObjectState(sO_Boss, getObjectEnumState(sO_Boss, sO_WithHammer));
+}
+
+void FullpipeEngine::setLevelStates() {
+ GameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+
+ if (v) {
+ v->setSubVarAsInt(sO_Level0, 2833);
+ v->setSubVarAsInt(sO_Level1, 2754);
+ v->setSubVarAsInt(sO_Level2, 2757);
+ v->setSubVarAsInt(sO_Level3, 2760);
+ v->setSubVarAsInt(sO_Level4, 2763);
+ v->setSubVarAsInt(sO_Level5, 2766);
+ v->setSubVarAsInt(sO_Level6, 2769);
+ v->setSubVarAsInt(sO_Level7, 2772);
+ v->setSubVarAsInt(sO_Level8, 2775);
+ v->setSubVarAsInt(sO_Level9, 2778);
+ }
+}
+
+void FullpipeEngine::addCursor(CursorInfo *cursorInfo, Scene *inv, int pictureId, int hotspotX, int hotspotY, int itemPictureOffsX, int itemPictureOffsY) {
+ cursorInfo->pictureId = pictureId;
+ cursorInfo->picture = inv->getPictureObjectById(pictureId, 0)->_picture;
+ cursorInfo->hotspotX = hotspotX;
+ cursorInfo->hotspotY = hotspotY;
+ cursorInfo->itemPictureOffsX = itemPictureOffsX;
+ cursorInfo->itemPictureOffsY = itemPictureOffsY;
+
+ getGameLoaderInputController()->addCursor(cursorInfo);
+}
+
+void FullpipeEngine::initCursors() {
+ CursorInfo crs;
+ Scene *inv = accessScene(SC_INV);
+
+ addCursor(&crs, inv, PIC_CSR_DEFAULT, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_DEFAULT_INV, 18, 18, 23, 23);
+ addCursor(&crs, inv, PIC_CSR_ITN, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_RED, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_GREEN, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_INV, 23, 17, 23, 17);
+ addCursor(&crs, inv, PIC_CSR_GOU, 15, 17, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOD, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOL, 26, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOR, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOFAR_L, 1, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOFAR_R, 39, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE1, 12, 24, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE2, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE2_D, 22, 15, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE3, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE4, 18, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE5, 23, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE6, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE6_D, 0, 0, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE7, 21, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE7_D, 7, 20, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE8, 23, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_LIFT, 6, 13, 10, 10);
+
+ getGameLoaderInputController()->setCursorMode(0);
+}
+
+void FullpipeEngine::initMap() {
+ memset(_mapTable, 0, sizeof(_mapTable));
+
+ updateMapPiece(PIC_MAP_S01, 1);
+ updateMapPiece(PIC_MAP_A13, 1u);
+}
+
+void FullpipeEngine::loadAllScenes() {
+ accessScene(301);
+ accessScene(302);
+ accessScene(303);
+ accessScene(304);
+ accessScene(305);
+ accessScene(321);
+ accessScene(635);
+ accessScene(649);
+ accessScene(650);
+ accessScene(651);
+ accessScene(652);
+ accessScene(653);
+ accessScene(654);
+ accessScene(655);
+ accessScene(726);
+ accessScene(858);
+ accessScene(903);
+ accessScene(1137);
+ accessScene(1138);
+ accessScene(1139);
+ accessScene(1140);
+ accessScene(1141);
+ accessScene(1142);
+ accessScene(1143);
+ accessScene(1144);
+ accessScene(1546);
+ accessScene(1547);
+ accessScene(1548);
+ accessScene(1549);
+ accessScene(1550);
+ accessScene(1551);
+ accessScene(1552);
+ accessScene(2062);
+ accessScene(2063);
+ accessScene(2064);
+ accessScene(2065);
+ accessScene(2066);
+ accessScene(2067);
+ accessScene(2068);
+ accessScene(2069);
+ accessScene(2070);
+ accessScene(2071);
+ accessScene(2072);
+ accessScene(2460);
+ accessScene(3896);
+ accessScene(3907);
+ accessScene(4620);
+ accessScene(4999);
+ accessScene(5000);
+ accessScene(5001);
+ accessScene(5166);
+ accessScene(5222);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
new file mode 100644
index 0000000000..e98920c78a
--- /dev/null
+++ b/engines/fullpipe/input.cpp
@@ -0,0 +1,277 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/input.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+InputController::InputController() {
+ g_fullpipe->_inputController = this;
+
+ _flag = 0;
+ _cursorHandle = 0;
+ _hCursor = 0;
+ _field_14 = 0;
+ _cursorId = 0;
+ _cursorIndex = -1;
+ _inputFlags = 1;
+
+ _cursorBounds.left = 0;
+ _cursorBounds.top = 0;
+ _cursorBounds.right = 0;
+ _cursorBounds.bottom = 0;
+
+ _cursorItemPicture = 0;
+}
+
+InputController::~InputController() {
+ removeMessageHandler(126, -1);
+
+ g_fullpipe->_inputController = 0;
+}
+
+void InputController::setInputDisabled(bool state) {
+ _flag = state;
+ g_fullpipe->_inputDisabled = state;
+}
+
+void setInputDisabled(bool state) {
+ g_fullpipe->_inputController->setInputDisabled(state);
+}
+
+void InputController::addCursor(CursorInfo *cursor) {
+ CursorInfo *newc = new CursorInfo(cursor);
+ Common::Point p;
+
+ cursor->picture->getDimensions(&p);
+
+ newc->width = p.x;
+ newc->height = p.y;
+
+ newc->picture->_x = -1;
+ newc->picture->_y = -1;
+
+ _cursorsArray.push_back(newc);
+}
+
+void InputController::setCursorMode(bool enabled) {
+ if (enabled)
+ _inputFlags |= 1;
+ else
+ _inputFlags &= ~1;
+}
+
+void InputController::drawCursor(int x, int y) {
+ if (_cursorIndex == -1)
+ return;
+
+ _cursorBounds.left = g_fullpipe->_sceneRect.left + x - _cursorsArray[_cursorIndex]->hotspotX;
+ _cursorBounds.top = g_fullpipe->_sceneRect.top + y - _cursorsArray[_cursorIndex]->hotspotY;
+ _cursorBounds.right = _cursorBounds.left + _cursorsArray[_cursorIndex]->width;
+ _cursorBounds.bottom = _cursorBounds.top + _cursorsArray[_cursorIndex]->height;
+
+ _cursorsArray[_cursorIndex]->picture->draw(_cursorBounds.left, _cursorBounds.top, 0, 0);
+
+ if (_cursorItemPicture)
+ _cursorItemPicture->draw(_cursorBounds.left + _cursorsArray[_cursorIndex]->itemPictureOffsX,
+ _cursorBounds.top + _cursorsArray[_cursorIndex]->itemPictureOffsY, 0, 0);
+}
+
+void InputController::setCursor(int cursorId) {
+ if (_cursorIndex == -1 || _cursorsArray[_cursorIndex]->pictureId != cursorId) {
+ _cursorIndex = -1;
+
+ for (uint i = 0; i < _cursorsArray.size(); i++) {
+ if (_cursorsArray[i]->pictureId == cursorId) {
+ _cursorIndex = i;
+ break;
+ }
+ }
+ }
+}
+
+CursorInfo::CursorInfo() {
+ pictureId = 0;
+ picture = 0;
+ hotspotX = 0;
+ hotspotY = 0;
+ itemPictureOffsX = 0;
+ itemPictureOffsY = 0;
+ width = 0;
+ height = 0;
+}
+
+CursorInfo::CursorInfo(CursorInfo *src) {
+ pictureId = src->pictureId;
+ picture = src->picture;
+ hotspotX = src->hotspotX;
+ hotspotY = src->hotspotY;
+ itemPictureOffsX = src->itemPictureOffsX;
+ itemPictureOffsY = src->itemPictureOffsY;
+ width = src->width;
+ height = src->height;
+}
+
+void FullpipeEngine::setCursor(int id) {
+ if (_inputController)
+ _inputController->setCursor(id);
+}
+
+const char *input_cheats[] = {
+ "HELP",
+ "STUFF",
+ "FASTER",
+ "OHWAIT",
+ "MUSOFF",
+ ""
+};
+
+void FullpipeEngine::defHandleKeyDown(int key) {
+ if (_currentCheat == -1) {
+ for (int i = 0; input_cheats[i][0]; i++)
+ if (toupper(key) == input_cheats[i][0]) {
+ _currentCheat = i;
+ _currentCheatPos = 1;
+ }
+
+ return;
+ }
+
+ if (toupper(key) != input_cheats[_currentCheat][_currentCheatPos]) {
+ _currentCheat = -1;
+
+ return;
+ }
+
+ _currentCheatPos++;
+
+ if (!input_cheats[_currentCheat][_currentCheatPos]) {
+ switch (_currentCheat) {
+ case 0: // HELP
+ winArcade();
+ break;
+ case 1: // STUFF
+ getAllInventory();
+ break;
+ case 2: // FASTER
+ _normalSpeed = !_normalSpeed;
+ break;
+ case 3: // OHWAIT
+ _gamePaused = 1;
+ _flgGameIsRunning = 0;
+ break;
+ case 4: // MUSOFF
+ if (_musicAllowed & 2)
+ setMusicAllowed(_musicAllowed & 0xFFFFFFFD);
+ else
+ setMusicAllowed(_musicAllowed | 2);
+ break;
+ default:
+ break;
+ }
+
+ _currentCheatPos = 0;
+ _currentCheat = -1;
+ }
+}
+
+void FullpipeEngine::winArcade() {
+ ExCommand *ex = new ExCommand(0, 17, MSG_CMN_WINARCADE, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+
+ ex->postMessage();
+
+}
+
+void FullpipeEngine::updateCursorCommon() {
+ GameObject *ani = _currentScene->getStaticANIObjectAtPos(_mouseVirtX, _mouseVirtY);
+
+ GameObject *pic = _currentScene->getPictureObjectAtPos(_mouseVirtX, _mouseVirtY);
+ if (!ani || (pic && pic->_priority < ani->_priority))
+ ani = pic;
+
+ int selId = getGameLoaderInventory()->getSelectedItemId();
+
+ _objectAtCursor = ani;
+
+ if (ani) {
+ _objectIdAtCursor = ani->_id;
+
+ if (!selId && ani->_id >= _minCursorId && ani->_id <= _maxCursorId) {
+ selId = _objectIdCursors[ani->_id - _minCursorId];
+ if (selId) {
+ _cursorId = selId;
+ return;
+ }
+ }
+ if (canInteractAny(_aniMan, ani, selId)) {
+ _cursorId = selId > 0 ? PIC_CSR_ITN_INV : PIC_CSR_ITN;
+ return;
+ }
+ if (selId) {
+ _cursorId = PIC_CSR_DEFAULT_INV;
+ return;
+ }
+ if (_objectIdAtCursor == ANI_LIFTBUTTON && lift_getButtonIdP(((StaticANIObject *)ani)->_statics->_staticsId)) {
+ _cursorId = PIC_CSR_LIFT;
+ return;
+ }
+ if (_sceneRect.right - _mouseVirtX < 47 && _sceneRect.right < _sceneWidth - 1) {
+ _cursorId = PIC_CSR_GOFAR_R;
+ return;
+ }
+ if (_mouseVirtX - _sceneRect.left < 47 && _sceneRect.left > 0) {
+ _cursorId = PIC_CSR_GOFAR_L;
+ return;
+ }
+ _cursorId = PIC_CSR_DEFAULT;
+ return;
+ } else {
+ _objectIdAtCursor = 0;
+
+ if (selId) {
+ _cursorId = PIC_CSR_DEFAULT_INV;
+ return;
+ }
+ if (_sceneRect.right - _mouseVirtX < 47 && _sceneRect.right < _sceneWidth - 1) {
+ _cursorId = PIC_CSR_GOFAR_R;
+ return;
+ }
+ if (_mouseVirtX - _sceneRect.left < 47 && _sceneRect.left > 0) {
+ _cursorId = PIC_CSR_GOFAR_L;
+ return;
+ }
+ }
+
+ _cursorId = PIC_CSR_DEFAULT;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/input.h b/engines/fullpipe/input.h
new file mode 100644
index 0000000000..bfd547ae2f
--- /dev/null
+++ b/engines/fullpipe/input.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INPUT_H
+#define FULLPIPE_INPUT_H
+
+namespace Fullpipe {
+
+class Picture;
+
+void setInputDisabled(bool state);
+
+struct CursorInfo {
+ int pictureId;
+ Picture *picture;
+ int hotspotX;
+ int hotspotY;
+ int itemPictureOffsX;
+ int itemPictureOffsY;
+ int width;
+ int height;
+
+ CursorInfo();
+ CursorInfo(CursorInfo *src);
+};
+
+typedef Common::Array<CursorInfo *> CursorsArray;
+
+class InputController {
+ //CObject obj;
+ int _flag;
+ int _inputFlags;
+ int _cursorHandle;
+ int _hCursor;
+ int _field_14;
+ int _cursorId;
+ int _cursorIndex;
+ CursorsArray _cursorsArray;
+ Common::Rect _cursorBounds;
+ Picture *_cursorItemPicture;
+
+ public:
+ InputController();
+ ~InputController();
+
+ void setInputDisabled(bool state);
+ void addCursor(CursorInfo *cursor);
+ void setCursorMode(bool mode);
+
+ void drawCursor(int x, int y);
+ void setCursor(int id);
+
+ void setCursorItemPicture(Picture *pic) { _cursorItemPicture = pic; }
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INPUT_H */
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
new file mode 100644
index 0000000000..b513d2b8ee
--- /dev/null
+++ b/engines/fullpipe/interaction.cpp
@@ -0,0 +1,528 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/motion.h"
+
+namespace Fullpipe {
+
+int handleObjectInteraction(StaticANIObject *subject, GameObject *object, int invId) {
+ return getGameLoaderInteractionController()->handleInteraction(subject, object, invId);
+}
+
+bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
+ int sceneId = 0;
+
+ if (g_fullpipe->_currentScene)
+ sceneId = g_fullpipe->_currentScene->_sceneId;
+
+ InteractionController *intC = getGameLoaderInteractionController();
+ for (ObList::iterator i = intC->_interactions.begin(); i != intC->_interactions.end(); ++i) {
+ Interaction *intr = (Interaction *)*i;
+
+ if (intr->_sceneId > 0 && intr->_sceneId != sceneId)
+ break;
+
+ if (invId == -3) {
+ invId = getGameLoaderInventory()->getSelectedItemId();
+ }
+ if (intr->canInteract(obj1, obj2, invId))
+ return true;
+ }
+ return false;
+}
+
+bool InteractionController::load(MfcArchive &file) {
+ debug(5, "InteractionController::load()");
+
+ return _interactions.load(file);
+}
+
+int static_compSceneId = 0;
+
+bool InteractionController::compareInteractions(const void *p1, const void *p2) {
+ const Interaction *i1 = (const Interaction *)p1;
+ const Interaction *i2 = (const Interaction *)p2;
+
+ if (i2->_sceneId < i1->_sceneId) {
+ if (i1->_sceneId != static_compSceneId)
+ return false;
+ }
+ if (i2->_sceneId != i1->_sceneId) {
+ if (i1->_sceneId > 0 && i2->_sceneId == static_compSceneId)
+ return false;
+ if (i2->_sceneId != i1->_sceneId)
+ return true;
+ }
+ if (i2->_objectId3 == -1)
+ return true;
+
+ if (i1->_objectId3 == i2->_objectId3)
+ return true;
+
+ if (i1->_objectId3 == -1 || i1->_objectId3 == -2)
+ return false;
+
+ return true;
+}
+
+void InteractionController::sortInteractions(int sceneId) {
+ static_compSceneId = sceneId;
+
+ Common::sort(_interactions.begin(), _interactions.end(), InteractionController::compareInteractions);
+}
+
+bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject *obj, int invId) {
+ if (subj) {
+ if (!subj->isIdle() || (subj->_flags & 0x100))
+ return false;
+ }
+
+ if (!_interactions.size())
+ return false;
+
+ Interaction *inter = 0;
+ Interaction *previnter = 0;
+ int dur = 0;
+ int mindur = 0xFFFF;
+
+ MessageQueue *mq;
+ ExCommand *ex;
+
+ for (ObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+ Interaction *cinter = (Interaction *)*i;
+
+ if (!cinter->canInteract(subj, obj, invId))
+ continue;
+
+ if ((inter || cinter->_objectId2) && (!obj || cinter->_objectId3 != obj->_id)) {
+ if (cinter->_messageQueue)
+ cinter->_messageQueue->calcDuration(subj);
+
+ PicAniInfo aniInfo;
+
+ obj->getPicAniInfo(&aniInfo);
+
+ if (cinter->_staticsId1) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+ ani->_messageQueueId = 0;
+ ani->changeStatics2(cinter->_staticsId1);
+ }
+ int xpos = cinter->_xOffs + obj->_ox;
+ int ypos = cinter->_yOffs + obj->_oy;
+
+ obj->setPicAniInfo(&aniInfo);
+
+ if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1) {
+ mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->doWalkTo(subj, xpos, ypos, 1, cinter->_staticsId2);
+ if (mq) {
+ dur = mq->calcDuration(subj);
+ delete mq;
+ } else {
+ dur = 0x10000;
+ }
+ inter = previnter;
+ } else {
+ dur = 0;
+ }
+ if (dur < mindur) {
+ inter = cinter;
+ mindur = dur;
+ previnter = cinter;
+ }
+ } else {
+ inter = cinter;
+ break;
+ }
+ }
+
+ if (!inter)
+ return false;
+
+ if (!inter->_objectId2) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (!ani->isIdle())
+ return false;
+
+ if (ani->_flags & 0x100)
+ return false;
+
+ if (!inter->_staticsId1 || !(inter->_flags & 1))
+ goto LABEL_38;
+
+ if (ani->_movement || ani->_statics == 0 || ani->_statics->_staticsId != inter->_staticsId1) {
+ mq = ani->changeStatics1(inter->_staticsId1);
+ if (!mq)
+ return false;
+
+ ex = new ExCommand((subj ? subj->_id : 0), 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = obj->_id;
+ ex->_y = obj->_okeyCode;
+ ex->_keyCode = subj ? subj->_okeyCode : 0;
+ ex->_excFlags = 3;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ ex->_field_20 = invId;
+ mq->_exCommands.push_back(ex);
+
+ if (mq->_isFinished) {
+ mq->_isFinished = 0;
+ ani->queueMessageQueue(mq);
+ }
+ } else {
+ if (ani->getMessageQueue())
+ ani->queueMessageQueue(0);
+LABEL_38:
+ if (inter->_messageQueue) {
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+ mq->changeParam28ForObjectId(ani->_id, -1, ani->_okeyCode);
+
+ if (!mq->chain(0))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (obj && !subj)
+ return true;
+
+ if (!obj || inter->_objectId3 == obj->_id) {
+ if (subj) {
+ if (inter->_messageQueue) {
+ if (subj->isIdle()) {
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+
+ if (!mq->chain(subj)) {
+ delete mq;
+
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ if (inter->isOverlapping(subj, obj)) {
+ if (obj->_objtype == kObjTypeStaticANIObject) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ ani->queueMessageQueue(0);
+
+ if (inter->_staticsId1)
+ ani->changeStatics2(inter->_staticsId1);
+
+ if (!(inter->_flags & 0x10000))
+ obj->_flags |= 0x80;
+ }
+
+ if (!inter->_messageQueue)
+ return false;
+
+ subj->setOXY(inter->_xOffs + obj->_ox, inter->_yOffs + obj->_oy);
+
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+ mq->changeParam28ForObjectId(obj->_id, -1, obj->_okeyCode);
+ mq->_flags |= 1;
+
+ if (!(inter->_flags & 0x10000)) {
+ ex = new ExCommand(obj->_id, 34, 0x80, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = obj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ }
+
+ ex = new ExCommand(obj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = obj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(subj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = subj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(subj->_id, 17, 0x40, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = 0;
+ mq->_exCommands.push_back(ex);
+
+ if (!mq->chain(subj)) {
+ delete mq;
+
+ return false;
+ }
+
+ subj->_flags |= 1;
+ obj->_flags |= 1;
+ } else {
+ bool someFlag = false;
+ PicAniInfo aniInfo;
+
+ obj->getPicAniInfo(&aniInfo);
+
+ if (obj->_objtype == kObjTypeStaticANIObject && inter->_staticsId1) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ ani->_messageQueueId = 0;
+ ani->changeStatics2(inter->_staticsId1);
+ }
+
+ int xpos = inter->_yOffs + obj->_ox;
+ int ypos = inter->_yOffs + obj->_oy;
+
+ obj->setPicAniInfo(&aniInfo);
+
+ if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1
+ || (inter->_staticsId2 != 0 && (subj->_statics == 0 || subj->_statics->_staticsId != inter->_staticsId2))) {
+ mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->method34(subj, xpos, ypos, 1, inter->_staticsId2);
+
+ if (!mq)
+ return false;
+
+ ex = new ExCommand(subj->_id, 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = obj->_id;
+ ex->_y = obj->_okeyCode;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags = 3;
+ ex->_field_20 = invId;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ mq->_exCommands.push_back(ex);
+
+ someFlag = true;
+
+ ex = new ExCommand(subj->_id, 17, 0x40, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = xpos;
+ ex->_y = ypos;
+ ex->_excFlags |= 3;
+ ex->_keyCode = 6;
+ ex->_field_14 = obj->_id;
+ ex->_field_20 = obj->_okeyCode;
+ ex->postMessage();
+ }
+
+ if (!inter->_staticsId1 || !(inter->_flags & 1))
+ return true;
+
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (!ani->isIdle())
+ return false;
+
+ if (ani->getMessageQueue())
+ ani->queueMessageQueue(0);
+
+ if (!ani->_statics || ani->_statics->_staticsId != inter->_staticsId1 || ani->_movement) {
+ mq = ani->changeStatics1(inter->_staticsId1);
+
+ if (!mq)
+ return false;
+
+ if (someFlag) {
+ if (!(inter->_flags & 0x10000)) {
+ if (mq->_isFinished) {
+ ani->_flags |= 0x80u;
+ } else {
+ ex = new ExCommand(ani->_id, 34, 0x80, 0, 0, 0, 1, 0, 0, 0);
+ ex->_field_14 = 0x80;
+ ex->_keyCode = ani->_okeyCode;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ }
+ }
+ ex = new ExCommand(ani->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = ani->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ } else {
+ ex = new ExCommand(subj->_id, 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = ani->_id;
+ ex->_y = ani->_okeyCode;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags = 2;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ ex->_field_20 = invId;
+ mq->_exCommands.push_back(ex);
+
+ if (!mq->_isFinished)
+ return true;
+
+ mq->_isFinished = 0;
+ ani->queueMessageQueue(mq);
+ }
+ } else {
+ obj->_flags |= 1;
+
+ if (inter->_flags & 0x10000)
+ return true;
+
+ obj->_flags |= 0x80;
+ }
+ }
+
+ return true;
+}
+
+Interaction *InteractionController::getInteractionByObjectIds(int obId, int obId2, int obId3) {
+ for (ObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+ Interaction *intr = (Interaction *)*i;
+
+ if (intr->_objectId1 == obId && intr->_objectId2 == obId2 && intr->_objectId3 == obId3)
+ return intr;
+ }
+
+ return 0;
+}
+
+Interaction::Interaction() {
+ _objectId1 = 0;
+ _objectId2 = 0;
+ _staticsId1 = 0;
+ _objectId3 = 0;
+ _objectState2 = 0;
+ _objectState1 = 0;
+ _messageQueue = 0;
+ _flags = 0;
+ _yOffs = 0;
+ _xOffs = 0;
+ _staticsId2 = 0;
+ _field_28 = 0;
+ _sceneId = -1;
+ _actionName = 0;
+}
+
+bool Interaction::load(MfcArchive &file) {
+ debug(5, "Interaction::load()");
+
+ _objectId1 = file.readUint16LE();
+ _objectId2 = file.readUint16LE();
+ _staticsId1 = file.readUint16LE();
+ _staticsId2 = file.readUint16LE();
+ _objectId3 = file.readUint16LE();
+ _objectState2 = file.readUint32LE();
+ _objectState1 = file.readUint32LE();
+ _xOffs = file.readUint32LE();
+ _yOffs = file.readUint32LE();
+ _sceneId = file.readUint32LE();
+ _flags = file.readUint32LE();
+ _actionName = file.readPascalString();
+
+ _messageQueue = (MessageQueue *)file.readClass();
+
+ return true;
+}
+
+bool Interaction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
+ if (_sceneId > 0 && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId != _sceneId)
+ return false;
+
+ if (_flags & 0x20000)
+ return false;
+
+ if (!obj2)
+ return false;
+
+ if (obj2->_id != _objectId1)
+ return false;
+
+ if ((_flags & 8) && (_flags & 1)) {
+ if (obj2->_objtype != kObjTypeStaticANIObject)
+ return false;
+
+ StaticANIObject *st = (StaticANIObject *)obj2;
+
+ if (!st->_statics)
+ return false;
+
+ if (st->_statics->_staticsId != _staticsId1) {
+ if (_staticsId1)
+ return false;
+ }
+ }
+
+ if ((_objectId3 != invId && _objectId3 != -1 && _objectId3 != -2) || (!invId && _objectId3 == -2))
+ return false;
+
+ if (_objectState1) {
+ if (_flags & 0x10) {
+ if ((g_fullpipe->getObjectState(obj1->getName()) & _objectState1) == 0)
+ return false;
+ } else {
+ if (g_fullpipe->getObjectState(obj1->getName()) != _objectState1)
+ return false;
+ }
+ }
+
+ if (_objectState2) {
+ if (_flags & 0x10) {
+ if ((g_fullpipe->getObjectState(obj2->getName()) & _objectState2) == 0)
+ return false;
+ } else {
+ if (g_fullpipe->getObjectState(obj2->getName()) != _objectState2)
+ return false;
+ }
+ }
+
+ if (_objectId2 && (!obj1 || _objectId2 != obj1->_id))
+ return false;
+
+ return true;
+}
+
+bool Interaction::isOverlapping(StaticANIObject *subj, GameObject *obj) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (abs(_xOffs + obj->_ox - subj->_ox) <= 1
+ && abs(obj->_oy + _yOffs - subj->_oy) <= 1) {
+ if (!_staticsId2 || (subj->_statics != 0 && subj->_statics->_staticsId == _staticsId2)) {
+ if (!_staticsId1 || !(_flags & 1) || (ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool EntranceInfo::load(MfcArchive &file) {
+ debug(5, "EntranceInfo::load()");
+
+ _sceneId = file.readUint32LE();
+ _field_4 = file.readUint32LE();
+ _messageQueueId = file.readUint32LE();
+ file.read(_gap_C, 292); // FIXME, Ugh
+ _field_130 = file.readUint32LE();
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/interaction.h b/engines/fullpipe/interaction.h
new file mode 100644
index 0000000000..456b35458b
--- /dev/null
+++ b/engines/fullpipe/interaction.h
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INTERACTION_H
+#define FULLPIPE_INTERACTION_H
+
+#include "fullpipe/utils.h"
+
+namespace Fullpipe {
+
+class GameObject;
+class MessageQueue;
+class StaticANIObject;
+
+int handleObjectInteraction(StaticANIObject *subject, GameObject *object, int invId);
+bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId);
+
+
+class Interaction : public CObject {
+ public:
+ int16 _objectId1;
+ int16 _objectId2;
+ int16 _objectId3;
+ int16 _staticsId1;
+ int16 _staticsId2;
+ int _objectState1;
+ int _objectState2;
+ int _xOffs;
+ int _yOffs;
+ MessageQueue *_messageQueue;
+ int _sceneId;
+ int _field_28;
+ int _flags;
+ char *_actionName;
+
+ public:
+ Interaction();
+ virtual bool load(MfcArchive &file);
+ bool canInteract(GameObject *obj1, GameObject *obj2, int invId);
+ bool isOverlapping(StaticANIObject *subj, GameObject *obj);
+};
+
+class InteractionController : public CObject {
+ public:
+ ObList _interactions;
+ int16 _field_20;
+ bool _flag24;
+
+ private:
+ static bool compareInteractions(const void *p1, const void *p2);
+
+ public:
+ InteractionController() : _field_20(0), _flag24(true) {}
+
+ virtual bool load(MfcArchive &file);
+
+ void enableFlag24() { _flag24 = true; }
+ void disableFlag24() { _flag24 = false; }
+
+ void sortInteractions(int sceneId);
+
+ bool handleInteraction(StaticANIObject *subj, GameObject *obj, int invId);
+
+ Interaction *getInteractionByObjectIds(int obId, int obId2, int obId3);
+};
+
+struct EntranceInfo {
+ int32 _sceneId;
+ int32 _field_4;
+ int32 _messageQueueId;
+ byte _gap_C[292]; // FIXME
+ int32 _field_130;
+
+ bool load(MfcArchive &file);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INTERACTION_H */
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
new file mode 100644
index 0000000000..18ef3c4d97
--- /dev/null
+++ b/engines/fullpipe/inventory.cpp
@@ -0,0 +1,437 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/utils.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/input.h"
+
+namespace Fullpipe {
+
+bool Inventory::load(MfcArchive &file) {
+ debug(5, "Inventory::load()");
+
+ _sceneId = file.readUint16LE();
+ int numInvs = file.readUint32LE();
+
+ for (int i = 0; i < numInvs; i++) {
+ InventoryPoolItem *t = new InventoryPoolItem();
+ t->id = file.readUint16LE();
+ t->pictureObjectNormal = file.readUint16LE();
+ t->pictureObjectId1 = file.readUint16LE();
+ t->pictureObjectHover = file.readUint16LE();
+ t->pictureObjectSelected = file.readUint16LE();
+ t->flags = file.readUint32LE();
+ t->field_C = 0;
+ t->field_A = -536;
+ _itemsPool.push_back(t);
+ }
+
+ return true;
+}
+
+int Inventory::getInventoryPoolItemIndexById(int itemId) {
+ if (_itemsPool.size() <= 0)
+ return -1;
+
+ for (uint i = 0; i < _itemsPool.size(); i++) {
+ if (_itemsPool[i]->id == itemId)
+ return i;
+ }
+
+ return 0;
+}
+
+bool Inventory::setItemFlags(int itemId, int flags) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ if (idx < 0)
+ return false;
+ else
+ _itemsPool[idx]->flags = flags;
+
+ return true;
+}
+
+Inventory2::Inventory2() {
+ _selectedId = -1;
+ _field_48 = -1;
+ _scene = 0;
+ _picture = 0;
+ _isInventoryOut = false;
+ _isLocked = 0;
+ _topOffset = -65;
+}
+
+bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartially
+ int numInvs = file.readUint32LE();
+
+ for (int i = 0; i < numInvs; i++) {
+ InventoryItem *t = new InventoryItem();
+ t->itemId = file.readUint16LE();
+ t->count = file.readUint16LE();
+ _inventoryItems.push_back(t);
+ }
+
+ return true;
+}
+
+void Inventory2::addItem(int itemId, int count) {
+ if (getInventoryPoolItemIndexById(itemId) >= 0)
+ _inventoryItems.push_back(new InventoryItem(itemId, count));
+}
+
+void Inventory2::addItem2(StaticANIObject *obj) {
+ if (getInventoryPoolItemIndexById(obj->_id) >= 0 && getInventoryPoolItemFieldCById(obj->_id) != 2) {
+ addItem(obj->_id, 1);
+ obj->hide();
+ }
+}
+
+void Inventory2::removeItem(int itemId, int count) {
+ warning("STUB: Inventory2::removeItem(%d, %d)", itemId, count);
+}
+
+void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority) {
+ warning("STUB: void removeItem2(sc, %d, %d, %d, %d)", itemId, x, y, priority);
+}
+
+int Inventory2::getCountItemsWithId(int itemId) {
+ int res = 0;
+
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ if (_inventoryItems[i]->itemId == itemId)
+ res += _inventoryItems[i]->count;
+ }
+
+ return res;
+}
+
+int Inventory2::getInventoryItemIndexById(int itemId) {
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ if (_inventoryItems[i]->itemId == itemId)
+ return i;
+ }
+
+ return -1;
+}
+
+int Inventory2::getInventoryPoolItemIdAtIndex(int itemId) {
+ return _itemsPool[itemId]->id;
+}
+
+int Inventory2::getInventoryPoolItemFieldCById(int itemId) {
+ for (uint i = 0; i < _itemsPool.size(); i++) {
+ if (_itemsPool[i]->id == itemId)
+ return _itemsPool[i]->field_C;
+ }
+
+ return 0;
+}
+
+int Inventory2::getItemFlags(int itemId) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ if (idx < 0)
+ return 0;
+
+ return _itemsPool[idx]->flags;
+}
+
+void Inventory2::rebuildItemRects() {
+ _scene = g_fullpipe->accessScene(_sceneId);
+
+ if (!_scene)
+ return;
+
+ _picture = _scene->getBigPicture(0, 0);
+ _picture->setAlpha(50);
+
+ int itemX = 9;
+ int itemY = 0;
+
+ for (uint i = 0; i < _scene->_picObjList.size(); i++) {
+ PictureObject *pic = (PictureObject *)_scene->_picObjList[i];
+
+ for (uint j = 0; j < _itemsPool.size(); j++) {
+ if (_itemsPool[j]->pictureObjectNormal == pic->_id) {
+ if (pic->_okeyCode)
+ _scene->deletePictureObject(pic);
+ else
+ pic->_flags &= 0xFFFB;
+ }
+ }
+ }
+
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ Common::Point point;
+
+ int idx = getInventoryPoolItemIndexById(_inventoryItems[i]->itemId);
+
+ InventoryIcon *icn = new InventoryIcon();
+
+ icn->inventoryItemId = _itemsPool[idx]->id;
+
+ icn->pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0);
+ icn->pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
+ icn->pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
+
+ icn->pictureObjectNormal->getDimensions(&point);
+
+ if (_itemsPool[idx]->flags & 0x10000) {
+ icn->x1 = 730;
+ icn->y1 = itemY;
+ icn->x2 = point.x + 730;
+ icn->y2 = point.y + itemY + 10;
+ } else {
+ icn->x1 = itemX;
+ icn->y1 = itemY;
+ icn->x2 = itemX + point.x;
+ itemX = icn->x2 + 1;
+ icn->y2 = point.y + itemY + 10;
+ }
+
+ _inventoryIcons.push_back(icn);
+
+ if (itemX >= 2 * (icn->x1 - icn->x2) + 800) {
+ itemX = 9;
+ itemY = icn->y2 + 1;
+ }
+ }
+}
+
+void Inventory2::draw() {
+ if (!_scene)
+ return;
+
+ int oldScLeft = g_fullpipe->_sceneRect.left;
+ int oldScTop = g_fullpipe->_sceneRect.top;
+
+ g_fullpipe->_sceneRect.top = -_topOffset;
+ g_fullpipe->_sceneRect.left = 0;
+
+ _picture->draw(-1, -1, 0, 0);
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ InventoryIcon *icn = _inventoryIcons[i];
+
+ if (icn->isSelected) {
+ icn->pictureObjectSelected->drawAt(icn->x1, icn->y1 + 10);
+ } else {
+ if (icn->isMouseHover)
+ icn->pictureObjectHover->drawAt(icn->x1, icn->y1 + 10);
+ else
+ icn->pictureObjectNormal->drawAt(icn->x1, icn->y1 + 10);
+ }
+ }
+
+ if (!_isInventoryOut)
+ goto LABEL_30;
+
+ int v10, v11, v12;
+
+ if (_topOffset != -10) {
+ if (_topOffset < -10) {
+ v10 = -10;
+ goto LABEL_13;
+ }
+ if (_topOffset + 10 >= 20) {
+ v11 = -20;
+cont:
+ _topOffset += v11;
+ goto reset;
+ }
+ v12 = -10;
+ goto LABEL_25;
+ }
+ if (!_isInventoryOut) {
+LABEL_30:
+ if (_topOffset != -65) {
+ if (_topOffset < -65) {
+ v10 = -65;
+LABEL_13:
+ v11 = v10 - _topOffset;
+ if (v11 >= 20)
+ v11 = 20;
+ goto cont;
+ }
+ if (_topOffset + 65 >= 20) {
+ v11 = -20;
+ goto cont;
+ }
+ v12 = -65;
+LABEL_25:
+ v11 = v12 - _topOffset;
+ goto cont;
+ }
+ }
+
+reset:
+
+ g_fullpipe->_sceneRect.top = oldScTop;
+ g_fullpipe->_sceneRect.left = oldScLeft;
+
+}
+
+void Inventory2::slideIn() {
+ _isInventoryOut = false;
+
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_2C = 10;
+ ex->_field_14 = _isInventoryOut;
+ ex->_field_20 = !_isInventoryOut;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+}
+
+void Inventory2::slideOut() {
+ _isInventoryOut = true;
+
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_2C = 10;
+ ex->_field_14 = _isInventoryOut;
+ ex->_field_20 = !_isInventoryOut;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+}
+
+bool Inventory2::handleLeftClick(ExCommand *cmd) {
+ if (!_isInventoryOut)
+ return false;
+
+ bool res = false;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ if (cmd->_x >= _inventoryIcons[i]->x1 && cmd->_x <= _inventoryIcons[i]->x2 &&
+ cmd->_y >= _inventoryIcons[i]->y1 && cmd->_y <= _inventoryIcons[i]->y2) {
+ if (getSelectedItemId()) {
+ if (getSelectedItemId() != _inventoryIcons[i]->inventoryItemId)
+ unselectItem(0);
+ }
+ if (getItemFlags(_inventoryIcons[i]->inventoryItemId) & 1) {
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+ ex->_field_2C = 11;
+ ex->_field_14 = _inventoryIcons[i]->inventoryItemId;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+ }
+ if (!(getItemFlags(_inventoryIcons[i]->inventoryItemId) & 2)) {
+ selectItem(_inventoryIcons[i]->inventoryItemId);
+ _inventoryIcons[i]->isSelected = true;
+ }
+ res = true;
+ }
+ }
+
+ if (!res)
+ unselectItem(0);
+
+ return res;
+}
+
+int Inventory2::selectItem(int itemId) {
+ if (getInventoryItemIndexById(itemId) < 0)
+ return -1;
+
+ unselectItem(0);
+
+ _selectedId = itemId;
+
+ if (_scene) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture;
+ g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(pic);
+ }
+
+ return _selectedId;
+}
+
+bool Inventory2::unselectItem(bool flag) {
+ if (_selectedId < 0)
+ return false;
+
+ _selectedId = -1;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ if (_inventoryIcons[i]->isSelected)
+ _inventoryIcons[i]->isSelected = false;
+ }
+
+ g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(0);
+
+ return true;
+}
+
+int Inventory2::getHoveredItem(Common::Point *point) {
+ int selId = getSelectedItemId();
+
+ if (point->y <= 20 && !_isInventoryOut && !_isLocked)
+ slideOut();
+
+ if (!selId && point->y >= 55) {
+ if (!_isInventoryOut)
+ return 0;
+
+ if (!_isLocked)
+ slideIn();
+ }
+
+ if (!_isInventoryOut)
+ return 0;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ InventoryIcon *icn = _inventoryIcons[i];
+ if (selId ||
+ point->x < icn->x1 ||
+ point->x > icn->x2 ||
+ point->y < _topOffset + icn->y1 ||
+ point->y > _topOffset + icn->y2) {
+ icn->isMouseHover = false;
+ } else {
+ icn->isMouseHover = true;
+ return icn->inventoryItemId;
+ }
+ }
+
+ return 0;
+}
+
+void FullpipeEngine::getAllInventory() {
+ Inventory2 *inv = getGameLoaderInventory();
+
+ for (uint i = 0; i < inv->getItemsPoolCount(); ++i ) {
+ int id = inv->getInventoryPoolItemIdAtIndex(i);
+
+ if (inv->getCountItemsWithId(id) < 1)
+ inv->addItem(id, 1);
+ }
+
+ inv->rebuildItemRects();
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h
new file mode 100644
index 0000000000..6d07f069bd
--- /dev/null
+++ b/engines/fullpipe/inventory.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INVENTORY_H
+#define FULLPIPE_INVENTORY_H
+
+namespace Fullpipe {
+
+class Scene;
+class BigPicture;
+
+struct InventoryPoolItem {
+ int16 id;
+ int16 pictureObjectNormal;
+ int16 pictureObjectId1;
+ int16 pictureObjectHover;
+ int16 pictureObjectSelected;
+ int16 field_A;
+ int field_C;
+ int obj;
+ int flags;
+};
+
+typedef Common::Array<InventoryPoolItem *> InventoryPoolItems;
+
+class Inventory : public CObject {
+ protected:
+ int16 _sceneId;
+ InventoryPoolItems _itemsPool;
+
+ public:
+ Inventory() { _sceneId = 0; }
+ virtual bool load(MfcArchive &file);
+
+ int getInventoryPoolItemIndexById(int itemId);
+ uint getItemsPoolCount() { return _itemsPool.size(); }
+ bool setItemFlags(int itemId, int flags);
+};
+
+struct InventoryItem {
+ int16 itemId;
+ int16 count;
+
+ InventoryItem() { itemId = count = 0; }
+ InventoryItem(int id, int cnt) : itemId(id), count(cnt) {}
+};
+
+typedef Common::Array<InventoryItem *> InventoryItems;
+
+class PictureObject;
+
+struct InventoryIcon {
+ PictureObject *pictureObjectNormal;
+ PictureObject *pictureObjectHover;
+ PictureObject *pictureObjectSelected;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int16 inventoryItemId;
+ bool isSelected;
+ bool isMouseHover;
+};
+
+typedef Common::Array<InventoryIcon *> InventoryIcons;
+
+class Inventory2 : public Inventory {
+ InventoryItems _inventoryItems;
+ InventoryIcons _inventoryIcons;
+ int _selectedId;
+ int _field_48;
+ bool _isInventoryOut;
+ bool _isLocked;
+ int _topOffset;
+ Scene *_scene;
+ BigPicture *_picture;
+
+ public:
+ Inventory2();
+ bool loadPartial(MfcArchive &file);
+ void addItem(int itemId, int count);
+ void addItem2(StaticANIObject *obj);
+ void removeItem(int itemId, int count);
+ void removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority);
+
+ int getInventoryItemIndexById(int itemId);
+ int getInventoryPoolItemIdAtIndex(int itemId);
+ int getInventoryPoolItemFieldCById(int itemId);
+ int getCountItemsWithId(int itemId);
+ int getItemFlags(int itemId);
+
+ void rebuildItemRects();
+
+ Scene *getScene() { return _scene; }
+ bool getIsLocked() { return _isLocked; }
+ void setIsLocked(bool val) { _isLocked = val; }
+ bool getIsInventoryOut() { return _isInventoryOut; }
+
+ int getSelectedItemId() { return _selectedId < 0 ? 0 : _selectedId; }
+ int getHoveredItem(Common::Point *point);
+ void slideIn();
+ void slideOut();
+
+ bool handleLeftClick(ExCommand *cmd);
+ int selectItem(int itemId);
+ bool unselectItem(bool flag);
+
+ void draw();
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INVENTORY_H */
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
new file mode 100644
index 0000000000..1d6d986977
--- /dev/null
+++ b/engines/fullpipe/lift.cpp
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+int FullpipeEngine::lift_getButtonIdP(int objid) {
+ switch (objid) {
+ case ST_LBN_0N:
+ return ST_LBN_0P;
+ break;
+ case ST_LBN_1N:
+ return ST_LBN_1P;
+ break;
+ case ST_LBN_2N:
+ return ST_LBN_2P;
+ break;
+ case ST_LBN_3N:
+ return ST_LBN_3P;
+ break;
+ case ST_LBN_4N:
+ return ST_LBN_4P;
+ break;
+ case ST_LBN_5N:
+ return ST_LBN_5P;
+ break;
+ case ST_LBN_6N:
+ return ST_LBN_6P;
+ break;
+ case ST_LBN_7N:
+ return ST_LBN_7P;
+ break;
+ case ST_LBN_8N:
+ return ST_LBN_8P;
+ break;
+ case ST_LBN_9N:
+ return ST_LBN_9P;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+void FullpipeEngine::lift_setButton(const char *name, int state) {
+ GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+
+ if (var)
+ var->setSubVarAsInt(name, state);
+}
+
+void FullpipeEngine::lift_sub5(Scene *sc, int qu1, int qu2) {
+ warning("STUB: FullpipeEngine::lift_sub5()");
+}
+
+void FullpipeEngine::lift_exitSeq(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::lift_exitSeq()");
+}
+
+void FullpipeEngine::lift_closedoorSeq() {
+ warning("STUB: FullpipeEngine::lift_closedoorSeq()");
+}
+
+void FullpipeEngine::lift_animation3() {
+ warning("STUB: FullpipeEngine::lift_animation3()");
+}
+
+void FullpipeEngine::lift_goAnimation() {
+ warning("STUB: FullpipeEngine::lift_goAnimation()");
+}
+
+void FullpipeEngine::lift_sub1(StaticANIObject *ani) {
+ warning("STUB: FullpipeEngine::lift_sub1()");
+}
+
+void FullpipeEngine::lift_startExitQueue() {
+ warning("STUB: FullpipeEngine::lift_startExitQueue()");
+}
+
+void FullpipeEngine::lift_sub05(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::lift_sub05()");
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
new file mode 100644
index 0000000000..fc57109f07
--- /dev/null
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -0,0 +1,743 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/messages.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+void global_messageHandler_KickStucco() {
+ warning("STUB: global_messageHandler_KickStucco()");
+}
+
+void global_messageHandler_KickMetal() {
+ warning("STUB: global_messageHandler_KickMetal()");
+}
+
+int global_messageHandler1(ExCommand *cmd) {
+ debug(0, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum);
+
+ if (cmd->_excFlags & 0x10000) {
+ if (cmd->_messageNum == MV_MAN_TOLADDER)
+ cmd->_messageNum = MV_MAN_TOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STARTLADDER)
+ cmd->_messageNum = MV_MAN_STARTLADDER2;
+ if (cmd->_messageNum == MV_MAN_GOLADDER)
+ cmd->_messageNum = MV_MAN_GOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STOPLADDER)
+ cmd->_messageNum = MV_MAN_STOPLADDER2;
+ }
+
+ if (g_fullpipe->_inputDisabled) {
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 36:
+ case 106:
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case MSG_MANSHADOWSON:
+ g_fullpipe->_aniMan->_shadowsOn = 1;
+ break;
+ case MSG_HMRKICK_STUCCO:
+ global_messageHandler_KickStucco();
+ break;
+ case MSG_MANSHADOWSOFF:
+ g_fullpipe->_aniMan->_shadowsOn = 0;
+ break;
+ case MSG_DISABLESAVES:
+ g_fullpipe->disableSaves(cmd);
+ break;
+ case MSG_ENABLESAVES:
+ g_fullpipe->enableSaves();
+ break;
+ case MSG_HMRKICK_METAL:
+ global_messageHandler_KickMetal();
+ break;
+ case 29: // left mouse
+ if (g_fullpipe->_inventoryScene) {
+ if (getGameLoaderInventory()->handleLeftClick(cmd))
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 107: // right mouse
+ if (getGameLoaderInventory()->getSelectedItemId()) {
+ getGameLoaderInventory()->unselectItem(0);
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 36: // keydown
+ g_fullpipe->defHandleKeyDown(cmd->_keyCode);
+
+ switch (cmd->_keyCode) {
+ case '\x1B': // ESC
+ if (g_fullpipe->_currentScene) {
+ getGameLoaderInventory()->unselectItem(0);
+ g_fullpipe->openMainMenu();
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 't':
+ g_fullpipe->stopAllSounds();
+ cmd->_messageKind = 0;
+ break;
+ case 'u':
+ g_fullpipe->toggleMute();
+ cmd->_messageKind = 0;
+ break;
+ case ' ':
+ if (getGameLoaderInventory()->getIsLocked()) {
+ if (getGameLoaderInventory()->getIsInventoryOut()) {
+ getGameLoaderInventory()->setIsLocked(0);
+ }
+ } else {
+ getGameLoaderInventory()->slideOut();
+ getGameLoaderInventory()->setIsLocked(1);
+ }
+ break;
+ case '\t':
+ if (g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openMap();
+ cmd->_messageKind = 0;
+ break;
+ case 'p':
+ if (g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openHelp();
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 33:
+ if (!g_fullpipe->_inventoryScene)
+ break;
+
+ int invItem;
+
+ if (g_fullpipe->_updateFlag && (invItem = g_fullpipe->_inventory->getHoveredItem(&g_fullpipe->_mouseScreenPos))) {
+ g_fullpipe->_cursorId = PIC_CSR_ITN;
+ if (!g_fullpipe->_currSelectedInventoryItemId && !g_fullpipe->_aniMan->_movement &&
+ !(g_fullpipe->_aniMan->_flags & 0x100) && g_fullpipe->_aniMan->isIdle()) {
+ int st = g_fullpipe->_aniMan->_statics->_staticsId;
+ ExCommand *newex = 0;
+
+ if (st == ST_MAN_RIGHT) {
+ newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, rMV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ } else if (st == (0x4000 | ST_MAN_RIGHT)) {
+ newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, MV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ }
+
+ if (newex) {
+ newex->_keyCode = g_fullpipe->_aniMan->_okeyCode;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+ }
+ }
+
+ if (g_fullpipe->_currSelectedInventoryItemId != invItem)
+ g_fullpipe->playSound(SND_CMN_070, 0);
+
+ g_fullpipe->_currSelectedInventoryItemId = invItem;
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+ break;
+ }
+ if (g_fullpipe->_updateCursorCallback)
+ g_fullpipe->_updateCursorCallback();
+
+ g_fullpipe->_currSelectedInventoryItemId = 0;
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+ break;
+ case 65: // open map
+ if (cmd->_field_2C == 11 && cmd->_field_14 == ANI_INV_MAP && g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openMap();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (cmd->_messageKind == 56) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ ExCommand *newex = new ExCommand(0, 35, SND_CMN_031, 0, 0, 0, 1, 0, 0, 0);
+
+ newex->_field_14 = 1;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+
+ return 1;
+ } else if (cmd->_messageKind == 57) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void staticANIObjectCallback(int *arg) {
+ (*arg)--;
+}
+
+int global_messageHandler2(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ int res = 0;
+ StaticANIObject *ani;
+
+ switch (cmd->_messageNum) {
+ case 0x44c8:
+ error("0x44c8");
+ // Unk3_sub_4477A0(&unk3, _parentId, _field_14 != 0);
+ break;
+
+ case 28:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani)
+ ani->_priority = cmd->_field_14;
+ break;
+
+ case 25:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ if (cmd->_field_14) {
+ ani->setFlags40(true);
+ ani->_callback2 = staticANIObjectCallback;
+ } else {
+ ani->setFlags40(false);
+ ani->_callback2 = 0;
+ }
+ }
+ break;
+
+ case 26:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ Movement *mov = ani->_movement;
+ if (mov)
+ mov->_currDynamicPhase->_field_68 = 0;
+ }
+ break;
+
+ default:
+#if 0
+ // We never put anything into _defMsgArray
+ while (::iterator it = g_fullpipe->_defMsgArray.begin(); it != g_fullpipe->_defMsgArray.end(); ++it)
+ if (((ExCommand *)*it)->_field_24 == _messageNum) {
+ ((ExCommand *)*it)->firef34(v13);
+ res = 1;
+ }
+#endif
+
+ //debug_msg(_messageNum);
+
+ if (!g_fullpipe->_soundEnabled || cmd->_messageNum != 33 || g_fullpipe->_currSoundListCount <= 0)
+ return res;
+
+ for (int snd = 0; snd < g_fullpipe->_currSoundListCount; snd++) {
+ SoundList *s = g_fullpipe->_currSoundList1[snd];
+ int ms = s->getCount();
+ for (int i = 0; i < ms; i++) {
+ s->getSoundByIndex(i)->setPanAndVolumeByStaticAni();
+ }
+ }
+ }
+
+ return res;
+}
+
+int global_messageHandler3(ExCommand *cmd) {
+ int result = 0;
+
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 36:
+ if (g_fullpipe->_inputDisabled)
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ StaticANIObject *ani, *ani2;
+
+ switch (cmd->_messageKind) {
+ case 17:
+ switch (cmd->_messageNum) {
+ case 61:
+ return g_fullpipe->_gameLoader->preloadScene(cmd->_parentId, cmd->_keyCode);
+ case 62:
+ return g_fullpipe->_gameLoader->gotoScene(cmd->_parentId, cmd->_keyCode);
+ case 64:
+ if (g_fullpipe->_currentScene && g_fullpipe->_msgObjectId2
+ && (!(cmd->_keyCode & 4) || g_fullpipe->_msgObjectId2 != cmd->_field_14 || g_fullpipe->_msgId != cmd->_field_20)) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_msgObjectId2, g_fullpipe->_msgId);
+ if (ani) {
+ ani->_flags &= 0xFF7F;
+ ani->_flags &= 0xFEFF;
+ ani->deleteFromGlobalMessageQueue();
+ }
+ }
+ g_fullpipe->_msgX = 0;
+ g_fullpipe->_msgY = 0;
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgId = 0;
+ if ((cmd->_keyCode & 1) || (cmd->_keyCode & 2)) {
+ g_fullpipe->_msgX = cmd->_x;
+ g_fullpipe->_msgY = cmd->_y;
+ }
+ if (cmd->_keyCode & 4) {
+ g_fullpipe->_msgObjectId2 = cmd->_field_14;
+ g_fullpipe->_msgId = cmd->_field_20;
+ }
+ return result;
+ case 29:
+ if (!g_fullpipe->_currentScene)
+ return result;
+
+ if (g_fullpipe->_gameLoader->_interactionController->_flag24) {
+ ani = g_fullpipe->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ ani2 = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (ani) {
+ if (g_fullpipe->_msgObjectId2 == ani->_id && g_fullpipe->_msgId == ani->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (canInteractAny(ani2, ani, cmd->_keyCode)) {
+ handleObjectInteraction(ani2, ani, cmd->_keyCode);
+ return 1;
+ }
+ } else {
+ int id = g_fullpipe->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fullpipe->_currentScene->getPictureObjectById(id, 0);
+ if (pic) {
+ if (g_fullpipe->_msgObjectId2 == pic->_id && g_fullpipe->_msgId == pic->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (!ani2 || canInteractAny(ani2, pic, cmd->_keyCode)) {
+ if (!ani2 || (ani2->isIdle() && !(ani2->_flags & 0x80) && !(ani2->_flags & 0x100)))
+ handleObjectInteraction(ani2, pic, cmd->_keyCode);
+ return 1;
+ }
+ }
+ }
+ }
+ if (getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->_isEnabled && cmd->_keyCode <= 0) {
+ if (g_fullpipe->_msgX != cmd->_sceneClickX || g_fullpipe->_msgY != cmd->_sceneClickY) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (!ani || (ani->isIdle() && !(ani->_flags & 0x80) && !(ani->_flags & 0x100))) {
+ result = startWalkTo(g_fullpipe->_gameLoader->_field_FA, -1, cmd->_sceneClickX, cmd->_sceneClickY, 0);
+ if (result) {
+ ExCommand *ex = new ExCommand(g_fullpipe->_gameLoader->_field_FA, 17, 64, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = 1;
+ ex->_excFlags |= 3;
+ ex->_x = cmd->_sceneClickX;
+ ex->_y = cmd->_sceneClickY;
+ ex->postMessage();
+ }
+ }
+ } else {
+ cmd->_messageKind = 0;
+ }
+ }
+ return result;
+ default:
+ return result;
+ }
+ case 58:
+ g_fullpipe->setCursor(cmd->_keyCode);
+ return result;
+ case 59:
+ setInputDisabled(1);
+ return result;
+ case 60:
+ setInputDisabled(0);
+ return result;
+ case 56:
+ if (cmd->_field_2C) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ getGameLoaderInventory()->addItem2(ani);
+ result = 1;
+ }
+ } else {
+ result = 1;
+ getGameLoaderInventory()->addItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return result;
+ case 57:
+ if (cmd->_field_2C) {
+ if (!cmd->_field_20) {
+ getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, cmd->_x, cmd->_y, cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (ani) {
+ getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, ani->_ox + cmd->_x, ani->_oy + cmd->_y, ani->_priority + cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ } else {
+ getGameLoaderInventory()->removeItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ case 55:
+ if (g_fullpipe->_currentScene) {
+ GameObject *obj;
+ if (cmd->_field_14)
+ obj = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_x, cmd->_y);
+ else
+ obj = g_fullpipe->_currentScene->getPictureObjectById(cmd->_x, cmd->_y);
+ handleObjectInteraction(g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode), obj, cmd->_field_20);
+ result = 1;
+ }
+ return result;
+ case 51:
+ return startWalkTo(cmd->_parentId, cmd->_keyCode, cmd->_x, cmd->_y, cmd->_field_20);
+ case 52:
+ return doSomeAnimation(cmd->_parentId, cmd->_keyCode, cmd->_field_20);
+ case 53:
+ return doSomeAnimation2(cmd->_parentId, cmd->_keyCode);
+ case 63:
+ if (cmd->_objtype == kObjTypeObjstateCommand) {
+ ObjstateCommand *c = (ObjstateCommand *)cmd;
+ result = 1;
+ g_fullpipe->setObjectState(c->_objCommandName, c->_value);
+ }
+ return result;
+ default:
+ return result;
+ }
+}
+
+int global_messageHandler4(ExCommand *cmd) {
+ StaticANIObject *ani = 0;
+
+ switch (cmd->_messageKind) {
+ case 18: {
+ MessageQueue *mq = new MessageQueue(g_fullpipe->_currentScene->getMessageQueueById(cmd->_messageNum), cmd->_parId, 0);
+
+ if (cmd->_excFlags & 1)
+ mq->_flag1 = 1;
+ else
+ mq->_flag1 = 0;
+
+ mq->sendNextCommand();
+ break;
+ }
+ case 2:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->trySetMessageQueue(cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 1: {
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ if (cmd->_excFlags & 1)
+ ani->startAnim(cmd->_messageNum, 0, flags);
+ else
+ ani->startAnim(cmd->_messageNum, cmd->_parId, flags);
+
+ break;
+ }
+ case 8:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->startAnimEx(cmd->_messageNum, cmd->_parId, -1, -1);
+ break;
+
+ case 20: {
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ ExCommand2 *cmd2 = (ExCommand2 *)cmd;
+
+ if (cmd->_excFlags & 1) {
+ ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ } else {
+ ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ }
+ break;
+ }
+ case 21:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->queueMessageQueue(0);
+ ani->playIdle();
+ break;
+ case 9:
+ // Nop in original
+ break;
+ case 3:
+ g_fullpipe->_currentScene->_y = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ break;
+
+ case 4:
+ g_fullpipe->_currentScene->_x = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ break;
+
+ case 19: {
+ if (!g_fullpipe->_currentScene)
+ break;
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ MessageQueue *mq = ani->getMessageQueue();
+ MessageQueue *mq2 = ani->changeStatics1(cmd->_messageNum);
+
+ if (!mq2 || !mq2->getExCommandByIndex(0) || !mq)
+ break;
+
+ mq2->_parId = mq->_id;
+ mq2->_flag1 = (cmd->_field_24 == 0);
+ break;
+ }
+ case 22:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags |= 4;
+ ani->changeStatics2(cmd->_messageNum);
+ break;
+
+ case 6:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->hide();
+ break;
+
+ case 27:
+ if (!g_fullpipe->_currentScene || g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode) == 0) {
+ ani = g_fullpipe->accessScene(cmd->_field_20)->getStaticANIObject1ById(cmd->_parentId, -1);
+ if (ani) {
+ ani = new StaticANIObject(ani);
+ g_fullpipe->_currentScene->addStaticANIObject(ani, 1);
+ }
+ }
+
+ // fall through
+ case 5:
+ if (g_fullpipe->_currentScene)
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show1(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 10:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show2(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 7: {
+ if (!g_fullpipe->_currentScene->_picObjList.size())
+ break;
+
+ int offX = g_fullpipe->_scrollSpeed * (cmd->_x / g_fullpipe->_scrollSpeed);
+ int offY = g_fullpipe->_scrollSpeed * (cmd->_y / g_fullpipe->_scrollSpeed);
+
+ if (cmd->_messageNum) {
+ g_fullpipe->_currentScene->_x = offX - g_fullpipe->_sceneRect.left;
+ g_fullpipe->_currentScene->_y = offY - g_fullpipe->_sceneRect.top;
+
+ if (cmd->_field_24) {
+ g_fullpipe->_currentScene->_messageQueueId = cmd->_parId;
+ }
+ } else {
+ g_fullpipe->_sceneRect.moveTo(offX, offY);
+
+ g_fullpipe->_currentScene->_x = 0;
+ g_fullpipe->_currentScene->_y = 0;
+
+ g_fullpipe->_currentScene->updateScrolling2();
+ }
+ break;
+ }
+ case 34:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags = cmd->_messageNum | (ani->_flags & ~cmd->_field_14);
+
+ break;
+
+ case 35:
+ global_messageHandler_handleSound(cmd);
+ break;
+
+ case 11:
+ case 12:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+int MovGraph_messageHandler(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ if (cmd->_messageNum != 33)
+ return 0;
+
+ StaticANIObject *ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+
+ if (!getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId))
+ return 0;
+
+ if (getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->_objtype != kObjTypeMovGraph || !ani)
+ return 0;
+
+ MovGraph *gr = (MovGraph *)getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId);
+
+ MovGraphLink *link = 0;
+ double mindistance = 1.0e10;
+ Common::Point point;
+
+ for (ObList::iterator i = gr->_links.begin(); i != gr->_links.end(); ++i) {
+ point.x = ani->_ox;
+ point.y = ani->_oy;
+
+ double dst = gr->calcDistance(&point, (MovGraphLink *)(*i), 0);
+ if (dst >= 0.0 && dst < mindistance) {
+ mindistance = dst;
+ link = (MovGraphLink *)(*i);
+ }
+ }
+
+ int top;
+
+ if (link) {
+ MovGraphNode *node = link->_movGraphNode1;
+
+ double sq = (ani->_oy - node->_y) * (ani->_oy - node->_y) + (ani->_ox - node->_x) * (ani->_ox - node->_x);
+ int off = (node->_field_14 >> 16) & 0xFF;
+ double off2 = ((link->_movGraphNode2->_field_14 >> 8) & 0xff) - off;
+
+ top = off + (int)(sqrt(sq) * off2 / link->_distance);
+ } else {
+ top = (gr->calcOffset(ani->_ox, ani->_oy)->_field_14 >> 8) & 0xff;
+ }
+
+ if (ani->_movement) {
+ ani->_movement->_currDynamicPhase->_rect->top = 255 - top;
+ return 0;
+ }
+
+ if (ani->_statics)
+ ani->_statics->_rect->top = 255 - top;
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
new file mode 100644
index 0000000000..4abf2ef56f
--- /dev/null
+++ b/engines/fullpipe/messages.cpp
@@ -0,0 +1,791 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/statics.h"
+
+namespace Fullpipe {
+
+ExCommand::ExCommand() {
+ _field_3C = 1;
+ _messageNum = 0;
+ _excFlags = 0;
+ _parId = 0;
+}
+
+ExCommand::ExCommand(ExCommand *src) : Message(src) {
+ _field_3C = 1;
+ _messageNum = src->_messageNum;
+ _excFlags = src->_excFlags;
+ _parId = src->_parId;
+
+}
+
+ExCommand::ExCommand(int16 parentId, int messageKind, int messageNum, int x, int y, int a7, int a8, int sceneClickX, int sceneClickY, int a11) :
+ Message(parentId, messageKind, x, y, a7, a8, sceneClickX, sceneClickY, a11) {
+ _field_3C = 1;
+ _messageNum = messageNum;
+ _excFlags = 0;
+ _parId = 0;
+}
+
+bool ExCommand::load(MfcArchive &file) {
+ debug(5, "ExCommand::load()");
+
+ _parentId = file.readUint16LE();
+ _messageKind = file.readUint32LE();
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _field_14 = file.readUint32LE();
+ _sceneClickX = file.readUint32LE();
+ _sceneClickY = file.readUint32LE();
+ _field_20 = file.readUint32LE();
+ _field_24 = file.readUint32LE();
+ _keyCode = file.readUint32LE();
+ _field_2C = file.readUint32LE();
+ _field_30 = file.readUint32LE();
+ _field_34 = file.readUint32LE();
+
+ _messageNum = file.readUint32LE();
+
+ _field_3C = 0;
+
+ if (g_fullpipe->_gameProjectVersion >= 12) {
+ _excFlags = file.readUint32LE();
+ _parId = file.readUint32LE();
+ }
+
+ return true;
+}
+
+bool ExCommand::handleMessage() {
+ int cnt = 0;
+ for (MessageHandler *m = g_fullpipe->_messageHandlers; m; m = m->nextItem)
+ cnt += m->callback(this);
+
+ if (_messageKind == 17 || (_excFlags & 1)) {
+ if (_parId) {
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+ if (mq)
+ mq->update();
+ }
+ }
+
+ if (_excFlags & 2)
+ delete this;
+
+ return (cnt > 0);
+}
+
+void ExCommand::sendMessage() {
+ g_fullpipe->_exCommandList.push_back(this);
+
+ processMessages();
+}
+
+void ExCommand::postMessage() {
+ g_fullpipe->_exCommandList.push_back(this);
+}
+
+void ExCommand::handle() {
+ if (g_fullpipe->_modalObject) {
+ g_fullpipe->_modalObject->handleMessage(this);
+
+ delete this;
+ } else {
+ postMessage();
+ }
+}
+
+Message::Message() {
+ _messageKind = 0;
+ _parentId = 0;
+
+ _x = 0;
+ _y = 0;
+ _field_14 = 0;
+ _sceneClickX = 0;
+ _sceneClickY = 0;
+ _field_20 = 0;
+ _field_24 = 0;
+ _keyCode = 0;
+ _field_2C = 0;
+ _field_30 = 0;
+ _field_34 = 0;
+}
+
+Message::Message(Message *src) {
+ _parentId = src->_parentId;
+ _messageKind = src->_messageKind;
+ _x = src->_x;
+ _y = src->_y;
+ _field_14 = src->_field_14;
+ _sceneClickX = src->_sceneClickX;
+ _sceneClickY = src->_sceneClickY;
+ _field_20 = src->_field_20;
+ _field_24 = src->_field_24;
+ _keyCode = src->_keyCode;
+ _field_2C = src->_field_2C;
+ _field_30 = src->_field_30;
+ _field_34 = src->_field_34;
+}
+
+Message::Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10) {
+ _messageKind = messageKind;
+ _parentId = parentId;
+ _x = x;
+ _y = y;
+ _field_14 = a6;
+ _sceneClickX = sceneClickX;
+ _sceneClickY = sceneClickY;
+ _field_24 = a7;
+ _field_20 = a10;
+ _keyCode = 0;
+ _field_2C = 0;
+ _field_30 = 0;
+ _field_34 = 0;
+}
+
+ObjstateCommand::ObjstateCommand() {
+ _value = 0;
+ _objCommandName = 0;
+}
+
+bool ObjstateCommand::load(MfcArchive &file) {
+ debug(5, "ObjStateCommand::load()");
+
+ _objtype = kObjTypeObjstateCommand;
+
+ _cmd.load(file);
+
+ _value = file.readUint32LE();
+
+ _objCommandName = file.readPascalString();
+
+ return true;
+}
+
+MessageQueue::MessageQueue() {
+ _field_14 = 0;
+ _parId = 0;
+ _dataId = 0;
+ _id = 0;
+ _isFinished = 0;
+ _flags = 0;
+ _queueName = 0;
+ _counter = 0;
+ _field_38 = 0;
+ _flag1 = 0;
+}
+
+MessageQueue::MessageQueue(int dataId) {
+ _field_14 = 0;
+ _parId = 0;
+ _dataId = dataId;
+ _id = g_fullpipe->_globalMessageQueueList->compact();
+ _isFinished = 0;
+ _flags = 0;
+ _queueName = 0;
+ _counter = 0;
+ _field_38 = 0;
+ _flag1 = 0;
+}
+
+MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
+ _counter = 0;
+ _field_38 = (field_38 == 0);
+
+ for (Common::List<ExCommand *>::iterator it = src->_exCommands.begin(); it != src->_exCommands.end(); ++it) {
+ ExCommand *ex = new ExCommand(*it);
+ ex->_excFlags |= 2;
+
+ _exCommands.push_back(ex);
+ }
+ _field_14 = src->_field_14;
+
+ if (parId)
+ _parId = parId;
+ else
+ _parId = src->_parId;
+
+ _id = g_fullpipe->_globalMessageQueueList->compact();
+ _dataId = src->_dataId;
+ _flags = src->_flags;
+
+ g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+
+ _isFinished = 0;
+ _flag1 = 0;
+}
+
+MessageQueue::~MessageQueue() {
+ for (Common::List<ExCommand *>::iterator it = _exCommands.begin(); it != _exCommands.end(); ++it) {
+ ExCommand *ex = (ExCommand *)*it;
+
+ if (ex && ex->_excFlags & 2)
+ delete ex;
+ }
+
+ _exCommands.clear();
+
+ if (_field_14)
+ delete _field_14;
+
+ if (_flags & 2) {
+ g_fullpipe->_globalMessageQueueList->removeQueueById(_id);
+ }
+
+ finish();
+
+ free(_queueName);
+}
+
+bool MessageQueue::load(MfcArchive &file) {
+ debug(5, "MessageQueue::load()");
+
+ _dataId = file.readUint16LE();
+
+ int count = file.readUint16LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 12);
+
+ _queueName = file.readPascalString();
+
+ for (int i = 0; i < count; i++) {
+ ExCommand *tmp = (ExCommand *)file.readClass();
+
+ _exCommands.push_back(tmp);
+ }
+
+ _id = -1;
+ _field_14 = 0;
+ _parId = 0;
+ _isFinished = 0;
+
+ return true;
+}
+
+bool MessageQueue::chain(StaticANIObject *ani) {
+ if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
+ if (!(getFlags() & 2)) {
+ g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+ _flags |= 2;
+ }
+ if (ani) {
+ ani->queueMessageQueue(this);
+ return true;
+ } else {
+ sendNextCommand();
+ return true;
+ }
+ }
+ return false;
+}
+
+void MessageQueue::update() {
+ if (_counter > 0)
+ _counter--;
+
+ if (_exCommands.size()) {
+ sendNextCommand();
+ } else if (_counter == 0) {
+ _isFinished = 1;
+ finish();
+ }
+}
+
+void MessageQueue::messageQueueCallback1(int par) {
+ // Autosave
+ debug(3, "STUB: MessageQueue::messageQueueCallback1()");
+}
+
+void MessageQueue::addExCommand(ExCommand *ex) {
+ _exCommands.push_front(ex);
+}
+
+ExCommand *MessageQueue::getExCommandByIndex(uint idx) {
+ if (idx > _exCommands.size())
+ return 0;
+
+ Common::List<ExCommand *>::iterator it = _exCommands.begin();
+
+ while (idx) {
+ ++it;
+ idx--;
+ }
+
+ return *it;
+}
+
+void MessageQueue::deleteExCommandByIndex(uint idx, bool doFree) {
+ if (idx > _exCommands.size())
+ return;
+
+ Common::List<ExCommand *>::iterator it = _exCommands.begin();
+
+ while (idx) {
+ ++it;
+ idx--;
+ }
+
+ _exCommands.erase(it);
+
+ if (doFree)
+ delete *it;
+}
+
+void MessageQueue::transferExCommands(MessageQueue *mq) {
+ while (mq->_exCommands.size()) {
+ _exCommands.push_back(mq->_exCommands.front());
+ mq->_exCommands.pop_front();
+ }
+}
+
+void MessageQueue::sendNextCommand() {
+ if (_exCommands.size()) {
+ if (!(_flags & 4) && (_flags & 1)) {
+ messageQueueCallback1(16);
+ }
+ ExCommand *ex = _exCommands.front();
+
+ _exCommands.pop_front();
+
+ _counter++;
+ ex->_parId = _id;
+ ex->_excFlags |= (ex->_field_24 == 0 ? 1 : 0) | (ex->_field_3C != 0 ? 2 : 0);
+
+ _flags |= 4;
+ ex->sendMessage();
+ } else if (_counter <= 0) {
+ _isFinished = 1;
+ finish();
+ }
+}
+
+bool MessageQueue::checkGlobalExCommandList1() {
+ ExCommand *ex, *ex1;
+
+ for (uint i = 0; i < getCount(); i++) {
+ ex = getExCommandByIndex(i);
+
+ if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
+ continue;
+
+ for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end(); it++) {
+ ex1 = *it;
+
+ if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27)
+ continue;
+
+ if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1)
+ continue;
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+
+ if (mq) {
+ if (mq->getFlags() & 1)
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool MessageQueue::checkGlobalExCommandList2() {
+ ExCommand *ex, *ex1;
+
+ for (uint i = 0; i < getCount(); i++) {
+ ex = getExCommandByIndex(i);
+
+ if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
+ continue;
+
+ for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end();) {
+ ex1 = *it;
+
+ if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27) {
+ it++;
+ continue;
+ }
+
+ if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1) {
+ it++;
+ continue;
+ }
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+
+ if (mq) {
+ if (mq->getFlags() & 1)
+ return false;
+
+ delete mq;
+ }
+
+ it = g_fullpipe->_exCommandList.erase(it);
+
+ if (ex1->_excFlags & 2) {
+ delete ex1;
+ }
+ }
+ }
+ return true;
+}
+
+void MessageQueue::finish() {
+ if (!_parId)
+ return;
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+
+ _parId = 0;
+
+ if (!mq)
+ return;
+
+ if (!_flag1) {
+ mq->update();
+ return;
+ }
+
+ mq->_counter--;
+
+ if (!mq->_counter && !mq->_exCommands.size())
+ mq->update();
+}
+
+void MessageQueue::replaceKeyCode(int key1, int key2) {
+ for (uint i = 0; i < getCount(); i++) {
+ ExCommand *ex = getExCommandByIndex(i);
+ int k = ex->_messageKind;
+ if ((k == 1 || k == 20 || k == 5 || k == 6 || k == 2 || k == 18 || k == 19 || k == 22 || k == 55)
+ && ex->_keyCode == key1)
+ ex->_keyCode = key2;
+ }
+}
+
+int MessageQueue::calcDuration(StaticANIObject *obj) {
+ int res = 0;
+ ExCommand *ex;
+ Movement *mov;
+
+ for (uint i = 0; (ex = getExCommandByIndex(i)); i++)
+ if (ex->_parentId == obj->_id) {
+ if (ex->_messageKind == 1 || ex->_messageKind == 20) {
+ if ((mov = obj->getMovementById(ex->_messageNum)) != 0) {
+ if (ex->_field_14 >= 1)
+ res += ex->_field_14;
+ else
+ res += mov->calcDuration();
+ }
+ }
+ }
+
+ return res;
+}
+
+void MessageQueue::changeParam28ForObjectId(int objId, int oldParam28, int newParam28) {
+ for (uint i = 0; i < _exCommands.size(); i++) {
+ ExCommand *ex = getExCommandByIndex(i);
+ int k = ex->_messageKind;
+
+ if ((k == 1 || k == 20 || k == 5 || k == 6 || k == 2 || k == 18 || k == 19 || k == 22 || k == 55)
+ && ex->_keyCode == oldParam28
+ && ex->_parentId == objId)
+ ex->_keyCode = newParam28;
+ }
+}
+
+MessageQueue *GlobalMessageQueueList::getMessageQueueById(int id) {
+ for (Common::Array<MessageQueue *>::iterator s = begin(); s != end(); ++s) {
+ if ((*s)->_id == id)
+ return *s;
+ }
+
+ return 0;
+}
+
+void GlobalMessageQueueList::deleteQueueById(int id) {
+ for (uint i = 0; i < size(); i++)
+ if (_storage[i]->_id == id) {
+ remove_at(i);
+
+ disableQueueById(id);
+ return;
+ }
+}
+
+void GlobalMessageQueueList::removeQueueById(int id) {
+ for (uint i = 0; i < size(); i++)
+ if (_storage[i]->_id == id) {
+ _storage[i]->_flags &= 0xFD; // It is quite pointless
+ remove_at(i);
+
+ disableQueueById(id);
+ return;
+ }
+}
+
+void GlobalMessageQueueList::disableQueueById(int id) {
+ for (Common::Array<MessageQueue *>::iterator s = begin(); s != end(); ++s) {
+ if ((*s)->_parId == id)
+ (*s)->_parId = 0;
+ }
+}
+
+int GlobalMessageQueueList::compact() {
+ for (uint i = 0; i < size();) {
+ if (((MessageQueue *)_storage[i])->_isFinished) {
+ disableQueueById(_storage[i]->_id);
+ remove_at(i);
+ } else {
+ i++;
+ }
+ }
+
+ return size() + 1;
+}
+
+void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
+ msg->setFlags(msg->getFlags() | 2);
+
+ push_back(msg);
+}
+
+void clearGlobalMessageQueueList1() {
+ warning("STUB: clearGlobalMessageQueueList1()");
+}
+
+bool removeMessageHandler(int16 id, int pos) {
+ if (g_fullpipe->_messageHandlers) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *prevItem = 0;
+ int curPos = 0;
+
+ while (id != curItem->id) {
+ prevItem = curItem;
+ curItem = curItem->nextItem;
+ curPos++;
+
+ if (!curItem)
+ return false;
+ }
+
+ if (pos == -1 || curPos == pos) {
+ prevItem->nextItem = curItem->nextItem;
+ delete curItem;
+ updateMessageHandlerIndex(prevItem->nextItem, -1);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void updateMessageHandlerIndex(MessageHandler *msg, int offset) {
+ for (; msg; msg = msg->nextItem)
+ msg->index += offset;
+}
+
+void addMessageHandler(int (*callback)(ExCommand *), int16 id) {
+ if (getMessageHandlerById(id))
+ return;
+
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ if (!curItem)
+ return;
+
+ int index = 0;
+ for (MessageHandler *i = g_fullpipe->_messageHandlers->nextItem; i; i = i->nextItem) {
+ curItem = i;
+ index++;
+ }
+
+ allocMessageHandler(curItem, id, callback, index);
+
+ if (curItem)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+}
+
+MessageHandler *getMessageHandlerById(int16 id) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ if (!curItem)
+ return 0;
+
+ while (id != curItem->id) {
+ curItem = curItem->nextItem;
+
+ if (!curItem)
+ return 0;
+ }
+
+ return curItem;
+}
+
+bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExCommand *), int index) {
+ MessageHandler *msg = new MessageHandler;
+
+ if (where) {
+ msg->nextItem = where->nextItem;
+ where->nextItem = msg;
+ msg->id = id;
+ msg->callback = callback;
+ msg->index = index;
+ } else {
+ msg->nextItem = 0;
+ msg->id = id;
+ msg->callback = callback;
+ msg->index = 0;
+
+ g_fullpipe->_messageHandlers = msg;
+ }
+
+ return true;
+}
+
+int getMessageHandlersCount() {
+ int result;
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (result = 0; curItem; result++)
+ curItem = curItem->nextItem;
+
+ return result;
+}
+
+bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id) {
+ if (getMessageHandlerById(id))
+ return false;
+
+ if (index) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (int i = index - 1; i > 0; i--)
+ if (curItem)
+ curItem = curItem->nextItem;
+
+ if (!curItem)
+ return false;
+
+ bool res = allocMessageHandler(curItem, id, callback, index);
+
+ if (res)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+
+ return res;
+ } else {
+ MessageHandler *newItem = new MessageHandler;
+
+ newItem->nextItem = g_fullpipe->_messageHandlers;
+ newItem->id = id;
+ newItem->callback = callback;
+ newItem->index = 0;
+
+ updateMessageHandlerIndex(g_fullpipe->_messageHandlers, 1);
+ g_fullpipe->_messageHandlers = newItem;
+
+ return true;
+ }
+}
+
+bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id) {
+ if (getMessageHandlerById(id))
+ return false;
+
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (int i = index; i > 0; i--)
+ if (curItem)
+ curItem = curItem->nextItem;
+
+ bool res = allocMessageHandler(curItem, id, callback, index + 1);
+ if (curItem)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+
+ return res;
+}
+
+void clearMessageHandlers() {
+ MessageHandler *curItem;
+ MessageHandler *nextItem;
+
+ curItem = g_fullpipe->_messageHandlers;
+ if (curItem) {
+ do {
+ nextItem = curItem->nextItem;
+
+ delete curItem;
+
+ curItem = nextItem;
+ } while (nextItem);
+
+ g_fullpipe->_messageHandlers = 0;
+ }
+}
+
+void processMessages() {
+ if (!g_fullpipe->_isProcessingMessages) {
+ g_fullpipe->_isProcessingMessages = true;
+
+ while (g_fullpipe->_exCommandList.size()) {
+ ExCommand *ex = g_fullpipe->_exCommandList.front();
+ g_fullpipe->_exCommandList.pop_front();
+ ex->handleMessage();
+ }
+ g_fullpipe->_isProcessingMessages = false;
+ }
+}
+
+void updateGlobalMessageQueue(int id, int objid) {
+ MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(id);
+ if (m) {
+ m->update();
+ }
+}
+
+bool chainQueue(int queueId, int flags) {
+ MessageQueue *mq = g_fullpipe->_currentScene->getMessageQueueById(queueId);
+
+ if (!mq)
+ return false;
+
+ MessageQueue *nmq = new MessageQueue(mq, 0, 0);
+
+ nmq->_flags |= flags;
+
+ if (!mq->chain(0)) {
+ delete mq;
+
+ return false;
+ }
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
new file mode 100644
index 0000000000..326f05cef3
--- /dev/null
+++ b/engines/fullpipe/messages.h
@@ -0,0 +1,181 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_MESSAGEQUEUE_H
+#define FULLPIPE_MESSAGEQUEUE_H
+
+#include "fullpipe/utils.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/sound.h"
+#include "fullpipe/scene.h"
+
+namespace Fullpipe {
+
+class Message : public CObject {
+ public:
+ int _messageKind;
+ int16 _parentId;
+ int _x;
+ int _y;
+ int _field_14;
+ int _sceneClickX;
+ int _sceneClickY;
+ int _field_20;
+ int _field_24;
+ int _keyCode;
+ int _field_2C;
+ int _field_30;
+ int _field_34;
+
+ public:
+ Message();
+ Message(Message *src);
+ virtual ~Message() {}
+
+ Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10);
+};
+
+class ExCommand : public Message {
+ public:
+
+ int _messageNum;
+ int _field_3C;
+ int _excFlags;
+ int _parId;
+
+ ExCommand();
+ ExCommand(ExCommand *src);
+ ExCommand(int16 parentId, int messageKind, int messageNum, int x, int y, int a7, int a8, int sceneClickX, int sceneClickY, int a11);
+ virtual ~ExCommand() {}
+
+ virtual bool load(MfcArchive &file);
+
+ bool handleMessage();
+ void sendMessage();
+ void postMessage();
+ void handle();
+};
+
+class ExCommand2 : public ExCommand {
+ public:
+ Common::Point **_points;
+ int _pointsSize;
+};
+
+class ObjstateCommand : public CObject {
+ public:
+ ExCommand _cmd;
+ char *_objCommandName;
+ int _value;
+
+ public:
+ ObjstateCommand();
+ virtual bool load(MfcArchive &file);
+};
+
+class MessageQueue : public CObject {
+ public:
+ int _id;
+ int _flags;
+ char *_queueName;
+ int16 _dataId;
+ CObject *_field_14;
+ Common::List<ExCommand *> _exCommands;
+ int _counter;
+ int _field_38;
+ int _isFinished;
+ int _parId;
+ int _flag1;
+
+ public:
+ MessageQueue();
+ MessageQueue(int dataId);
+ MessageQueue(MessageQueue *src, int parId, int field_38);
+ virtual ~MessageQueue();
+
+ virtual bool load(MfcArchive &file);
+
+ int getFlags() { return _flags; }
+ void setFlags(int flags) { _flags = flags; }
+
+ uint getCount() { return _exCommands.size(); }
+
+ void addExCommand(ExCommand *ex);
+ ExCommand *getExCommandByIndex(uint idx);
+ void deleteExCommandByIndex(uint idx, bool doFree);
+
+ void transferExCommands(MessageQueue *mq);
+
+ void replaceKeyCode(int key1, int key2);
+
+ bool chain(StaticANIObject *ani);
+ void update();
+ void sendNextCommand();
+ void finish();
+
+ void messageQueueCallback1(int par);
+
+ bool checkGlobalExCommandList1();
+ bool checkGlobalExCommandList2();
+
+ int calcDuration(StaticANIObject *obj);
+ void changeParam28ForObjectId(int objId, int oldParam28, int newParam28);
+};
+
+class GlobalMessageQueueList : public Common::Array<MessageQueue *> {
+ public:
+ MessageQueue *getMessageQueueById(int id);
+ void deleteQueueById(int id);
+ void removeQueueById(int id);
+ void disableQueueById(int id);
+ void addMessageQueue(MessageQueue *msg);
+
+ int compact();
+};
+
+struct MessageHandler {
+ int (*callback)(ExCommand *cmd);
+ int16 id;
+ int16 field_6;
+ int index;
+ MessageHandler *nextItem;
+};
+
+bool removeMessageHandler(int16 id, int pos);
+void updateMessageHandlerIndex(MessageHandler *msg, int offset);
+void addMessageHandler(int (*callback)(ExCommand *), int16 id);
+MessageHandler *getMessageHandlerById(int16 id);
+bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExCommand *), int index);
+int getMessageHandlersCount();
+bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id);
+bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id);
+void clearMessageHandlers();
+void processMessages();
+void updateGlobalMessageQueue(int id, int objid);
+void clearGlobalMessageQueueList1();
+
+bool chainQueue(int queueId, int flags);
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MESSAGEQUEUE_H */
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
new file mode 100644
index 0000000000..f766be3eac
--- /dev/null
+++ b/engines/fullpipe/modal.cpp
@@ -0,0 +1,242 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/gameloader.h"
+
+namespace Fullpipe {
+
+ModalIntro::ModalIntro() {
+ _field_8 = 0;
+ _countDown = 0;
+ _stillRunning = 0;
+
+ if (g_vars->sceneIntro_skipIntro) {
+ _introFlags = 4;
+ } else {
+ _introFlags = 33;
+ _countDown = 150;
+
+ PictureObject *pict = g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0);
+ pict->setFlags(pict->_flags & 0xFFFB);
+ }
+
+ g_vars->sceneIntro_skipIntro = false;
+ _sfxVolume = g_fullpipe->_sfxVolume;
+}
+
+ModalIntro::~ModalIntro() {
+ g_fullpipe->stopAllSounds();
+ g_fullpipe->_sfxVolume = _sfxVolume;
+}
+
+bool ModalIntro::handleMessage(ExCommand *message) {
+ if (message->_messageKind != 17)
+ return false;
+
+ if (message->_messageNum != 36)
+ return false;
+
+ if (message->_keyCode != 13 && message->_keyCode != 27 && message->_keyCode != 32)
+ return false;
+
+ if (_stillRunning) {
+ if (!(_introFlags & 0x10)) {
+ _countDown = 0;
+ g_vars->sceneIntro_needBlackout = true;
+ return true;
+ }
+ g_vars->sceneIntro_playing = false;
+ g_vars->sceneIntro_needBlackout = true;
+ }
+
+ return true;
+}
+
+bool ModalIntro::init(int counterdiff) {
+ if (!g_vars->sceneIntro_playing) {
+ if (!_stillRunning) {
+ finish();
+ return false;
+ }
+
+ if (_introFlags & 0x10)
+ g_fullpipe->_gameLoader->updateSystems(42);
+
+ _introFlags |= 2;
+
+ return true;
+ }
+
+ if (_introFlags & 4) {
+ ModalVideoPlayer *player = new ModalVideoPlayer();
+
+ g_fullpipe->_modalObject = player;
+ player->_parentObj = this;
+ player->play("intro.avi");
+
+ _countDown--;
+
+ if (_countDown > 0 )
+ return true;
+
+ if (_stillRunning <= 0) {
+ _countDown = 0;
+ _stillRunning = 0;
+ _introFlags = (_introFlags & 0xfb) | 0x40;
+
+ return true;
+ }
+
+ _introFlags |= 2;
+ return true;
+ }
+
+ if (_introFlags & 0x40) {
+ ModalVideoPlayer *player = new ModalVideoPlayer();
+
+ g_fullpipe->_modalObject = player;
+ player->_parentObj = this;
+ player->play("intro2.avi");
+
+ _countDown--;
+ if (_countDown > 0)
+ return true;
+
+ if (_stillRunning <= 0) {
+ _countDown = 50;
+ _stillRunning = 0;
+ _introFlags = (_introFlags & 0xbf) | 9;
+
+ return true;
+ }
+
+ _introFlags |= 2;
+ return true;
+ }
+
+ if (_introFlags & 8) {
+ _countDown--;
+
+ if (_countDown > 0 )
+ return true;
+
+ if (_stillRunning > 0) {
+ _introFlags |= 2;
+ return true;
+ }
+
+ _countDown = 150;
+ _introFlags = (_introFlags & 0xf7) | 0x21;
+ g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
+ }
+
+ if (!(_introFlags & 0x20)) {
+ if (_introFlags & 0x10) {
+ if (!_stillRunning) {
+ _introFlags |= 1;
+
+ g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
+ g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
+
+ chainQueue(QU_INTR_STARTINTRO, 1);
+ }
+ g_fullpipe->_gameLoader->updateSystems(42);
+ }
+ return true;
+ }
+
+ _countDown--;
+
+ if (_countDown <= 0) {
+ if (_stillRunning > 0) {
+ _introFlags |= 2;
+
+ return true;
+ }
+
+ _introFlags = (_introFlags & 0xdf) | 0x10;
+
+ g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
+
+ _stillRunning = 0;
+ }
+
+ return true;
+}
+
+void ModalIntro::update() {
+ if (g_fullpipe->_currentScene) {
+ if (_introFlags & 1) {
+ //sceneFade(virt, g_currentScene, 1);
+ _stillRunning = 255;
+ _introFlags &= 0xfe;
+
+ if (_introFlags & 0x20)
+ g_fullpipe->playSound(SND_INTR_019, 0);
+ } else if (_introFlags & 2) {
+ if (g_vars->sceneIntro_needBlackout) {
+ //vrtRectangle(*(_DWORD *)virt, 0, 0, 0, 800, 600);
+ g_vars->sceneIntro_needBlackout = 0;
+ _stillRunning = 0;
+ _introFlags &= 0xfd;
+ } else {
+ //sceneFade(virt, g_currentScene, 0);
+ _stillRunning = 0;
+ _introFlags &= 0xfd;
+ }
+ } else if (_stillRunning) {
+ g_fullpipe->_currentScene->draw();
+ }
+ }
+}
+
+void ModalIntro::finish() {
+ g_fullpipe->_gameLoader->unloadScene(SC_INTRO2);
+ g_fullpipe->_currentScene = g_fullpipe->accessScene(SC_INTRO1);
+ g_fullpipe->_gameLoader->preloadScene(SC_INTRO1, TrubaDown);
+
+ if (g_fullpipe->_currentScene)
+ g_fullpipe->_gameLoader->updateSystems(42);
+}
+
+void ModalVideoPlayer::play(const char *fname) {
+ warning("STUB: ModalVideoPlayer::play(%s)", fname);
+}
+
+void FullpipeEngine::openMap() {
+ warning("STUB: FullpipeEngine::openMap()");
+}
+
+void FullpipeEngine::openHelp() {
+ warning("STUB: FullpipeEngine::openHelp()");
+}
+
+void FullpipeEngine::openMainMenu() {
+ warning("STUB: FullpipeEngine::openMainMenu()");
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
new file mode 100644
index 0000000000..b57d1fbd06
--- /dev/null
+++ b/engines/fullpipe/modal.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_MODAL_H
+#define FULLPIPE_MODAL_H
+
+namespace Fullpipe {
+
+class BaseModalObject {
+ public:
+
+ BaseModalObject *_parentObj;
+
+ public:
+ BaseModalObject() : _parentObj(0) {}
+ virtual ~BaseModalObject() {}
+
+
+ virtual bool pollEvent() = 0;
+ virtual bool handleMessage(ExCommand *message) = 0;
+ virtual bool init(int counterdiff) = 0;
+ virtual void update() = 0;
+
+ virtual void saveload() = 0;
+};
+
+class ModalIntro : public BaseModalObject {
+ int _field_8;
+ int _introFlags;
+ int _countDown;
+ int _stillRunning;
+ int _sfxVolume;
+
+ public:
+ ModalIntro();
+ virtual ~ModalIntro();
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
+ virtual void saveload() {}
+
+ void finish();
+};
+
+class ModalVideoPlayer : public BaseModalObject {
+public:
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message) { return true; }
+ virtual bool init(int counterdiff) { return false; }
+ virtual void update() {}
+ virtual void saveload() {}
+
+ void play(const char *fname);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MODAL_H */
diff --git a/engines/fullpipe/module.mk b/engines/fullpipe/module.mk
new file mode 100644
index 0000000000..88e3ac5d02
--- /dev/null
+++ b/engines/fullpipe/module.mk
@@ -0,0 +1,39 @@
+MODULE := engines/fullpipe
+
+MODULE_OBJS = \
+ behavior.o \
+ detection.o \
+ floaters.o \
+ fullpipe.o \
+ gameloader.o \
+ gfx.o \
+ init.o \
+ input.o \
+ interaction.o \
+ inventory.o \
+ lift.o \
+ messagehandlers.o \
+ messages.o \
+ modal.o \
+ motion.o \
+ ngiarchive.o \
+ scene.o \
+ scenes.o \
+ sound.o \
+ stateloader.o \
+ statics.o \
+ utils.o \
+ scenes/scene01.o \
+ scenes/scene02.o \
+ scenes/scene03.o \
+ scenes/scene04.o \
+ scenes/sceneDbg.o \
+ scenes/sceneIntro.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_FULLPIPE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
new file mode 100644
index 0000000000..f67011a50f
--- /dev/null
+++ b/engines/fullpipe/motion.cpp
@@ -0,0 +1,1611 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/array.h"
+#include "common/list.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/gameloader.h"
+
+namespace Fullpipe {
+
+bool MotionController::load(MfcArchive &file) {
+ // Is originally empty file.readClass();
+
+ debug(5, "MotionController::load()");
+
+ return true;
+}
+
+bool MctlCompound::load(MfcArchive &file) {
+ debug(5, "MctlCompound::load()");
+
+ int count = file.readUint32LE();
+
+ debug(6, "MctlCompound::count = %d", count);
+
+ for (int i = 0; i < count; i++) {
+ debug(6, "CompoundArray[%d]", i);
+ MctlCompoundArrayItem *obj = new MctlCompoundArrayItem();
+
+ obj->_motionControllerObj = (MotionController *)file.readClass();
+
+ int count1 = file.readUint32LE();
+
+ debug(6, "ConnectionPoint::count: %d", count1);
+ for (int j = 0; j < count1; j++) {
+ debug(6, "ConnectionPoint[%d]", j);
+ MctlConnectionPoint *obj1 = (MctlConnectionPoint *)file.readClass();
+
+ obj->_connectionPoints.push_back(obj1);
+ }
+
+ obj->_field_20 = file.readUint32LE();
+ obj->_field_24 = file.readUint32LE();
+
+ debug(6, "graphReact");
+ obj->_movGraphReactObj = (MovGraphReact *)file.readClass();
+
+ _motionControllers.push_back(obj);
+ }
+
+ return true;
+}
+
+void MctlCompound::addObject(StaticANIObject *obj) {
+ for (uint i = 0; i < _motionControllers.size(); i++)
+ _motionControllers[i]->_motionControllerObj->addObject(obj);
+}
+
+int MctlCompound::removeObject(StaticANIObject *obj) {
+ warning("STUB: MctlCompound::removeObject()");
+
+ return 0;
+}
+
+void MctlCompound::initMovGraph2() {
+ if (_objtype != kObjTypeMctlCompound)
+ return;
+
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_motionControllerObj->_objtype != kObjTypeMovGraph)
+ continue;
+
+ MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj;
+
+ MovGraph2 *newgr = new MovGraph2();
+
+ newgr->_links = gr->_links;
+ newgr->_nodes = gr->_nodes;
+
+ gr->_links.clear();
+ gr->_nodes.clear();
+
+ delete gr;
+
+ _motionControllers[i]->_motionControllerObj = newgr;
+ }
+}
+
+void MctlCompound::freeItems() {
+ for (uint i = 0; i < _motionControllers.size(); i++)
+ _motionControllers[i]->_motionControllerObj->freeItems();
+}
+
+MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MctlCompound::method34()");
+
+ return 0;
+}
+
+MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ int match1 = -1;
+ int match2 = -1;
+
+ if (!subj)
+ return 0;
+
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_movGraphReactObj) {
+ if (_motionControllers[i]->_movGraphReactObj->pointInRegion(subj->_ox, subj->_oy)) {
+ match1 = i;
+ break;
+ }
+ }
+ }
+
+ if (match1 == -1)
+ return 0;
+
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_movGraphReactObj) {
+ if (_motionControllers[i]->_movGraphReactObj->pointInRegion(xpos, ypos)) {
+ match2 = i;
+ break;
+ }
+ }
+ }
+
+ if (match2 == -1)
+ return 0;
+
+ if (match1 == match2)
+ return _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId);
+
+ MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &match2);
+
+ if (!closestP)
+ return 0;
+
+ MessageQueue *mq = _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, closestP->_connectionX, closestP->_connectionY, 1, closestP->_field_14);
+
+ ExCommand *ex;
+
+ if (mq) {
+ for (uint i = 0; i < closestP->_messageQueueObj->getCount(); i++) {
+ ex = new ExCommand(closestP->_messageQueueObj->getExCommandByIndex(i));
+ ex->_excFlags |= 2;
+ mq->_exCommands.push_back(ex);
+ }
+
+ ex = new ExCommand(subj->_id, 51, 0, xpos, ypos, 0, 1, 0, 0, 0);
+
+ ex->_field_20 = fuzzyMatch;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags |= 2;
+
+ mq->_exCommands.push_back(ex);
+ }
+
+ return mq;
+}
+
+MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr) {
+ warning("STUB: MctlCompound::findClosestConnectionPoint()");
+
+ return 0;
+}
+
+bool MctlCompoundArray::load(MfcArchive &file) {
+ debug(5, "MctlCompoundArray::load()");
+
+ int count = file.readUint32LE();
+
+ debug(0, "MctlCompoundArray::count = %d", count);
+
+ assert(0);
+
+ return true;
+}
+
+MovGraphItem::MovGraphItem() {
+ ani = 0;
+ field_4 = 0;
+ field_8 = 0;
+ field_C = 0;
+ field_10 = 0;
+ field_14 = 0;
+ field_18 = 0;
+ field_1C = 0;
+ field_20 = 0;
+ field_24 = 0;
+ items = 0;
+ count = 0;
+ field_30 = 0;
+ field_34 = 0;
+ field_38 = 0;
+ field_3C = 0;
+}
+
+int MovGraph_messageHandler(ExCommand *cmd);
+
+int MovGraphCallback(int a1, int a2, int a3) {
+ warning("STUB: MovgraphCallback");
+
+ return 0;
+}
+
+MovGraph::MovGraph() {
+ _callback1 = MovGraphCallback;
+ _field_44 = 0;
+ insertMessageHandler(MovGraph_messageHandler, getMessageHandlersCount() - 1, 129);
+
+ _objtype = kObjTypeMovGraph;
+}
+
+bool MovGraph::load(MfcArchive &file) {
+ debug(5, "MovGraph::load()");
+
+ _links.load(file);
+ _nodes.load(file);
+
+ return true;
+}
+
+void MovGraph::addObject(StaticANIObject *obj) {
+ _mgm.clear();
+ _mgm.addItem(obj->_id);
+
+ for (uint i = 0; i < _items.size(); i++)
+ if (_items[i]->ani == obj)
+ return;
+
+ MovGraphItem *item = new MovGraphItem();
+
+ item->ani = obj;
+
+ _items.push_back(item);
+
+ _mgm.addItem(obj->_id); // FIXME: Is it really needed?
+}
+
+int MovGraph::removeObject(StaticANIObject *obj) {
+ warning("STUB: MovGraph::removeObject()");
+
+ return 0;
+}
+
+void MovGraph::freeItems() {
+ warning("STUB: MovGraph::freeItems()");
+}
+
+int MovGraph::method28() {
+ warning("STUB: MovGraph::method28()");
+
+ return 0;
+}
+
+int MovGraph::method2C() {
+ warning("STUB: MovGraph::method2C()");
+
+ return 0;
+}
+
+MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MovGraph::method34()");
+
+ return 0;
+}
+
+int MovGraph::changeCallback() {
+ warning("STUB: MovGraph::changeCallback()");
+
+ return 0;
+}
+
+int MovGraph::method3C() {
+ warning("STUB: MovGraph::method3C()");
+
+ return 0;
+}
+
+int MovGraph::method44() {
+ warning("STUB: MovGraph::method44()");
+
+ return 0;
+}
+
+MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MovGraph::doWalkTo()");
+
+ return 0;
+}
+
+int MovGraph::method50() {
+ warning("STUB: MovGraph::method50()");
+
+ return 0;
+}
+
+double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) {
+ int n1x = link->_movGraphNode1->_x;
+ int n1y = link->_movGraphNode1->_y;
+ int n2x = link->_movGraphNode2->_x;
+ int n2y = link->_movGraphNode2->_y;
+ double dist1x = (double)(point->x - n1x);
+ double dist1y = (double)(n1y - point->y);
+ double dist2x = (double)(n2x - n1x);
+ double dist2y = (double)(n2y - n1y);
+ double dist1 = sqrt(dist1y * dist1y + dist1x * dist1x);
+ double dist2 = ((double)(n1y - n2y) * dist1y + dist2x * dist1x) / link->_distance / dist1;
+ double distm = dist2 * dist1;
+ double res = sqrt(1.0 - dist2 * dist2) * dist1;
+
+ if (dist2 <= 0.0 || distm >= link->_distance) {
+ if (fuzzyMatch) {
+ if (dist2 > 0.0) {
+ if (distm >= link->_distance) {
+ point->x = n2x;
+ point->y = n2y;
+ }
+ } else {
+ point->x = n1x;
+ point->y = n1y;
+ }
+ } else {
+ return -1.0;
+ }
+ } else {
+ point->x = n1x + (dist2x * distm / link->_distance);
+ point->y = n1y + (dist2y * distm / link->_distance);
+ }
+
+ return res;
+}
+
+void MovGraph::calcNodeDistancesAndAngles() {
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ lnk->_flags &= 0x7FFFFFFF;
+
+ lnk->calcNodeDistanceAndAngle();
+ }
+}
+
+int MovGraph2::getItemIndexByGameObjectId(int objectId) {
+ for (uint i = 0; i < _items2.size(); i++)
+ if (_items2[i]->_objectId == objectId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByStaticsId(int idx, int staticsId) {
+ for (int i = 0; i < 4; i++)
+ if (_items2[idx]->_subItems[i]._staticsId1 == staticsId || _items2[idx]->_subItems[i]._staticsId2 == staticsId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMovementId(int idx, int movId) {
+ for (int i = 0; i < 4; i++)
+ if (_items2[idx]->_subItems[i]._walk[0]._movementId == movId || _items2[idx]->_subItems[i]._turn[0]._movementId == movId ||
+ _items2[idx]->_subItems[i]._turnS[0]._movementId == movId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMGM(int idx, StaticANIObject *ani) {
+ warning("STUB: MovGraph2::getItemSubIndexByMGM()");
+
+ return -1;
+}
+
+bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
+ item->_obj = obj;
+ item->_objectId = obj->_id;
+
+ GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(obj->_objectName);
+ if (!var)
+ return false;
+
+ var = var->getSubVarByName("Test_walk");
+
+ if (!var)
+ return false;
+
+ GameVar *varD = 0;
+ Common::Point point;
+
+ for (int dir = 0; dir < 4; dir++) {
+ switch (dir) {
+ case 0:
+ varD = var->getSubVarByName("Right");
+ break;
+ case 1:
+ varD = var->getSubVarByName("Left");
+ break;
+ case 2:
+ varD = var->getSubVarByName("Up");
+ break;
+ case 3:
+ varD = var->getSubVarByName("Down");
+ break;
+ }
+
+ if (!varD)
+ return false;
+
+ for (int act = 0; act < 3; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("Start");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("Go");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("Stop");
+ break;
+ }
+
+ item->_subItems[dir]._walk[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._walk[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._walk[act]._mx = point.x;
+ item->_subItems[dir]._walk[act]._my = point.y;
+ }
+ }
+
+ for (int act = 0; act < 4; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("TurnR");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("TurnL");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("TurnU");
+ break;
+ case 3:
+ idx = varD->getSubVarAsInt("TurnD");
+ break;
+ }
+
+ item->_subItems[dir]._turn[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._turn[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._turn[act]._mx = point.x;
+ item->_subItems[dir]._turn[act]._my = point.y;
+ }
+ }
+
+ for (int act = 0; act < 4; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("TurnSR");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("TurnSL");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("TurnSU");
+ break;
+ case 3:
+ idx = varD->getSubVarAsInt("TurnSD");
+ break;
+ }
+
+ item->_subItems[dir]._turnS[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._turnS[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._turnS[act]._mx = point.x;
+ item->_subItems[dir]._turnS[act]._my = point.y;
+ }
+ }
+
+ item->_subItems[dir]._staticsId1 = item->_subItems[dir]._walk[0]._mov->_staticsObj1->_staticsId;
+ item->_subItems[dir]._staticsId2 = item->_subItems[dir]._walk[0]._mov->_staticsObj2->_staticsId;
+
+ }
+ return true;
+}
+
+void MovGraph2::addObject(StaticANIObject *obj) {
+ MovGraph::addObject(obj);
+
+ int id = getItemIndexByGameObjectId(obj->_id);
+
+ if (id >= 0) {
+ _items2[id]->_obj = obj;
+ } else {
+ MovGraph2Item *item = new MovGraph2Item;
+
+ if (initDirections(obj, item)) {
+ _items2.push_back(item);
+ } else {
+ delete item;
+ }
+ }
+}
+
+void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) {
+ MovInfo1Sub *elem;
+ Common::Point point;
+ Common::Rect rect;
+
+ int subIndex = movinfo->subIndex;
+
+ movinfo->items.clear();
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = movinfo->pt1.x;
+ elem->y = movinfo->pt1.y;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ int prevSubIndex = movinfo->subIndex;
+
+ for (uint i = 0; i < linkList->size(); i++) {
+ int idx1;
+
+ if (linkList->size() <= 1) {
+ if (linkList->size() == 1)
+ idx1 = getShortSide((*linkList)[0], movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+ else
+ idx1 = getShortSide(0, movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+
+ point.y = -1;
+ rect.bottom = -1;
+ rect.right = -1;
+ rect.top = -1;
+ rect.left = -1;
+ } else {
+ idx1 = findLink(linkList, i, &rect, &point);
+ }
+
+ if (idx1 != prevSubIndex) {
+ prevSubIndex = idx1;
+ subIndex = idx1;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = rect.left;
+ elem->y = rect.top;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+ }
+
+ if (i != linkList->size() - 1) {
+ while (1) {
+ i++;
+ if (findLink(linkList, i, &rect, 0) != prevSubIndex) {
+ i--;
+ findLink(linkList, i, &rect, &point);
+
+ break;
+ }
+
+ if (i == linkList->size() - 1)
+ break;
+ }
+ }
+
+ if (movinfo->items.back()->subIndex != 10) {
+ subIndex = prevSubIndex;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = 10;
+ elem->x = -1;
+ elem->y = -1;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ if (i == linkList->size()) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ } else {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = rect.right;
+ elem->y = rect.bottom;
+ elem->distance = point.y;
+
+ movinfo->items.push_back(elem);
+ }
+ }
+ }
+
+ if (subIndex != movinfo->item1Index) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = movinfo->item1Index;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ }
+
+ movinfo->itemsCount = movinfo->items.size();
+}
+
+MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) {
+ MovInfo1 movinfo;
+
+ memcpy(&movinfo, movInfo, sizeof(movinfo));
+
+ int curX = movInfo->pt1.x;
+ int curY = movInfo->pt1.y;
+ int curDistance = movInfo->distance1;
+
+ MessageQueue *mq = new MessageQueue(g_fullpipe->_globalMessageQueueList->compact());
+
+ for (int i = 0; i < movInfo->itemsCount - 1; i++) {
+ if (movInfo->items[i + 1]->subIndex != 10) {
+ MG2I *mg2i;
+
+ if (i >= movInfo->itemsCount - 2 || movInfo->items[i + 2]->subIndex != 10) {
+ movinfo.flags = 0;
+ mg2i = &_items2[movInfo->field_0]->_subItems[movInfo->items[i]->subIndex]._turnS[movInfo->items[i + 1]->subIndex];
+ } else {
+ movinfo.flags = 2;
+ mg2i = &_items2[movInfo->field_0]->_subItems[movInfo->items[i]->subIndex]._turn[movInfo->items[i + 1]->subIndex];
+ }
+ if (i < movInfo->itemsCount - 2
+ || (movInfo->items[i]->x == movInfo->items[i + 1]->x
+ && movInfo->items[i]->y == movInfo->items[i + 1]->y)
+ || movInfo->items[i]->x == -1
+ || movInfo->items[i]->y == -1
+ || movInfo->items[i + 1]->x == -1
+ || movInfo->items[i + 1]->y == -1) {
+
+ ExCommand *ex = new ExCommand(_items2[movInfo->field_0]->_objectId, 1, mg2i->_movementId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+ ex->_keyCode = _items2[movInfo->field_0]->_obj->_okeyCode;
+ ex->_field_24 = 1;
+ ex->_field_14 = -1;
+ mq->_exCommands.push_back(ex);
+
+ curX += mg2i->_mx;
+ curY += mg2i->_my;
+ } else {
+ MGMInfo mgminfo;
+
+ memset(&mgminfo, 0, sizeof(mgminfo));
+
+ mgminfo.ani = _items2[movInfo->field_0]->_obj;
+ mgminfo.staticsId2 = mg2i->_mov->_staticsObj2->_staticsId;
+ mgminfo.x1 = movInfo->items[i + 1]->x;
+ mgminfo.y1 = movInfo->items[i + 1]->y;
+ mgminfo.field_1C = movInfo->items[i + 1]->distance;
+ mgminfo.staticsId1 = mg2i->_mov->_staticsObj1->_staticsId;
+
+ mgminfo.x2 = movInfo->items[i]->x;
+ mgminfo.y2 = movInfo->items[i]->y;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 0x7f;
+ mgminfo.movementId = mg2i->_movementId;
+
+ MessageQueue *mq2 = _mgm.genMovement(&mgminfo);
+ mq->transferExCommands(mq2);
+
+ delete mq2;
+
+ curX = movInfo->items[i + 1]->x;
+ curY = movInfo->items[i + 1]->y;
+ }
+ } else {
+ movinfo.item1Index = movInfo->items[i]->subIndex;
+ movinfo.subIndex = movinfo.item1Index;
+ movinfo.pt1.y = curY;
+ movinfo.pt1.x = curX;
+
+ movinfo.distance1 = curDistance;
+ movinfo.pt2.x = movInfo->items[i + 2]->x;
+ movinfo.pt2.y = movInfo->items[i + 2]->y;
+ movinfo.distance2 = movInfo->items[i + 2]->distance;
+
+ if (i >= movInfo->itemsCount - 4
+ || movInfo->items[i + 2]->subIndex == 10
+ || movInfo->items[i + 3]->subIndex == 10
+ || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex
+ || movInfo->items[i + 4]->subIndex != 10) {
+ if (i >= movInfo->itemsCount - 3
+ || movInfo->items[i + 2]->subIndex == 10
+ || movInfo->items[i + 3]->subIndex == 10
+ || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex) {
+ movinfo.flags &= 3;
+ } else {
+ MG2I *m = &_items2[movInfo->field_0]->_subItems[movInfo->items[i + 2]->subIndex]._turnS[movInfo->items[i + 3]->subIndex];
+ movinfo.pt2.x -= m->_mx;
+ movinfo.pt2.y -= m->_my;
+ movinfo.flags &= 3;
+ }
+ } else {
+ MG2I *m = &_items2[movInfo->field_0]->_subItems[movInfo->items[i + 2]->subIndex]._turn[movInfo->items[i + 3]->subIndex];
+
+ if (movinfo.item1Index && movinfo.item1Index != 1) {
+ movinfo.pt2.y -= m->_my;
+ movinfo.flags = (movinfo.flags & 2) | 1;
+ } else {
+ movinfo.pt2.x -= m->_mx;
+ movinfo.flags = (movinfo.flags & 2) | 1;
+ }
+ }
+ i++; // intentional
+
+ MessageQueue *mq2 = genMovement(&movinfo);
+
+ if (!mq2) {
+ delete mq;
+ return 0;
+ }
+
+ mq->transferExCommands(mq2);
+
+ delete mq2;
+
+ curX = movinfo.pt2.x;
+ curY = movinfo.pt2.y;
+ curDistance = movinfo.distance2;
+ }
+ }
+
+ movInfo->pt2.x = movinfo.pt2.x;
+ movInfo->pt2.y = movinfo.pt2.y;
+
+ return mq;
+}
+
+int MovGraph2::removeObject(StaticANIObject *obj) {
+ warning("STUB: MovGraph2::removeObject()");
+
+ return 0;
+}
+
+void MovGraph2::freeItems() {
+ warning("STUB: MovGraph2::freeItems()");
+}
+
+MessageQueue *MovGraph2::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ if (!ani->isIdle())
+ return 0;
+
+ if (ani->_flags & 0x100)
+ return 0;
+
+ MessageQueue *mq = doWalkTo(ani, xpos, ypos, fuzzyMatch, staticsId);
+
+ if (!mq)
+ return 0;
+
+ if (ani->_movement) {
+ if (mq->getCount() <= 1 || mq->getExCommandByIndex(0)->_messageKind != 22) {
+ PicAniInfo picAniInfo;
+
+ ani->getPicAniInfo(&picAniInfo);
+ ani->updateStepPos();
+ MessageQueue *mq1 = doWalkTo(ani, xpos, ypos, fuzzyMatch, staticsId);
+
+ ani->setPicAniInfo(&picAniInfo);
+
+ if (mq1) {
+ delete mq;
+
+ mq = mq1;
+ }
+ } else {
+ ani->_movement = 0;
+ }
+ }
+
+ if (!mq->chain(ani)) {
+ delete mq;
+
+ return 0;
+ }
+
+ return mq;
+}
+
+MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ LinkInfo linkInfoDest;
+ LinkInfo linkInfoSource;
+ MovInfo1 movInfo1;
+ PicAniInfo picAniInfo;
+ Common::Point point;
+
+ int idx = getItemIndexByGameObjectId(obj->_id);
+
+ if (idx < 0)
+ return 0;
+
+ linkInfoSource.link = 0;
+ linkInfoSource.node = 0;
+
+ linkInfoDest.link = 0;
+ linkInfoDest.node = 0;
+
+ point.x = 0;
+
+ obj->getPicAniInfo(&picAniInfo);
+
+ int idxsub;
+
+ if (obj->_movement)
+ idxsub = getItemSubIndexByMovementId(idx, obj->_movement->_id);
+ else
+ idxsub = getItemSubIndexByStaticsId(idx, obj->_statics->_staticsId);
+
+ bool subMgm = false;
+
+ if (idxsub == -1) {
+ idxsub = getItemSubIndexByMGM(idx, obj);
+ subMgm = true;
+
+ if (idxsub == -1)
+ return 0;
+ }
+
+ if (obj->_movement) {
+ int newx, newy;
+
+ if (subMgm) {
+ obj->_messageQueueId = 0;
+ obj->changeStatics2(_items2[idx]->_subItems[idxsub]._staticsId1);
+ newx = obj->_ox;
+ newy = obj->_oy;
+ } else {
+ obj->_movement->calcSomeXY(point, 0);
+ newx = obj->_movement->_ox - point.x;
+ newy = obj->_movement->_oy - point.y;
+ if (idxsub != 1 && idxsub) {
+ if (idxsub == 2 || idxsub == 3) {
+ newy = obj->_movement->_oy;
+ }
+ } else {
+ newx = obj->_movement->_ox;
+ }
+ }
+
+ obj->_movement = 0;
+ obj->setOXY(newx, newy);
+ }
+
+ if (obj->_ox == xpos && obj->_oy == ypos) {
+ g_fullpipe->_globalMessageQueueList->compact();
+
+ MessageQueue *mq = new MessageQueue();
+
+ if (staticsId && obj->_statics->_staticsId != staticsId) {
+ int idxwalk = getItemSubIndexByStaticsId(idx, staticsId);
+ if (idxwalk == -1) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ delete mq;
+
+ return 0;
+ }
+
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items2[idx]->_subItems[idxsub]._walk[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_24 = 1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+
+ mq->_exCommands.push_back(ex);
+ } else {
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 22, obj->_statics->_staticsId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 5, -1, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->_exCommands.push_back(ex);
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+ }
+
+ linkInfoSource.node = findNode(obj->_ox, obj->_oy, 0);
+
+ if (!linkInfoSource.node) {
+ linkInfoSource.link = findLink1(obj->_ox, obj->_oy, idxsub, 0);
+
+ if (!linkInfoSource.link) {
+ linkInfoSource.link = findLink2(obj->_ox, obj->_oy);
+
+ if (!linkInfoSource.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+ }
+
+ linkInfoDest.node = findNode(xpos, ypos, fuzzyMatch);
+
+ if (!linkInfoDest.node) {
+ linkInfoDest.link = findLink1(xpos, ypos, idxsub, fuzzyMatch);
+
+ if (!linkInfoDest.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+
+ Common::Array<MovGraphLink *> tempLinkList;
+ double minPath = findMinPath(&linkInfoSource, &linkInfoDest, &tempLinkList);
+
+ debug(0, "MovGraph2::doWalkTo(): path: %g parts: %d", minPath, tempLinkList.size());
+
+ if (minPath < 0.0 || ((linkInfoSource.node != linkInfoDest.node || !linkInfoSource.node) && !tempLinkList.size()))
+ return 0;
+
+ memset(&movInfo1, 0, sizeof(movInfo1));
+
+ movInfo1.subIndex = idxsub;
+ movInfo1.pt1.x = obj->_ox;
+ movInfo1.pt1.y = obj->_oy;
+
+ int dx1 = obj->_ox;
+ int dy1 = obj->_oy;
+ int dx2, dy2;
+
+ if (linkInfoSource.node)
+ movInfo1.distance1 = linkInfoSource.node->_distance;
+ else
+ movInfo1.distance1 = linkInfoSource.link->_movGraphNode1->_distance;
+
+ if (linkInfoDest.node) {
+ dx2 = linkInfoDest.node->_x;
+ dy2 = linkInfoDest.node->_y;
+
+ movInfo1.pt2.x = linkInfoDest.node->_x;
+ movInfo1.pt2.y = linkInfoDest.node->_y;
+
+ movInfo1.distance2 = linkInfoDest.node->_distance;
+ } else {
+ movInfo1.pt2.x = xpos;
+ movInfo1.pt2.y = ypos;
+
+ MovGraphNode *nod = linkInfoDest.link->_movGraphNode1;
+ double dst1 = sqrt((double)((ypos - nod->_y) * (ypos - nod->_y) + (xpos - nod->_x) * (xpos - nod->_x)));
+ int dst = linkInfoDest.link->_movGraphNode2->_distance - nod->_distance;
+
+ movInfo1.distance2 = nod->_distance + (dst1 * (double)dst / linkInfoDest.link->_distance);
+
+ calcDistance(&movInfo1.pt2, linkInfoDest.link, 1);
+
+ dx1 = movInfo1.pt1.x;
+ dy1 = movInfo1.pt1.y;
+ dx2 = movInfo1.pt2.x;
+ dy2 = movInfo1.pt2.y;
+ }
+
+ if (staticsId) {
+ movInfo1.item1Index = getItemSubIndexByStaticsId(idx, staticsId);
+ } else if (tempLinkList.size() <= 1) {
+ if (tempLinkList.size() == 1)
+ movInfo1.item1Index = getShortSide(tempLinkList[0], dx2 - dx1, dy2 - dy1);
+ else
+ movInfo1.item1Index = getShortSide(0, dx2 - dx1, dy2 - dy1);
+ } else {
+ movInfo1.item1Index = findLink(&tempLinkList, tempLinkList.size() - 1, 0, 0);
+ }
+
+ movInfo1.flags = fuzzyMatch != 0;
+
+ if (_items2[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId)
+ movInfo1.flags |= 2;
+
+ buildMovInfo1SubItems(&movInfo1, &tempLinkList, &linkInfoSource, &linkInfoDest);
+
+ MessageQueue *mq = buildMovInfo1MessageQueue(&movInfo1);
+
+ linkInfoDest.node = findNode(movInfo1.pt2.x, movInfo1.pt2.y, fuzzyMatch);
+
+ if (!linkInfoDest.node)
+ linkInfoDest.link = findLink1(movInfo1.pt2.x, movInfo1.pt2.y, movInfo1.item1Index, fuzzyMatch);
+
+ if (fuzzyMatch || linkInfoDest.link || linkInfoDest.node) {
+ if (mq && mq->getCount() > 0 && picAniInfo.movementId) {
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (ex && (ex->_messageKind == 1 || ex->_messageKind == 20)
+ && picAniInfo.movementId == ex->_messageNum
+ && picAniInfo.someDynamicPhaseIndex == ex->_field_14) {
+ mq->deleteExCommandByIndex(0, 1);
+ } else {
+ ex = new ExCommand(picAniInfo.objectId, 5, ex->_messageNum, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+ mq->addExCommand(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 22, _items2[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->addExCommand(ex);
+ }
+ }
+ } else {
+ if (mq)
+ delete mq;
+ mq = 0;
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+}
+
+MovGraphNode *MovGraph2::findNode(int x, int y, int fuzzyMatch) {
+ for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+
+ MovGraphNode *node = (MovGraphNode *)*i;
+
+ if (fuzzyMatch) {
+ if (abs(node->_x - x) < 15 && abs(node->_y - y) < 15)
+ return node;
+ } else {
+ if (node->_x == x && node->_y == y)
+ return node;
+ }
+ }
+
+ return 0;
+}
+
+int MovGraph2::getShortSide(MovGraphLink *lnk, int x, int y) {
+ bool cond;
+
+ if (lnk)
+ cond = abs(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) > abs(lnk->_movGraphNode2->_y - lnk->_movGraphNode1->_y);
+ else
+ cond = abs(x) > abs(y);
+
+ if (cond)
+ return x <= 0;
+ else
+ return ((y > 0) + 2);
+}
+
+int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *rect, Common::Point *point) {
+ MovGraphNode *node1 = (*linkList)[idx]->_movGraphNode1;
+ MovGraphNode *node2 = (*linkList)[idx]->_movGraphNode2;
+ MovGraphNode *node3 = node1;
+
+ if (idx != 0) {
+ MovGraphLink *lnk = (*linkList)[idx - 1];
+
+ if (lnk->_movGraphNode2 != node1) {
+ if (lnk->_movGraphNode1 != node1) {
+ if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node2;
+ node2 = node1;
+ }
+ goto LABEL_7;
+ }
+ }
+ node3 = node1;
+ } else if (idx != (int)(linkList->size() - 1)) {
+ MovGraphLink *lnk = (*linkList)[idx + 1];
+
+ if (lnk->_movGraphNode2 == node1 || lnk->_movGraphNode1 == node1) {
+ node3 = node2;
+ node2 = node1;
+ } else if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node1;
+ }
+ }
+
+ LABEL_7:
+ if (rect) {
+ rect->left = node3->_x;
+ rect->top = node3->_y;
+ rect->right = node2->_x;
+ rect->bottom = node2->_y;
+ }
+ if (point) {
+ point->x = node3->_distance;
+ point->y = node2->_distance;
+ }
+
+ if (abs(node3->_x - node2->_x) <= abs(node3->_y - node2->_y))
+ return (node3->_y < node2->_x) + 2;
+ else
+ return node3->_x >= node2->_x;
+}
+
+MessageQueue *MovGraph2::genMovement(MovInfo1 *movinfo) {
+ warning("STUB: MovGraph2::genMovement()");
+
+ return 0;
+}
+
+MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) {
+ Common::Point point;
+ MovGraphLink *res = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (fuzzyMatch) {
+ point.x = x;
+ point.y = y;
+ double dst = calcDistance(&point, lnk, 0);
+
+ if (dst >= 0.0 && dst < 2.0)
+ return lnk;
+ } else if (!(lnk->_flags & 0x20000000)) {
+ if (lnk->_movGraphReact->pointInRegion(x, y)) {
+ if (abs(lnk->_movGraphNode1->_x - lnk->_movGraphNode2->_x) <= abs(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y)) {
+ if (idx == 2 || idx == 3)
+ return lnk;
+ res = lnk;
+ } else {
+ if (idx == 1 || !idx)
+ return lnk;
+ res = lnk;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+MovGraphLink *MovGraph2::findLink2(int x, int y) {
+ double mindist = 1.0e20;
+ MovGraphLink *res = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (!(lnk->_flags & 0x20000000)) {
+ double n1x = lnk->_movGraphNode1->_x;
+ double n1y = lnk->_movGraphNode1->_y;
+ double n2x = lnk->_movGraphNode2->_x;
+ double n2y = lnk->_movGraphNode2->_y;
+ double n1dx = n1x - x;
+ double n1dy = n1y - y;
+ double dst1 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ double coeff1 = ((n1y - n2y) * n1dy + (n2x - n1x) * n1dx) / lnk->_distance / dst1;
+ double dst3 = coeff1 * dst1;
+ double dst2 = sqrt(1.0 - coeff1 * coeff1) * dst1;
+
+ if (coeff1 * dst1 < 0.0) {
+ dst3 = 0.0;
+ dst2 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ }
+ if (dst3 > lnk->_distance) {
+ dst3 = lnk->_distance;
+ dst2 = sqrt((n2x - x) * (n2x - x) + (n2y - y) * (n2y - y));
+ }
+ if (dst3 >= 0.0 && dst3 <= lnk->_distance && dst2 < mindist) {
+ mindist = dst2;
+ res = lnk;
+ }
+ }
+ }
+
+ if (mindist < 1.0e20)
+ return res;
+ else
+ return 0;
+}
+
+double MovGraph2::findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj) {
+ LinkInfo linkInfoWorkSource;
+
+ if (linkInfoSource->link != linkInfoDest->link || linkInfoSource->node != linkInfoDest->node) {
+ double minDistance = -1.0;
+
+ if (linkInfoSource->node) {
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if ((lnk->_movGraphNode1 == linkInfoSource->node || lnk->_movGraphNode2 == linkInfoSource->node) && !(lnk->_flags & 0xA0000000)) {
+ linkInfoWorkSource.node = 0;
+ linkInfoWorkSource.link = lnk;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ lnk->_flags |= 0x80000000;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0 && (minDistance < 0.0 || newDistance + lnk->_distance < minDistance)) {
+ listObj->clear();
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance + lnk->_distance;
+ }
+
+ lnk->_flags &= 0x7FFFFFFF;
+ }
+ }
+ } else if (linkInfoSource->link) {
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode1;
+ linkInfoWorkSource.link = 0;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0) {
+ listObj->clear();
+
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+
+ linkInfoWorkSource.link = 0;
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode2;
+
+ tmpList.clear();
+
+ newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0 && (minDistance < 0.0 || newDistance < minDistance)) {
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+ }
+
+ return minDistance;
+ } else {
+ if (linkInfoSource->link)
+ listObj->push_back(linkInfoSource->link);
+
+ return 0.0;
+ }
+}
+
+MovGraphNode *MovGraph::calcOffset(int ox, int oy) {
+ MovGraphNode *res = 0;
+ double mindist = 1.0e10;
+
+ for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+
+ MovGraphNode *node = (MovGraphNode *)*i;
+
+ double dist = sqrt((double)((node->_x - oy) * (node->_x - oy) + (node->_x - ox) * (node->_x - ox)));
+ if (dist < mindist) {
+ mindist = dist;
+ res = node;
+ }
+ }
+
+ return res;
+}
+
+void MGM::clear() {
+ _items.clear();
+}
+
+MGMItem::MGMItem() {
+ objId = 0;
+}
+
+MGMSubItem::MGMSubItem() {
+ movement = 0;
+ staticsIndex = 0;
+ field_8 = 0;
+ field_C = 0;
+ x = 0;
+ y = 0;
+}
+
+void MGM::addItem(int objId) {
+ if (getItemIndexById(objId) == -1) {
+ MGMItem *item = new MGMItem();
+
+ item->objId = objId;
+ _items.push_back(item);
+ }
+ rebuildTables(objId);
+}
+
+void MGM::rebuildTables(int objId) {
+ int idx = getItemIndexById(objId);
+
+ if (idx == -1)
+ return;
+
+ _items[idx]->subItems.clear();
+ _items[idx]->statics.clear();
+ _items[idx]->movements1.clear();
+ _items[idx]->movements2.clear();
+
+ StaticANIObject *obj = g_fullpipe->_currentScene->getStaticANIObject1ById(objId, -1);
+
+ if (!obj)
+ return;
+
+ for (uint i = 0; i < obj->_staticsList.size(); i++)
+ _items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
+
+ for (uint i = 0; i < obj->_movements.size(); i++)
+ _items[idx]->movements1.push_back((Movement *)obj->_movements[i]);
+
+ _items[idx]->subItems.clear();
+}
+
+int MGM::getItemIndexById(int objId) {
+ for (uint i = 0; i < _items.size(); i++)
+ if (_items[i]->objId == objId)
+ return i;
+
+ return -1;
+}
+
+MessageQueue *MGM::genMovement(MGMInfo *mgminfo) {
+ warning("STUB: MGM::genMovement()");
+
+ return 0;
+}
+
+MovGraphLink::MovGraphLink() {
+ _distance = 0;
+ _angle = 0;
+ _flags = 0x10000000;
+ _movGraphNode2 = 0;
+ _movGraphNode1 = 0;
+ _field_3C = 0;
+ _field_38 = 0;
+ _movGraphReact = 0;
+ _name = 0;
+
+ _objtype = kObjTypeMovGraphLink;
+}
+
+bool MovGraphLink::load(MfcArchive &file) {
+ debug(5, "MovGraphLink::load()");
+
+ _dwordArray1.load(file);
+ _dwordArray2.load(file);
+
+ _flags = file.readUint32LE();
+
+ debug(8, "GraphNode1");
+ _movGraphNode1 = (MovGraphNode *)file.readClass();
+ debug(8, "GraphNode2");
+ _movGraphNode2 = (MovGraphNode *)file.readClass();
+
+ _distance = file.readDouble();
+ _angle = file.readDouble();
+
+ debug(8, "distance: %g, angle: %g", _distance, _angle);
+
+ _movGraphReact = (MovGraphReact *)file.readClass();
+ _name = file.readPascalString();
+
+ return true;
+}
+
+void MovGraphLink::calcNodeDistanceAndAngle() {
+ if (_movGraphNode1) {
+ double dx = _movGraphNode2->_x - _movGraphNode1->_x;
+ double dy = _movGraphNode2->_y - _movGraphNode1->_y;
+
+ _distance = sqrt(dy * dy + dx * dx);
+ _angle = atan2(dx, dy);
+ }
+}
+
+bool MovGraphNode::load(MfcArchive &file) {
+ debug(5, "MovGraphNode::load()");
+
+ _field_14 = file.readUint32LE();
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _distance = file.readUint32LE();
+
+ return true;
+}
+
+ReactParallel::ReactParallel() {
+ _x1 = 0;
+ _x2 = 0;
+ _dy = 0;
+ _dx = 0;
+ _y1 = 0;
+ _y2 = 0;
+}
+
+bool ReactParallel::load(MfcArchive &file) {
+ debug(5, "ReactParallel::load()");
+
+ _x1 = file.readUint32LE();
+ _y1 = file.readUint32LE();
+ _x2 = file.readUint32LE();
+ _y2 = file.readUint32LE();
+ _dx = file.readUint32LE();
+ _dy = file.readUint32LE();
+
+ createRegion();
+
+ return true;
+}
+
+void ReactParallel::createRegion() {
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * 4);
+
+ for (int i = 0; i < 4; i++)
+ _points[i] = new Common::Point;
+
+ double at = atan2((double)(_x1 - _x2), (double)(_y1 - _y2)) + 1.570796;
+ double sn = sin(at);
+ double cs = cos(at);
+
+ _points[0]->x = (int16)(_x1 - _dx * cs);
+ _points[0]->y = (int16)(_y1 - _dx * sn);
+
+ _points[1]->x = (int16)(_x2 - _dx * cs);
+ _points[1]->y = (int16)(_y2 - _dx * sn);
+
+ _points[2]->x = (int16)(_x2 + _dy * cs);
+ _points[2]->y = (int16)(_y2 + _dy * sn);
+
+ _points[3]->x = (int16)(_x1 + _dy * cs);
+ _points[3]->y = (int16)(_y1 + _dy * sn);
+
+ _pointCount = 4;
+ // GdiObject::Attach(_rgn, CreatePolygonRgn(_points, 4, 2);
+}
+
+void ReactParallel::method14() {
+ warning("STUB: ReactParallel::method14()");
+}
+
+ReactPolygonal::ReactPolygonal() {
+ _field_C = 0;
+ _field_10 = 0;
+}
+
+bool ReactPolygonal::load(MfcArchive &file) {
+ debug(5, "ReactPolygonal::load()");
+
+ _field_C = file.readUint32LE();
+ _field_10 = file.readUint32LE();
+ _pointCount = file.readUint32LE();
+
+ if (_pointCount > 0) {
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * _pointCount);
+
+ for (int i = 0; i < _pointCount; i++) {
+ _points[i] = new Common::Point;
+
+ _points[i]->x = file.readUint32LE();
+ _points[i]->y = file.readUint32LE();
+ }
+
+ }
+
+ createRegion();
+
+ return true;
+}
+
+void ReactPolygonal::createRegion() {
+ if (_points) {
+
+ // GdiObject::Attach(_rgn, CreatePolygonRgn(_points, _pointCount, 2);
+ }
+}
+
+void ReactPolygonal::method14() {
+ warning("STUB: ReactPolygonal::method14()");
+}
+
+bool MovGraphReact::pointInRegion(int x, int y) {
+ if (_pointCount < 3) {
+ return false;
+ }
+
+ int counter = 0;
+ double xinters;
+ Common::Point p, p1, p2;
+
+ p.x = (double)x;
+ p.y = (double)y;
+
+ p1.x = (double)_points[0]->x;
+ p1.y = (double)_points[0]->y;
+
+ for (int i = 1; i <= _pointCount; i++) {
+ p2.x = (double)_points[i % _pointCount]->x;
+ p2.y = (double)_points[i % _pointCount]->y;
+
+ if (p.y > MIN(p1.y, p2.y)) {
+ if (p.y <= MAX(p1.y, p2.y)) {
+ if (p.x <= MAX(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+
+ if (counter % 2 == 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+int startWalkTo(int objId, int objKey, int x, int y, int a5) {
+ MctlCompound *mc = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId);
+
+ if (mc)
+ return (mc->method34(g_fullpipe->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, a5, 0) != 0);
+
+ return 0;
+}
+
+int doSomeAnimation(int objId, int objKey, int a3) {
+ warning("STUB: doSomeAnimation(%d, %d, %d)", objId, objKey, a3);
+
+ return 0;
+}
+
+int doSomeAnimation2(int objId, int objKey) {
+ return doSomeAnimation(objId, objKey, 0);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
new file mode 100644
index 0000000000..bab0ffc8ca
--- /dev/null
+++ b/engines/fullpipe/motion.h
@@ -0,0 +1,372 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_MOTION_H
+#define FULLPIPE_MOTION_H
+
+namespace Fullpipe {
+
+class Statics;
+class Movement;
+class MctlConnectionPoint;
+
+int startWalkTo(int objId, int objKey, int x, int y, int a5);
+int doSomeAnimation(int objId, int objKey, int a3);
+int doSomeAnimation2(int objId, int objKey);
+
+class MotionController : public CObject {
+public:
+ int _field_4;
+ bool _isEnabled;
+
+public:
+ MotionController() : _isEnabled(true), _field_4(0) {}
+ virtual ~MotionController() {}
+ virtual bool load(MfcArchive &file);
+ virtual void methodC() {}
+ virtual void method10() {}
+ virtual void clearEnabled() { _isEnabled = false; }
+ virtual void setEnabled() { _isEnabled = true; }
+ virtual void addObject(StaticANIObject *obj) {}
+ virtual int removeObject(StaticANIObject *obj) { return 0; }
+ virtual void freeItems() {}
+ virtual int method28() { return 0; }
+ virtual int method2C() { return 0; }
+ virtual int method30() { return 0; }
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
+ virtual int changeCallback() { return 0; }
+ virtual int method3C() { return 0; }
+ virtual int method40() { return 0; }
+ virtual int method44() { return 0; }
+ virtual int method48() { return -1; }
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
+};
+
+class MovGraphReact : public CObject {
+public:
+ int _pointCount;
+ Common::Point **_points;
+
+public:
+ MovGraphReact() : _pointCount(0), _points(0) {}
+ ~MovGraphReact() { free(_points); }
+
+ virtual void method14() {}
+ virtual void createRegion() {}
+ virtual bool pointInRegion(int x, int y);
+};
+
+class MctlCompoundArrayItem : public CObject {
+ friend class MctlCompound;
+
+protected:
+ MotionController *_motionControllerObj;
+ MovGraphReact *_movGraphReactObj;
+ Common::Array<MctlConnectionPoint *> _connectionPoints;
+ int _field_20;
+ int _field_24;
+ int _field_28;
+
+public:
+ MctlCompoundArrayItem() : _movGraphReactObj(0), _motionControllerObj(0), _field_20(0), _field_24(0), _field_28(0) {}
+};
+
+class MctlCompoundArray : public Common::Array<MctlCompoundArrayItem *>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class MctlCompound : public MotionController {
+ MctlCompoundArray _motionControllers;
+
+ public:
+ MctlCompound() { _objtype = kObjTypeMctlCompound; }
+
+ virtual bool load(MfcArchive &file);
+
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj);
+ virtual void freeItems();
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+
+ void initMovGraph2();
+ MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr);
+};
+
+struct MGMSubItem {
+ int movement;
+ int staticsIndex;
+ int field_8;
+ int field_C;
+ int x;
+ int y;
+
+ MGMSubItem();
+};
+
+struct MGMItem {
+ int16 objId;
+ Common::Array<MGMSubItem *> subItems;
+ Common::Array<Statics *> statics;
+ Common::Array<Movement *> movements1;
+ Common::Array<Movement *> movements2;
+
+ MGMItem();
+};
+
+struct MGMInfo {
+ StaticANIObject *ani;
+ int staticsId1;
+ int staticsId2;
+ int movementId;
+ int field_10;
+ int x1;
+ int y1;
+ int field_1C;
+ int x2;
+ int y2;
+ int flags;
+};
+
+class MGM : public CObject {
+public:
+ Common::Array<MGMItem *> _items;
+
+public:
+ void clear();
+ void addItem(int objId);
+ void rebuildTables(int objId);
+ int getItemIndexById(int objId);
+
+ MessageQueue *genMovement(MGMInfo *mgminfo);
+};
+
+class MovGraphNode : public CObject {
+public:
+ int _x;
+ int _y;
+ int _distance;
+ int16 _field_10;
+ int _field_14;
+
+public:
+ MovGraphNode() : _x(0), _y(0), _distance(0), _field_10(0), _field_14(0) { _objtype = kObjTypeMovGraphNode; }
+ virtual bool load(MfcArchive &file);
+};
+
+class ReactParallel : public MovGraphReact {
+ //CRgn _rgn;
+ int _x1;
+ int _y1;
+ int _x2;
+ int _y2;
+ int _dx;
+ int _dy;
+
+ public:
+ ReactParallel();
+ virtual bool load(MfcArchive &file);
+
+ virtual void method14();
+ virtual void createRegion();
+};
+
+class ReactPolygonal : public MovGraphReact {
+ //CRgn _rgn;
+ int _field_C;
+ int _field_10;
+
+ public:
+ ReactPolygonal();
+ virtual bool load(MfcArchive &file);
+
+ virtual void method14();
+ virtual void createRegion();
+};
+
+class MovGraphLink : public CObject {
+ public:
+ MovGraphNode *_movGraphNode1;
+ MovGraphNode *_movGraphNode2;
+ DWordArray _dwordArray1;
+ DWordArray _dwordArray2;
+ int _flags;
+ int _field_38;
+ int _field_3C;
+ double _distance;
+ double _angle;
+ MovGraphReact *_movGraphReact;
+ char *_name;
+
+ public:
+ MovGraphLink();
+ virtual bool load(MfcArchive &file);
+
+ void calcNodeDistanceAndAngle();
+};
+
+struct MovGraphItem {
+ StaticANIObject *ani;
+ int field_4;
+ int field_8;
+ int field_C;
+ int field_10;
+ int field_14;
+ int field_18;
+ int field_1C;
+ int field_20;
+ int field_24;
+ int items;
+ int count;
+ int field_30;
+ int field_34;
+ int field_38;
+ int field_3C;
+
+ MovGraphItem();
+};
+
+class MovGraph : public MotionController {
+public:
+ ObList _nodes;
+ ObList _links;
+ int _field_44;
+ Common::Array<MovGraphItem *> _items;
+ int (*_callback1)(int, int, int);
+ MGM _mgm;
+
+public:
+ MovGraph();
+ virtual bool load(MfcArchive &file);
+
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj);
+ virtual void freeItems();
+ virtual int method28();
+ virtual int method2C();
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual int changeCallback();
+ virtual int method3C();
+ virtual int method44();
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual int method50();
+
+ double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch);
+ void calcNodeDistancesAndAngles();
+ MovGraphNode *calcOffset(int ox, int oy);
+};
+
+class Movement;
+
+struct MG2I {
+ int _movementId;
+ Movement *_mov;
+ int _mx;
+ int _my;
+};
+
+struct MovGraph2ItemSub {
+ int _staticsId2;
+ int _staticsId1;
+ MG2I _walk[3];
+ MG2I _turn[4];
+ MG2I _turnS[4];
+};
+
+struct LinkInfo {
+ MovGraphLink *link;
+ MovGraphNode *node;
+};
+
+struct MovInfo1Sub {
+ int subIndex;
+ int x;
+ int y;
+ int distance;
+};
+
+struct MovInfo1 {
+ int field_0;
+ Common::Point pt1;
+ Common::Point pt2;
+ int distance1;
+ int distance2;
+ int subIndex;
+ int item1Index;
+ Common::Array<MovInfo1Sub *> items;
+ int itemsCount;
+ int flags;
+};
+
+struct MovGraph2Item { // 744
+ int _objectId;
+ StaticANIObject *_obj;
+ MovGraph2ItemSub _subItems[4]; // 184
+};
+
+class MovGraph2 : public MovGraph {
+public:
+ Common::Array<MovGraph2Item *> _items2;
+
+public:
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj);
+ virtual void freeItems();
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+
+ int getItemIndexByGameObjectId(int objectId);
+ int getItemSubIndexByStaticsId(int index, int staticsId);
+ int getItemSubIndexByMovementId(int index, int movId);
+ int getItemSubIndexByMGM(int idx, StaticANIObject *ani);
+
+ int getShortSide(MovGraphLink *lnk, int x, int y);
+ int findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *a3, Common::Point *a4);
+
+ bool initDirections(StaticANIObject *obj, MovGraph2Item *item);
+ void buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst);
+ MessageQueue *buildMovInfo1MessageQueue(MovInfo1 *movInfo);
+
+ MovGraphNode *findNode(int x, int y, int fuzzyMatch);
+ MovGraphLink *findLink1(int x, int y, int idx, int fuzzyMatch);
+ MovGraphLink *findLink2(int x, int y);
+ double findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj);
+
+ MessageQueue *genMovement(MovInfo1 *movinfo);
+};
+
+class MctlConnectionPoint : public CObject {
+public:
+ int _connectionX;
+ int _connectionY;
+ int _field_C;
+ int _field_10;
+ int16 _field_14;
+ int16 _field_16;
+ MessageQueue *_messageQueueObj;
+ int _motionControllerObj;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MOTION_H */
diff --git a/engines/fullpipe/ngiarchive.cpp b/engines/fullpipe/ngiarchive.cpp
new file mode 100644
index 0000000000..5d895c17a0
--- /dev/null
+++ b/engines/fullpipe/ngiarchive.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+#include "common/archive.h"
+
+#include "common/file.h"
+#include "common/hash-str.h"
+#include "common/memstream.h"
+#include "common/bufferedstream.h"
+#include "common/textconsole.h"
+
+#include "fullpipe/ngiarchive.h"
+
+namespace Fullpipe {
+
+NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename) {
+ Common::File ngiFile;
+
+ if (!ngiFile.open(_ngiFilename)) {
+ warning("NGIArchive::NGIArchive(): Could not find the archive file");
+ return;
+ }
+
+ ngiFile.seek(4, SEEK_SET);
+
+ unsigned int count = ngiFile.readUint16LE(); // How many entries?
+
+ ngiFile.seek(20, SEEK_SET);
+
+ unsigned int key = ngiFile.readUint16LE();
+
+ byte key1, key2;
+
+ key1 = key & 0xff;
+ key2 = (key >> 8) & 0xff;
+
+ int fatSize = count * 32;
+
+ ngiFile.seek(32, SEEK_SET);
+
+ byte *fat = (byte *)calloc(fatSize, 1);
+
+ ngiFile.read(fat, fatSize);
+
+ for (int i = 0; i < fatSize; i++) {
+ key1 = (key1 << 1) ^ key2;
+ key2 = (key2 >> 1) ^ key1;
+
+ fat[i] ^= key1;
+ }
+
+ NgiHeader header;
+ NgiHeader *head;
+
+ for (uint i = 0; i < count; i++) {
+ memcpy(header.filename, &fat[i * 32], 12);
+ header.filename[12] = 0;
+ header.flags = READ_LE_UINT32(&fat[i * 32 + 16]);
+ header.extVal = READ_LE_UINT32(&fat[i * 32 + 20]);
+ header.pos = READ_LE_UINT32(&fat[i * 32 + 24]);
+ header.size = READ_LE_UINT32(&fat[i * 32 + 28]);
+
+ if (header.flags & 0x1e0) {
+ warning("File has flags: %.8x\n", header.flags & 0x1e0);
+ }
+
+ head = new NgiHeader(header);
+
+ _headers[header.filename] = head;
+ }
+
+ free(fat);
+
+ g_fullpipe->_currArchive = this;
+
+ debug(0, "NGIArchive::NGIArchive(%s): Located %d files", filename.c_str(), _headers.size());
+}
+
+NGIArchive::~NGIArchive() {
+ debug(0, "NGIArchive Destructor Called");
+ NgiHeadersMap::iterator it = _headers.begin();
+ for ( ; it != _headers.end(); ++it) {
+ delete it->_value;
+ }
+
+ g_fullpipe->_currArchive = 0;
+}
+
+bool NGIArchive::hasFile(const Common::String &name) const {
+ return _headers.contains(name);
+}
+
+ int NGIArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int matches = 0;
+
+ NgiHeadersMap::const_iterator it = _headers.begin();
+ for ( ; it != _headers.end(); ++it) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->filename, this)));
+ matches++;
+ }
+
+ return matches;
+}
+
+const Common::ArchiveMemberPtr NGIArchive::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::String &name) const {
+ if (!_headers.contains(name)) {
+ return 0;
+ }
+
+ NgiHeader *hdr = _headers[name];
+
+ Common::File archiveFile;
+ archiveFile.open(_ngiFilename);
+ archiveFile.seek(hdr->pos, SEEK_SET);
+
+ byte *data = (byte *)malloc(hdr->size);
+ assert(data);
+
+ int32 len = archiveFile.read(data, hdr->size);
+ assert(len == hdr->size);
+
+ return new Common::MemoryReadStream(data, hdr->size, DisposeAfterUse::YES);
+}
+
+Common::Archive *makeNGIArchive(const Common::String &name) {
+ return new NGIArchive(name);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/ngiarchive.h b/engines/fullpipe/ngiarchive.h
new file mode 100644
index 0000000000..a5b05a2e50
--- /dev/null
+++ b/engines/fullpipe/ngiarchive.h
@@ -0,0 +1,69 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_NGIARCHIVE_H
+#define FULLPIPE_NGIARCHIVE_H
+
+#include "common/str.h"
+
+namespace Fullpipe {
+
+class Archive;
+
+#define NGI_FILENAME_MAX 13
+
+struct NgiHeader {
+ int32 pos;
+ int32 extVal;
+ int32 flags;
+ int32 size;
+ char filename[NGI_FILENAME_MAX];
+};
+
+typedef Common::HashMap<Common::String, NgiHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> NgiHeadersMap;
+
+class NGIArchive : public Common::Archive {
+ NgiHeadersMap _headers;
+ Common::String _ngiFilename;
+
+public:
+ NGIArchive(const Common::String &name);
+ virtual ~NGIArchive();
+
+ // Archive implementation
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+ virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+};
+
+/**
+ * This factory method creates an Archive instance corresponding to the content
+ * of the NGI compressed file with the given name.
+ *
+ * May return 0 in case of a failure.
+ */
+Common::Archive *makeNGIArchive(const Common::String &name);
+
+} // End of namespace Fullpipe
+
+#endif
diff --git a/engines/fullpipe/objectnames.h b/engines/fullpipe/objectnames.h
new file mode 100644
index 0000000000..241e31b165
--- /dev/null
+++ b/engines/fullpipe/objectnames.h
@@ -0,0 +1,250 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// This file is used in order to avoid usage of constants in Russian accross the code
+
+#ifndef FULLPIPE_OBJECTNAMES_H
+#define FULLPIPE_OBJECTNAMES_H
+
+namespace Fullpipe {
+
+#define sO_Grandma "\xc1\xe0\xe1\xf3\xeb\xff" // "БабулÑ"
+#define sO_Jar_4 "\xc1\xe0\xed\xea\xe0_4" // "Банка_4"
+#define sO_Pool "\xc1\xe0\xf1\xf1\xe5\xe9\xed" // "БаÑÑейн"
+#define sO_TumyTrampie "\xc1\xe0\xf2\xf3\xf2\xe0" // "Батута"
+#define sO_WithoutBoot "\xc1\xe5\xe7 \xe1\xee\xf2\xe8\xed\xea\xe0" // "Без ботинка"
+#define sO_WithoutJug "\xc1\xe5\xe7 \xe3\xee\xf0\xf8\xea\xee\xe2" // "Без горшков"
+#define sO_WithoutCarpet "\xc1\xe5\xe7 \xea\xee\xe2\xf0\xe8\xea\xe0" // "Без коврика"
+#define sO_WithoutCoin "\xc1\xe5\xe7 \xec\xee\xed\xe5\xf2\xfb" // "Без монеты"
+#define sO_WithNothing "\xc1\xe5\xe7 \xed\xe8\xf7\xe5\xe3\xee" // "Без ничего"
+#define sO_WithoutHandle "\xc1\xe5\xe7 \xf0\xf3\xf7\xea\xe8" // "Без ручки"
+#define sO_WithoutStool "\xc1\xe5\xe7 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xe8" // "Без табуретки"
+#define sO_WithoutDrawer "\xc1\xe5\xe7 \xff\xf9\xe8\xea\xe0" // "Без Ñщика"
+#define sO_Blocked "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Блокирован"
+#define sO_BlockedShe "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed\xe0" // "Блокирована"
+#define sO_Awaken "\xc1\xee\xe4\xf0\xf1\xf2\xe2\xf3\xe5\xf2" // "БодрÑтвует"
+#define sO_Boot_15 "\xc1\xee\xf2\xe8\xed\xee\xea_15" // "Ботинок_15"
+#define sO_Bottle_38 "\xc1\xf3\xf2\xfb\xeb\xea\xe0_38" // "Бутылка_38"
+#define sO_InSmokeRoom "\xc2 \xea\xf3\xf0\xe8\xeb\xea\xe5" // "В курилке"
+#define sO_InSock "\xc2 \xed\xee\xf1\xea\xe5" // "Ð’ ноÑке"
+#define sO_InGlasses "\xc2 \xee\xf7\xea\xe0\xf5" // "В очках"
+#define sO_In_14 "\xc2_14" // "Ð’_14"
+#define sO_In_32_Lies "\xc2_32 \xeb\xe5\xe6\xe8\xf2" // "В_32 лежит"
+#define sO_In_32_Stands "\xc2_32 \xf2\xee\xf0\xf7\xe8\xf2" // "В_32 торчит"
+#define sO_In_33 "\xc2_33" // "Ð’_33"
+#define sO_In_7 "\xc2_7" // "Ð’_7"
+#define sO_Together "\xc2\xe4\xe2\xee\xe5\xec" // "Вдвоем"
+#define sO_Valve1_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x31_26" // "Вентиль1_26"
+#define sO_Valve2_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x32_26" // "Вентиль2_26"
+#define sO_Valve3_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x33_26" // "Вентиль3_26"
+#define sO_Valve4_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x34_26" // "Вентиль4_26"
+#define sO_Valve5_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x35_26" // "Вентиль5_26"
+#define sO_Valve_34 "\xc2\xe5\xed\xf2\xe8\xeb\xfc_34" // "Вентиль_34"
+#define sO_UpperHatch_23 "\xc2\xe5\xf0\xf5\xed\xe8\xe9 \xeb\xfe\xea_23" // "Верхний люк_23"
+#define sO_Taken "\xc2\xe7\xff\xf2" // "ВзÑÑ‚"
+#define sO_HangsOnPipe "\xc2\xe8\xf1\xe8\xf2 \xed\xe0 \xf2\xf0\xf3\xe1\xe5" // "ВиÑит на трубе"
+#define sO_On "\xc2\xea\xeb" // "Вкл"
+#define sO_TurnedOn "\xc2\xea\xeb\xfe\xf7\xe5\xed" // "Включен"
+#define sO_Driver "\xc2\xee\xe4\xe8\xeb\xe0" // "Водила"
+#define sO_HareTheNooksiter "\xc2\xf3\xe3\xeb\xf3\xf1\xe5\xe4" // "ВуглуÑед"
+#define sO_Off "\xc2\xfb\xea\xeb" // "Выкл"
+#define sO_TurnedOff "\xc2\xfb\xea\xeb\xfe\xf7\xe5\xed" // "Выключен"
+#define sO_HasGrown "\xc2\xfb\xf0\xee\xf1" // "ВыроÑ"
+#define sO_Boss "\xc3\xeb\xe0\xe2\xe0\xf0\xfc" // "Главарь"
+#define sO_Jug "\xc3\xee\xf0\xf8\xee\xea" // "Горшок"
+#define sO_Strolling "\xc3\xf3\xeb\xff\xe5\xf2" // "ГулÑет"
+#define sO_Yes "\xc4\xe0" // "Да"
+#define sO_Girl "\xc4\xe5\xe2\xee\xf7\xea\xe0" // "Девочка"
+#define sO_Elephantine "\xc4\xe5\xe2\xee\xf7\xea\xe0-\xf1\xeb\xee\xed\xe8\xea" // "Девочка-Ñлоник"
+#define sO_Grandpa "\xc4\xe5\xe4\xf3\xf8\xea\xe0" // "Дедушка"
+#define sO_Plank_25 "\xc4\xee\xf1\xea\xe0_25" // "ДоÑка_25"
+#define sO_Plank_34 "\xc4\xee\xf1\xea\xe0_34" // "ДоÑка_34"
+#define sO_DudeJumped "\xc4\xff\xe4\xff \xef\xf0\xfb\xe3\xe0\xeb" // "ДÑÐ´Ñ Ð¿Ñ€Ñ‹Ð³Ð°Ð»"
+#define sO_Dude "\xc4\xff\xe4\xff" // "ДÑдÑ"
+#define sO_GuvTheDrawer "\xc4\xff\xe4\xff-\xff\xf9\xe8\xea" // "ДÑдÑ-Ñщик"
+#define sO_DudeSwinged "\xc4\xff\xe4\xff_\xea\xe0\xf2\xe0\xeb\xf1\xff" // "ДÑдÑ_каталÑÑ"
+#define sO_Eats "\xc5\xf1\xf2" // "ЕÑÑ‚"
+#define sO_Present "\xc5\xf1\xf2\xfc" // "ЕÑть"
+#define sO_CloseThing1 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 1" // "Закрываемое 1"
+#define sO_CloseThing2 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 2" // "Закрываемое 2"
+#define sO_CloseThing3 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 3" // "Закрываемое 3"
+#define sO_CloseThing "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5" // "Закрываемое"
+#define sO_Closed "\xc7\xe0\xea\xf0\xfb\xf2" // "Закрыт"
+#define sO_ClosedWithBoot "\xc7\xe0\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Закрыта Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
+#define sO_IsClosed "\xc7\xe0\xea\xf0\xfb\xf2\xe0" // "Закрыта"
+#define sO_HalfFull "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xed\xe0\xef\xee\xeb\xee\xe2\xe8\xed\xf3" // "Заполнен наполовину"
+#define sO_Full "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xf6\xe5\xeb\xe8\xea\xee\xec" // "Заполнен целиком"
+#define sO_MirroredTo "\xc7\xe5\xf0\xea\xe0\xeb\xfc\xed\xe0\xff \xea" // "Ð—ÐµÑ€ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ðº"
+#define sO_Playing "\xc8\xe3\xf0\xe0\xe5\xf2" // "Играет"
+#define sO_Tub "\xca\xe0\xe4\xea\xe0" // "Кадка"
+#define sO_Cactus "\xca\xe0\xea\xf2\xf3\xf1" // "КактуÑ"
+#define sO_SwingingWithBoot "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "КатаетÑÑ Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
+#define sO_Swinging "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff" // "КатаетÑÑ"
+#define sO_Swingie "\xca\xe0\xf7\xe5\xeb\xe5\xed\xff" // "КачеленÑ"
+#define sO_LiftButtons "\xca\xed\xee\xef\xea\xe8 \xeb\xe8\xf4\xf2\xe0" // "Кнопки лифта"
+#define sO_Carpet_35 "\xca\xee\xe2\xf0\xe8\xea_35" // "Коврик_35"
+#define sO_Valve_35 "\xca\xf0\xe0\xed_35" // "Кран_35"
+#define sO_Cup "\xca\xf0\xf3\xe6\xea\xe0" // "Кружка"
+#define sO_Cube "\xca\xf3\xe1\xe8\xea" // "Кубик"
+#define sO_LeftPipe_15 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_15" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_15"
+#define sO_LeftPipe_26 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_26" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_26"
+#define sO_LeftPipe_29 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_29" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_29"
+#define sO_LeftPipe_30 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_30" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_30"
+#define sO_LeftPipe_37 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_37" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_37"
+#define sO_StarsDown_24 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xe2\xed\xe8\xe7_24" // "ЛеÑтница вниз_24"
+#define sO_StairsUp_8 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xf1\xe2\xe5\xf0\xf5\xf3_8" // "ЛеÑтница Ñверху_8"
+#define sO_Stairway "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0" // "ЛеÑтница"
+#define sO_Fliers "\xcb\xe5\xf2\xf3\xed\xfb" // "Летуны"
+#define sO_Hatch_26 "\xcb\xfe\xea_26" // "Люк_26"
+#define sO_Hatch_34 "\xcb\xfe\xea_34" // "Люк_34"
+#define sO_MommyOfHandle_32 "\xcc\xe0\xec\xe0 \xf0\xf3\xf7\xea\xe8_32" // "Мама ручки_32"
+#define sO_BigMumsy "\xcc\xe0\xec\xe0\xf8\xe0" // "Мамаша"
+#define sO_Bag_22 "\xcc\xe5\xf8\xee\xea_22" // "Мешок_22"
+#define sO_CoinSlot_1 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea 1" // "Монетоприемник 1"
+#define sO_CoinSlot_22 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea_22" // "Монетоприемник_22"
+#define sO_CoinSlot_35 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea_35" // "Монетоприемник_35"
+#define sO_Bridge "\xcc\xee\xf1\xf2" // "МоÑÑ‚"
+#define sO_Fly_12 "\xcc\xf3\xf5\xe0_12" // "Муха_12"
+#define sO_Fly_17 "\xcc\xf3\xf5\xe0_17" // "Муха_17"
+#define sO_OnTheFloor "\xcd\xe0 \xef\xee\xeb\xf3" // "Ðа полу"
+#define sO_OnTheSpring "\xcd\xe0 \xef\xf0\xf3\xe6\xe8\xed\xe5" // "Ðа пружине"
+#define sO_OnTheTable "\xcd\xe0 \xf1\xf2\xee\xeb\xe5" // "Ðа Ñтоле"
+#define sO_OnStool "\xcd\xe0 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xe5" // "Ðа табуретке"
+#define sO_Inflater "\xcd\xe0\xe4\xf3\xe2\xe0\xf2\xe5\xeb\xfc" // "Ðадуватель"
+#define sO_NotTaken "\xcd\xe5 \xe2\xe7\xff\xf2" // "Ðе взÑÑ‚"
+#define sO_NotHanging "\xcd\xe5 \xe2\xe8\xf1\xe8\xf2" // "Ðе виÑит"
+#define sO_NotGrown "\xcd\xe5 \xe2\xfb\xf0\xee\xf1" // "Ðе выроÑ"
+#define sO_DidNotCrackEgg "\xcd\xe5 \xea\xee\xeb\xee\xeb \xff\xe9\xf6\xee" // "Ðе колол Ñйцо"
+#define sO_NotFallen "\xcd\xe5 \xef\xe0\xe4\xe0\xeb" // "Ðе падал"
+#define sO_NotAvailable "\xcd\xe5\xe4\xee\xf1\xf2\xf3\xef\xed\xe0" // "ÐедоÑтупна"
+#define sO_CannotTake "\xcd\xe5\xeb\xfc\xe7\xff \xe2\xe7\xff\xf2\xfc" // "ÐÐµÐ»ÑŒÐ·Ñ Ð²Ð·Ñть"
+#define sO_No "\xcd\xe5\xf2" // "Ðет"
+#define sO_LowerHatch_23 "\xcd\xe8\xe6\xed\xe8\xe9 \xeb\xfe\xea_23" // "Ðижний люк_23"
+#define sO_LowerPipe "\xcd\xe8\xe6\xed\xff\xff \xf2\xf0\xf3\xe1\xe0" // "ÐижнÑÑ Ñ‚Ñ€ÑƒÐ±Ð°"
+#define sO_LowerPipe_21 "\xcd\xe8\xe6\xed\xff\xff \xf2\xf0\xf3\xe1\xe0_21" // "ÐижнÑÑ Ñ‚Ñ€ÑƒÐ±Ð°_21"
+#define sO_WantsNothing "\xcd\xe8\xf7\xe5\xe3\xee \xed\xe5 \xf5\xee\xf7\xe5\xf2" // "Ðичего не хочет"
+#define sO_Leg "\xcd\xee\xe3\xe0" // "Ðога"
+#define sO_FriesPit "\xcd\xee\xf0\xea\xe0 \xea\xee\xe7\xff\xe2\xea\xe8" // "Ðорка козÑвки"
+#define sO_Sock_26 "\xcd\xee\xf1\xee\xea_26" // "ÐоÑок_26"
+#define sO_ClockAxis "\xce\xf1\xfc \xf7\xe0\xf1\xee\xe2" // "ОÑÑŒ чаÑов"
+#define sO_Opened "\xce\xf2\xea\xf0\xfb\xf2" // "Открыт"
+#define sO_OpenedWithBoot "\xce\xf2\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Открыта Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
+#define sO_OpenedShe "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта"
+#define sO_WeirdWacko "\xce\xf2\xec\xee\xf0\xee\xe6\xe5\xed\xed\xfb\xe9" // "Отмороженный"
+#define sO_NotPresent "\xce\xf2\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "ОтÑутÑтвует"
+#define sO_Error "\xce\xf8\xe8\xe1\xea\xe0" // "Ошибка"
+#define sO_Passive "\xcf\xe0\xf1\xf1\xe8\xe2\xed\xe0" // "ПаÑÑивна"
+#define sO_First "\xcf\xe5\xf0\xe2\xfb\xe9" // "Первый"
+#define sO_UpsideDown "\xcf\xe5\xf0\xe5\xe2\xe5\xf0\xed\xf3\xf2\xe0" // "Перевернута"
+#define sO_Overfull "\xcf\xe5\xf0\xe5\xef\xee\xeb\xed\xe5\xed" // "Переполнен"
+#define sO_Fireman "\xcf\xee\xe6\xe0\xf0\xed\xe8\xea" // "Пожарник"
+#define sO_ShowingHeel "\xcf\xee\xea\xe0\xe7\xfb\xe2\xe0\xe5\xf2 \xef\xff\xf2\xea\xf3" // "Показывает пÑтку"
+#define sO_FullPipe "\xcf\xee\xeb\xed\xe0\xff \xd2\xf0\xf3\xe1\xe0" // "ÐŸÐ¾Ð»Ð½Ð°Ñ Ð¢Ñ€ÑƒÐ±Ð°"
+#define sO_RightStairs_9 "\xcf\xf0\xe0\xe2\xe0\xff \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe0_9" // "ÐŸÑ€Ð°Ð²Ð°Ñ Ð»ÐµÑтница_9"
+#define sO_RightPipe_17 "\xcf\xf0\xe0\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_17" // "ÐŸÑ€Ð°Ð²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_17"
+#define sO_Available "\xcf\xf0\xe8\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "ПриÑутÑтвует"
+#define sO_GulpedEgg "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xee\xe5 \xff\xe9\xf6\xee" // "Проглоченное Ñйцо"
+#define sO_GulpedEggs "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xfb\xe5 \xff\xe9\xf6\xe0" // "Проглоченные Ñйца"
+#define sO_BellyInflater "\xcf\xf3\xe7\xee\xe4\xf3\xe2" // "Пузодув"
+#define sO_Empty "\xcf\xf3\xf1\xf2" // "ПуÑÑ‚"
+#define sO_EmptyShe "\xcf\xf3\xf1\xf2\xe0\xff" // "ПуÑтаÑ"
+#define sO_WayToPipe "\xcf\xf3\xf2\xfc \xea \xf2\xf0\xf3\xe1\xe5" // "Путь к трубе"
+#define sO_Drinking "\xcf\xfc\xe5\xf2" // "Пьет"
+#define sO_BrokenInPieces "\xd0\xe0\xe7\xe1\xe8\xf2\xe0" // "Разбита"
+#define sO_Unblocked "\xd0\xe0\xe7\xe1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Разблокирован"
+#define sO_Unfolded "\xd0\xe0\xe7\xe2\xe5\xf0\xed\xf3\xf2" // "Развернут"
+#define sO_Jawcrucnher "\xd0\xee\xf2\xee\xf5\xf0\xf3\xf1" // "РотохруÑ"
+#define sO_UsherHand "\xd0\xf3\xea\xe0 \xc1\xe8\xeb\xe5\xf2\xe5\xf0\xf8\xe8" // "Рука Билетерши"
+#define sO_LeverHandle_23 "\xd0\xf3\xea\xee\xff\xf2\xea\xe0 \xf0\xfb\xf7\xe0\xe3\xe0_23" // "РукоÑтка рычага_23"
+#define sO_ClockHandle "\xd0\xf3\xf7\xea\xe0 \xee\xf2 \xf7\xe0\xf1\xee\xe2" // "Ручка от чаÑов"
+#define sO_Lever_23 "\xd0\xfb\xf7\xe0\xe3_23" // "Рычаг_23"
+#define sO_WithDudeOnLeft "\xd1 \xc4\xff\xe4\xe5\xe9 \xf1\xeb\xe5\xe2\xe0" // "С ДÑдей Ñлева"
+#define sO_WithDudeOnRight "\xd1 \xc4\xff\xe4\xe5\xe9 \xf1\xef\xf0\xe0\xe2\xe0" // "С ДÑдей Ñправа"
+#define sO_WithBoot "\xd1 \xe1\xe0\xf8\xec\xe0\xea\xee\xec" // "С башмаком"
+#define sO_WithBig "\xd1 \xe1\xee\xeb\xfc\xf8\xe8\xec" // "С большим"
+#define sO_WithPlunger "\xd1 \xe2\xe0\xed\xf2\xf3\xe7\xee\xec" // "С вантузом"
+#define sO_WithJug "\xd1 \xe3\xee\xf0\xf8\xea\xee\xec" // "С горшком"
+#define sO_WithGum "\xd1 \xe6\xe2\xe0\xf7\xea\xee\xe9" // "С жвачкой"
+#define sO_WithShovel "\xd1 \xeb\xee\xef\xe0\xf2\xee\xe9" // "С лопатой"
+#define sO_WithTiny "\xd1 \xec\xe0\xeb\xfb\xec" // "С малым"
+#define sO_WithHammer "\xd1 \xec\xee\xeb\xee\xf2\xea\xee\xec" // "С молотком"
+#define sO_WithCoin "\xd1 \xec\xee\xed\xe5\xf2\xee\xe9" // "С монетой"
+#define sO_WithSock "\xd1 \xed\xee\xf1\xea\xee\xec" // "С ноÑком"
+#define sO_WithCork "\xd1 \xef\xf0\xee\xe1\xea\xee\xe9" // "С пробкой"
+#define sO_WithSteering "\xd1 \xf0\xf3\xeb\xe5\xec" // "С рулем"
+#define sO_WithHandle "\xd1 \xf0\xf3\xf7\xea\xee\xe9" // "С ручкой"
+#define sO_WithApple "\xd1 \xff\xe1\xeb\xee\xea\xee\xec" // "С Ñблоком"
+#define sO_WithDrawer "\xd1 \xff\xf9\xe8\xea\xee\xec" // "С Ñщиком"
+#define sO_Sugar "\xd1\xe0\xf5\xe0\xf0\xee\xea" // "Сахарок"
+#define sO_Convoluted "\xd1\xe2\xe5\xf0\xed\xf3\xf2" // "Свернут"
+#define sO_IsFree "\xd1\xe2\xee\xe1\xee\xe4\xed\xe0" // "Свободна"
+#define sO_Sitting "\xd1\xe8\xe4\xe8\xf2" // "Сидит"
+#define sO_Laughing "\xd1\xec\xe5\xe5\xf2\xf1\xff" // "СмеетÑÑ"
+#define sO_WithEveryone "\xd1\xee \xe2\xf1\xe5\xec\xe8" // "Со вÑеми"
+#define sO_WithMop "\xd1\xee \xf8\xe2\xe0\xe1\xf0\xee\xe9" // "Со шваброй"
+#define sO_WithHose "\xd1\xee \xf8\xeb\xe0\xed\xe3\xee\xec" // "Со шлангом"
+#define sO_WithBrush "\xd1\xee \xf9\xe5\xf2\xea\xee\xe9" // "Со щеткой"
+#define sO_Sleeping "\xd1\xef\xe8\xf2" // "Спит"
+#define sO_OnRight "\xd1\xef\xf0\xe0\xe2\xe0" // "Справа"
+#define sO_StandsInBoots "\xd1\xf2\xee\xe8\xf2 \xe2 \xe1\xee\xf2\xe8\xed\xea\xe0\xf5" // "Стоит в ботинках"
+#define sO_StandsInCorner "\xd1\xf2\xee\xe8\xf2 \xe2 \xf3\xe3\xeb\xf3" // "Стоит в углу"
+#define sO_Guardian "\xd1\xf2\xee\xf0\xee\xe6" // "Сторож"
+#define sO_Guard_1 "\xd1\xf2\xf0\xe0\xe6 1" // "Страж 1"
+#define sO_Gurad_2 "\xd1\xf2\xf0\xe0\xe6 2" // "Страж 2"
+#define sO_Guard_3 "\xd1\xf2\xf0\xe0\xe6 3" // "Страж 3"
+#define sO_Stool_34 "\xd2\xe0\xe1\xf3\xf0\xe5\xf2_34" // "Табурет_34"
+#define sO_Pipe_9 "\xd2\xf0\xf3\xe1\xe0_9" // "Труба_9"
+#define sO_Pedestal_16 "\xd2\xf3\xec\xe1\xe0_16" // "Тумба_16"
+#define sO_Pedestal_17 "\xd2\xf3\xec\xe1\xe0_17" // "Тумба_17"
+#define sO_Pedestal_33 "\xd2\xf3\xec\xe1\xe0_33" // "Тумба_33"
+#define sO_NearDudesStairs "\xd3 \xc4\xff\xe4\xe8 \xed\xe0 \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe5" // "У ДÑди на леÑтнице"
+#define sO_NearDude "\xd3 \xc4\xff\xe4\xe8" // "У ДÑди"
+#define sO_NearPipeWithStool "\xd3 \xf2\xf0\xf3\xe1\xfb \xf1 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xee\xe9" // "У трубы Ñ Ñ‚Ð°Ð±ÑƒÑ€ÐµÑ‚ÐºÐ¾Ð¹"
+#define sO_NearPipe "\xd3 \xf2\xf0\xf3\xe1\xfb" // "У трубы"
+#define sO_Janitors "\xd3\xe1\xee\xf0\xf9\xe8\xea\xe8" // "Уборщики"
+#define sO_Janitress "\xd3\xe1\xee\xf0\xf9\xe8\xf6\xe0" // "Уборщица"
+#define sO_Gone "\xd3\xe5\xf5\xe0\xeb\xe0" // "Уехала"
+#define sO_FallenOnce "\xd3\xef\xe0\xeb \xf0\xe0\xe7" // "Упал раз"
+#define sO_FallenBrush "\xd3\xef\xe0\xeb\xe0 \xf9\xe5\xf2\xea\xe0" // "Упала щетка"
+#define sO_NotBroken "\xd6\xe5\xeb\xe0" // "Цела"
+#define sO_ScratchingBelly "\xd7\xe5\xf8\xe5\xf2 \xef\xf3\xe7\xee" // "Чешет пузо"
+#define sO_Level0 "\xdd\xf2\xe0\xe6 0" // "Этаж 0"
+#define sO_Level1 "\xdd\xf2\xe0\xe6 1" // "Этаж 1"
+#define sO_Level2 "\xdd\xf2\xe0\xe6 2" // "Этаж 2"
+#define sO_Level3 "\xdd\xf2\xe0\xe6 3" // "Этаж 3"
+#define sO_Level4 "\xdd\xf2\xe0\xe6 4" // "Этаж 4"
+#define sO_Level5 "\xdd\xf2\xe0\xe6 5" // "Этаж 5"
+#define sO_Level6 "\xdd\xf2\xe0\xe6 6" // "Этаж 6"
+#define sO_Level7 "\xdd\xf2\xe0\xe6 7" // "Этаж 7"
+#define sO_Level8 "\xdd\xf2\xe0\xe6 8" // "Этаж 8"
+#define sO_Level9 "\xdd\xf2\xe0\xe6 9" // "Этаж 9"
+#define sO_EggGulperGaveCoin "\xdf\xe9\xf6\xe5\xe3\xeb\xee\xf2 \xee\xf2\xe4\xe0\xeb \xec\xee\xed\xe5\xf2\xf3" // "Яйцеглот отдал монету"
+#define sO_EggGulper "\xdf\xe9\xf6\xe5\xe3\xeb\xee\xf2" // "Яйцеглот"
+#define sO_EggCracker "\xdf\xe9\xf6\xe5\xea\xee\xeb" // "Яйцекол"
+#define sO_NotCarryingEgg "\xdf\xe9\xf6\xee \xed\xe5 \xed\xe5\xf1\xe5\xf2" // "Яйцо не неÑет"
+#define sO_Egg1 "\xdf\xe9\xf6\xee\x31" // "Яйцо1"
+#define sO_Egg2 "\xdf\xe9\xf6\xee\x32" // "Яйцо2"
+#define sO_Egg3 "\xdf\xe9\xf6\xee\x33" // "Яйцо3"
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_OBJECTNAMES_H */
diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
new file mode 100644
index 0000000000..a12851e63b
--- /dev/null
+++ b/engines/fullpipe/objects.h
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_OBJECTS_H
+#define FULLPIPE_OBJECTS_H
+
+#include "fullpipe/utils.h"
+
+namespace Fullpipe {
+
+class MessageQueue;
+class SceneTagList;
+
+class GameProject : public CObject {
+ public:
+ int _field_4;
+ char *_headerFilename;
+ SceneTagList *_sceneTagList;
+ int _field_10;
+
+ public:
+ GameProject();
+ ~GameProject();
+ virtual bool load(MfcArchive &file);
+};
+
+struct PicAniInfo {
+ int32 type;
+ int16 objectId;
+ int16 field_6;
+ int32 field_8;
+ int16 sceneId;
+ int16 field_E;
+ int32 ox;
+ int32 oy;
+ int32 priority;
+ int16 staticsId;
+ int16 movementId;
+ int16 dynamicPhaseIndex;
+ int16 flags;
+ int32 field_24;
+ int32 someDynamicPhaseIndex;
+
+ bool load(MfcArchive &file);
+};
+
+union VarValue {
+ float floatValue;
+ int32 intValue;
+ char *stringValue;
+};
+
+class GameVar : public CObject {
+ public:
+ GameVar *_nextVarObj;
+ GameVar *_prevVarObj;
+ GameVar *_parentVarObj;
+ GameVar *_subVars;
+ GameVar *_field_14;
+ char *_varName;
+ VarValue _value;
+ int _varType;
+
+ public:
+ GameVar();
+ virtual bool load(MfcArchive &file);
+ GameVar *getSubVarByName(const char *name);
+ bool setSubVarAsInt(const char *name, int value);
+ int getSubVarAsInt(const char *name);
+ GameVar *addSubVarAsInt(const char *name, int value);
+ bool addSubVar(GameVar *subvar);
+ int getSubVarsCount();
+ GameVar *getSubVarByIndex(int idx);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_OBJECTS_H */
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
new file mode 100644
index 0000000000..3831831866
--- /dev/null
+++ b/engines/fullpipe/scene.cpp
@@ -0,0 +1,691 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/gameloader.h"
+
+#include "fullpipe/constants.h"
+
+#include "common/algorithm.h"
+
+namespace Fullpipe {
+
+Scene *FullpipeEngine::accessScene(int sceneId) {
+ SceneTag *t = 0;
+
+ for (SceneTagList::iterator s = _gameProject->_sceneTagList->begin(); s != _gameProject->_sceneTagList->end(); ++s) {
+ if (s->_sceneId == sceneId) {
+ t = &(*s);
+ break;
+ }
+ }
+
+ if (!t)
+ return 0;
+
+ if (!t->_scene) {
+ t->loadScene();
+ }
+
+ return t->_scene;
+}
+
+bool SceneTagList::load(MfcArchive &file) {
+ debug(5, "SceneTagList::load()");
+
+ int numEntries = file.readUint16LE();
+
+ for (int i = 0; i < numEntries; i++) {
+ SceneTag *t = new SceneTag();
+ t->load(file);
+ push_back(*t);
+ }
+
+ return true;
+}
+
+SceneTag::SceneTag() {
+ _field_4 = 0;
+ _scene = 0;
+ _tag = 0;
+ _sceneId = 0;
+}
+
+bool SceneTag::load(MfcArchive &file) {
+ debug(5, "SceneTag::load()");
+
+ _field_4 = 0;
+ _scene = 0;
+
+ _sceneId = file.readUint16LE();
+
+ _tag = file.readPascalString();
+
+ debug(6, "sceneId: %d tag: %s", _sceneId, _tag);
+
+ return true;
+}
+
+SceneTag::~SceneTag() {
+ free(_tag);
+}
+
+void SceneTag::loadScene() {
+ char *archname = genFileName(0, _sceneId, "nl");
+
+ Common::Archive *arch = makeNGIArchive(archname);
+
+ char *fname = genFileName(0, _sceneId, "sc");
+
+ Common::SeekableReadStream *file = arch->createReadStreamForMember(fname);
+
+ _scene = new Scene();
+
+ MfcArchive archive(file);
+
+ _scene->load(archive);
+
+ if (_scene->_shadows)
+ _scene->_shadows->init();
+
+ delete file;
+
+ g_fullpipe->_currArchive = 0;
+
+ free(fname);
+ free(archname);
+}
+
+Scene::Scene() {
+ _sceneId = 0;
+ _field_BC = 0;
+ _shadows = 0;
+ _soundList = 0;
+ _libHandle = 0;
+ _sceneName = 0;
+}
+
+bool Scene::load(MfcArchive &file) {
+ debug(5, "Scene::load()");
+
+ Background::load(file);
+
+ _sceneId = file.readUint16LE();
+
+ _sceneName = file.readPascalString();
+ debug(0, "scene: <%s> %d", transCyrillic((byte *)_sceneName), _sceneId);
+
+ int count = file.readUint16LE();
+ debug(7, "scene.ani: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int aniNum = file.readUint16LE();
+ char *aniname = genFileName(0, aniNum, "ani");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(aniname);
+
+ StaticANIObject *ani = new StaticANIObject();
+
+ MfcArchive archive(f);
+
+ ani->load(archive);
+ ani->_sceneId = _sceneId;
+
+ _staticANIObjectList1.push_back(ani);
+
+ delete f;
+ free(aniname);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "scene.mq: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int qNum = file.readUint16LE();
+ char *qname = genFileName(0, qNum, "qu");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(qname);
+ MfcArchive archive(f);
+
+ archive.readUint16LE(); // Skip 2 bytes
+
+ MessageQueue *mq = new MessageQueue();
+
+ mq->load(archive);
+
+ _messageQueueList.push_back(mq);
+
+ delete f;
+ free(qname);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "scene.fa: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ // There are no .FA files
+ assert(0);
+ }
+
+ _libHandle = g_fullpipe->_currArchive;
+
+ if (_picObjList.size() > 0 && _bgname && strlen(_bgname) > 1) {
+ char fname[260];
+
+ strcpy(fname, _bgname);
+ strcpy(strrchr(fname, '.') + 1, "col");
+
+ MemoryObject *col = new MemoryObject();
+ col->loadFile(fname);
+
+ _palette = col;
+ }
+
+ char *shdname = genFileName(0, _sceneId, "shd");
+
+ Shadows *shd = new Shadows();
+
+ if (shd->loadFile(shdname))
+ _shadows = shd;
+
+ free(shdname);
+
+ char *slsname = genFileName(0, _sceneId, "sls");
+
+ if (g_fullpipe->_soundEnabled) {
+ _soundList = new SoundList();
+
+ if (g_fullpipe->_flgSoundList) {
+ char *nlname = genFileName(17, _sceneId, "nl");
+
+ _soundList->loadFile(slsname, nlname);
+
+ free(nlname);
+ } else {
+ _soundList->loadFile(slsname, 0);
+ }
+ }
+
+ free(slsname);
+
+ initStaticANIObjects();
+
+ if (file.size() - file.pos() > 0)
+ error("Scene::load (%d bytes left)", file.size() - file.pos());
+
+ return true;
+}
+
+void Scene::initStaticANIObjects() {
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ ((StaticANIObject *)_staticANIObjectList1[i])->initMovements();
+}
+
+void Scene::init() {
+ _x = 0;
+ _y = 0;
+
+ g_fullpipe->_sceneRect.moveTo(0, 0);
+
+ for (uint i = 0; i < _picObjList.size(); i++)
+ ((PictureObject *)_picObjList[i])->clearFlags();
+
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ ((StaticANIObject *)_staticANIObjectList1[i])->clearFlags();
+
+ if (_staticANIObjectList2.size() != _staticANIObjectList1.size()) {
+ _staticANIObjectList2.clear();
+
+ for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s)
+ _staticANIObjectList2.push_back(*s);
+ }
+}
+
+StaticANIObject *Scene::getAniMan() {
+ StaticANIObject *aniMan = getStaticANIObject1ById(ANI_MAN, -1);
+
+ deleteStaticANIObject(aniMan);
+
+ return aniMan;
+}
+
+StaticANIObject *Scene::getStaticANIObject1ById(int obj, int a3) {
+ for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s) {
+ StaticANIObject *o = (StaticANIObject *)*s;
+ if (o->_id == obj && (a3 == -1 || o->_okeyCode == a3))
+ return o;
+ }
+
+ return 0;
+}
+
+StaticANIObject *Scene::getStaticANIObject1ByName(char *name, int a3) {
+ for (uint n = 0; n < _staticANIObjectList1.size(); n++) {
+ StaticANIObject *o = (StaticANIObject *)_staticANIObjectList1[n];
+ if (!strcmp(o->_objectName, name) && (a3 == -1 || o->_okeyCode == a3))
+ return o;
+ }
+
+ return 0;
+}
+
+void Scene::deleteStaticANIObject(StaticANIObject *obj) {
+ for (uint n = 0; n < _staticANIObjectList1.size(); n++)
+ if ((StaticANIObject *)_staticANIObjectList1[n] == obj) {
+ _staticANIObjectList1.remove_at(n);
+ break;
+ }
+
+ for (uint n = 0; n < _staticANIObjectList2.size(); n++)
+ if ((StaticANIObject *)_staticANIObjectList2[n] == obj) {
+ _staticANIObjectList2.remove_at(n);
+ break;
+ }
+}
+
+void Scene::addStaticANIObject(StaticANIObject *obj, bool addList2) {
+ if (obj->_okeyCode)
+ obj->renumPictures(&_staticANIObjectList1);
+
+ _staticANIObjectList1.push_back(obj);
+
+ if (addList2) {
+ if (!obj->_okeyCode)
+ obj->clearFlags();
+
+ _staticANIObjectList2.push_back(obj);
+ }
+}
+
+void Scene::setPictureObjectsFlag4() {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ ((PictureObject *)_picObjList[i])->_flags |= 4;
+ }
+}
+
+PictureObject *Scene::getPictureObjectById(int objId, int flags) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_okeyCode == flags)
+ return (PictureObject *)_picObjList[i];
+ }
+
+ return 0;
+}
+
+PictureObject *Scene::getPictureObjectByName(const char *objName, int flags) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (!strcmp(((PictureObject *)_picObjList[i])->_objectName, objName) && (((PictureObject *)_picObjList[i])->_okeyCode == flags || flags == -1))
+ return (PictureObject *)_picObjList[i];
+ }
+
+ return 0;
+}
+
+void Scene::deletePictureObject(PictureObject *obj) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i]) == obj) {
+ _picObjList.remove_at(i);
+ delete obj;
+
+ return;
+ }
+ }
+}
+
+MessageQueue *Scene::getMessageQueueById(int messageId) {
+ for (uint i = 0; i < _messageQueueList.size(); i++)
+ if (((MessageQueue *)_messageQueueList[i])->_dataId == messageId)
+ return (MessageQueue *)_messageQueueList[i];
+
+ return 0;
+}
+
+MessageQueue *Scene::getMessageQueueByName(char *name) {
+ for (uint i = 0; i < _messageQueueList.size(); i++)
+ if (!strcmp(((MessageQueue *)_messageQueueList[i])->_queueName, name))
+ return (MessageQueue *)_messageQueueList[i];
+
+ return 0;
+}
+
+void Scene::preloadMovements(GameVar *var) {
+ GameVar *preload = var->getSubVarByName("PRELOAD");
+ if (!preload)
+ return;
+
+ for (GameVar *i = preload->_subVars; i; i = i->_nextVarObj) {
+ StaticANIObject *ani = getStaticANIObject1ByName(i->_varName, -1);
+
+ if (ani) {
+ GameVar *subVars = i->_subVars;
+
+ if (subVars) {
+ for (;subVars; subVars = subVars->_nextVarObj) {
+ Movement *mov = ani->getMovementByName(subVars->_varName);
+
+ if (mov)
+ mov->loadPixelData();
+ }
+ } else {
+ ani->loadMovementsPixelData();
+ }
+ }
+ }
+}
+
+void Scene::initObjectCursors(const char *varname) {
+ GameVar *cursorsVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("CURSORS");
+
+ if (!cursorsVar || !cursorsVar->_subVars)
+ return;
+
+ int maxId = 0;
+ int minId = 0xffff;
+
+ for (GameVar *sub = cursorsVar->_subVars; sub; sub = sub->_nextVarObj) {
+ GameObject *obj = getPictureObjectByName(sub->_varName, -1);
+
+ if (obj || (obj = getStaticANIObject1ByName(sub->_varName, -1)) != 0) {
+ if (obj->_id < minId)
+ minId = obj->_id;
+ if (obj->_id > maxId)
+ maxId = obj->_id;
+ }
+ }
+
+ g_fullpipe->_minCursorId = minId;
+ g_fullpipe->_maxCursorId = maxId;
+
+ g_fullpipe->_objectIdCursors.resize(maxId - minId + 1);
+
+ for (GameVar *sub = cursorsVar->_subVars; sub; sub = sub->_nextVarObj) {
+ GameObject *obj = getPictureObjectByName(sub->_varName, -1);
+
+ if (!obj)
+ obj = getStaticANIObject1ByName(sub->_varName, -1);
+
+ PictureObject *pic = getGameLoaderInventory()->getScene()->getPictureObjectByName(sub->_value.stringValue, -1);
+
+ if (obj && pic)
+ g_fullpipe->_objectIdCursors[obj->_id - minId] = pic->_id;
+ }
+}
+
+bool Scene::compareObjPriority(const void *p1, const void *p2) {
+ if (((const StaticANIObject *)p1)->_priority > ((const StaticANIObject *)p2)->_priority)
+ return true;
+
+ return false;
+}
+
+void Scene::objectList_sortByPriority(PtrList &list) {
+ Common::sort(list.begin(), list.end(), Scene::compareObjPriority);
+}
+
+void Scene::draw() {
+ debug(0, ">>>>> Scene::draw()");
+ updateScrolling();
+
+ drawContent(60000, 0, true);
+
+ objectList_sortByPriority(_staticANIObjectList2);
+
+ for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
+ ((StaticANIObject *)*s)->draw2();
+ }
+
+ int priority = -1;
+ for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
+ drawContent(((StaticANIObject *)*s)->_priority, priority, false);
+ ((StaticANIObject *)*s)->draw();
+
+ priority = ((StaticANIObject *)*s)->_priority;
+ }
+
+ drawContent(-1, priority, false);
+}
+
+void Scene::updateScrolling() {
+ debug(0, "STUB Scene::updateScrolling()");
+}
+
+void Scene::updateScrolling2() {
+ warning("STUB Scene::updateScrolling2()");
+}
+
+StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) {
+ StaticANIObject *res = 0;
+
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++) {
+ StaticANIObject *p = (StaticANIObject *)_staticANIObjectList1[i];
+ int pixel;
+
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->getPixelAtPos(x, y, &pixel) &&
+ (!res || res->_priority >= p->_priority))
+ res = p;
+ }
+
+ return res;
+}
+
+PictureObject *Scene::getPictureObjectAtPos(int x, int y) {
+ PictureObject *res = 0;
+
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ PictureObject *p = (PictureObject *)_picObjList[i];
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->isPixelHitAtPos(x, y) &&
+ (!res || res->_priority >= p->_priority))
+ res = p;
+ }
+
+ return res;
+}
+
+int Scene::getPictureObjectIdAtPos(int x, int y) {
+ PictureObject *resp = 0;
+ int res = 0;
+
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ PictureObject *p = (PictureObject *)_picObjList[i];
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->isPixelHitAtPos(x, y) &&
+ (!res || resp->_priority >= p->_priority)) {
+ resp = p;
+ res = p->_id;
+ }
+ }
+
+ return res;
+}
+
+void Scene::update(int counterdiff) {
+ debug(0, "Scene::update(%d)", counterdiff);
+
+ for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s)
+ ((StaticANIObject *)*s)->update(counterdiff);
+}
+
+void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
+ if (!_picObjList.size() && !_bigPictureArray1Count)
+ return;
+
+ if (_palette) {
+ g_fullpipe->_globalPalette = _palette->_data;
+ }
+
+ debug(8, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
+
+ if (_picObjList.size() > 2) { // We need to z-sort them
+ objectList_sortByPriority(_picObjList);
+ }
+
+ if (minPri == -1 && _picObjList.size())
+ minPri = ((PictureObject *)_picObjList.back())->_priority - 1;
+
+ if (maxPri == -1)
+ maxPri = 60000;
+
+ debug(8, "-> Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
+
+ Common::Point point;
+
+ debug(8, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size());
+ if (drawBg && _bigPictureArray1Count && _picObjList.size()) {
+
+ _bigPictureArray[0][0]->getDimensions(&point);
+
+ int width = point.x;
+ int height = point.y;
+
+ debug(8, "w: %d h:%d", width, height);
+
+ ((PictureObject *)_picObjList[0])->getDimensions(&point);
+
+ debug(8, "w2: %d h2:%d", point.x, point.y);
+
+ int bgStX = g_fullpipe->_sceneRect.left % point.x;
+
+ if (bgStX < 0)
+ bgStX += point.x;
+
+ int bgNumX = bgStX / width;
+ int bgOffsetX = bgStX % width;
+
+ int bgStY = g_fullpipe->_sceneRect.top % point.y;
+
+ if (bgStY < 0)
+ bgStY += point.y;
+
+ int bgNumY = bgStY / height;
+ int bgOffsetY = bgStY % height;
+
+ int bgPosX = g_fullpipe->_sceneRect.left - bgOffsetX;
+
+ if (bgPosX < g_fullpipe->_sceneRect.right - 1) {
+ while (1) {
+ int v25 = bgNumY;
+ for (int y = g_fullpipe->_sceneRect.top - bgOffsetY; y < g_fullpipe->_sceneRect.bottom - 1;) {
+ BigPicture *v27 = _bigPictureArray[bgNumX][v25];
+ v27->draw(bgPosX, y, 0, 0);
+ y += v27->getDimensions(&point)->y;
+ v25++;
+
+ if (v25 >= _bigPictureArray2Count) {
+ if (!(((PictureObject *)_picObjList[0])->_flags & 0x20))
+ break;
+ v25 = 0;
+ }
+ }
+ _bigPictureArray[bgNumX][0]->getDimensions(&point);
+ int v32 = point.x + bgPosX;
+ bgPosX += point.x;
+ bgNumX++;
+
+ if (bgNumX >= _bigPictureArray1Count) {
+ if (!(((PictureObject *)_picObjList[0])->_flags & 0x2))
+ break;
+ bgNumX = 0;
+ }
+ if (v32 >= g_fullpipe->_sceneRect.right - 1)
+ break;
+ }
+ }
+ }
+
+
+ for (uint i = 1; i < _picObjList.size(); i++) {
+ PictureObject *obj = (PictureObject *)_picObjList[i];
+
+ debug(8, "pri: %d", obj->_priority);
+ if (obj->_priority < minPri || obj->_priority >= maxPri)
+ continue;
+
+ int objX = obj->_ox;
+ int objY = obj->_oy;
+
+ debug(8, "obj: %d %d", objX, objY);
+
+ obj->getDimensions(&point);
+
+ int width = point.x;
+ int height = point.y;
+
+ if (obj->_flags & 8) {
+ while (objX > g_fullpipe->_sceneRect.right) {
+ objX -= width;
+ obj->setOXY(objX, objY);
+ }
+ for (int j = width + objX; width + objX < g_fullpipe->_sceneRect.left; j = width + objX) {
+ objX = j;
+ obj->setOXY(j, objY);
+ }
+ }
+
+ if (obj->_flags & 0x10) {
+ while (objY > g_fullpipe->_sceneRect.bottom) {
+ objY -= height;
+ obj->setOXY(objX, objY);
+ }
+ for (int j = objY + height; objY + height < g_fullpipe->_sceneRect.top; j = objY + height) {
+ objY = j;
+ obj->setOXY(objX, j);
+ }
+ }
+ if (obj->_flags & 4)
+ obj->draw();
+
+ if (obj->_flags & 2) {
+ if (objX > g_fullpipe->_sceneRect.left) {
+ obj->setOXY(objX - width, objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ if (width + objX < g_fullpipe->_sceneRect.right) {
+ obj->setOXY(width + objX, objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ }
+
+ if (obj->_flags & 0x20) {
+ if (objY > g_fullpipe->_sceneRect.top) {
+ obj->setOXY(objX, objY - height);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ if (height + objY < g_fullpipe->_sceneRect.bottom) {
+ obj->setOXY(objX, height + objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ }
+ }
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
new file mode 100644
index 0000000000..db0da5db31
--- /dev/null
+++ b/engines/fullpipe/scene.h
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SCENE_H
+#define FULLPIPE_SCENE_H
+
+#include "fullpipe/gfx.h"
+
+namespace Fullpipe {
+
+class MessageQueue;
+
+class Scene : public Background {
+ public:
+ PtrList _staticANIObjectList1;
+ PtrList _staticANIObjectList2;
+ PtrList _messageQueueList;
+ PtrList _faObjectList;
+ Shadows *_shadows;
+ SoundList *_soundList;
+ int16 _sceneId;
+ char *_sceneName;
+ int _field_BC;
+ NGIArchive *_libHandle;
+
+ public:
+ Scene();
+
+ virtual bool load(MfcArchive &file);
+
+ void initStaticANIObjects();
+ void init();
+ void draw();
+ void drawContent(int minPri, int maxPri, bool drawBG);
+ void updateScrolling();
+ void updateScrolling2();
+
+ void update(int counterdiff);
+
+ StaticANIObject *getAniMan();
+ StaticANIObject *getStaticANIObject1ById(int obj, int a3);
+ StaticANIObject *getStaticANIObject1ByName(char *name, int a3);
+ MessageQueue *getMessageQueueById(int messageId);
+ MessageQueue *getMessageQueueByName(char *name);
+
+ void deleteStaticANIObject(StaticANIObject *obj);
+ void addStaticANIObject(StaticANIObject *obj, bool addList2);
+
+ void setPictureObjectsFlag4();
+ PictureObject *getPictureObjectById(int objId, int flags);
+ PictureObject *getPictureObjectByName(const char *name, int keyCode);
+ void deletePictureObject(PictureObject *obj);
+ void preloadMovements(GameVar *var);
+
+ StaticANIObject *getStaticANIObjectAtPos(int x, int y);
+ PictureObject *getPictureObjectAtPos(int x, int y);
+ int getPictureObjectIdAtPos(int x, int y);
+
+ void initObjectCursors(const char *name);
+
+ private:
+ static bool compareObjPriority(const void *p1, const void *p2);
+ void objectList_sortByPriority(PtrList &list);
+};
+
+class SceneTag : public CObject {
+ public:
+ int _field_4;
+ char *_tag;
+ Scene *_scene;
+ int16 _sceneId;
+
+ public:
+ SceneTag();
+ ~SceneTag();
+
+ virtual bool load(MfcArchive &file);
+ void loadScene();
+};
+
+class SceneTagList : public Common::List<SceneTag>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SCENE_H */
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
new file mode 100644
index 0000000000..a0f90af532
--- /dev/null
+++ b/engines/fullpipe/scenes.cpp
@@ -0,0 +1,712 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/utils.h"
+#include "fullpipe/objects.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/input.h"
+#include "fullpipe/behavior.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+Vars::Vars() {
+ sceneIntro_aniin1man = 0;
+ sceneIntro_needSleep = true;
+ sceneIntro_needGetup = false;
+ sceneIntro_skipIntro = true;
+ sceneIntro_playing = false;
+ sceneIntro_needBlackout = false;
+
+ swallowedEgg1 = 0;
+ swallowedEgg2 = 0;
+ swallowedEgg3 = 0;
+
+ scene01_picSc01Osk = 0;
+ scene01_picSc01Osk2 = 0;
+
+ scene02_guvTheDrawer = 0;
+ scene02_boxDelay = 0;
+ scene02_boxOpen = false;
+
+ scene03_eggeater = 0;
+ scene03_domino = 0;
+
+ scene04_bottle = 0;
+ scene04_hand = 0;
+ scene04_plank = 0;
+ scene04_clock = 0;
+ scene04_hand = 0;
+ scene04_spring = 0;
+ scene04_mamasha = 0;
+ scene04_boot = 0;
+ scene04_speaker = 0;
+
+ scene04_ladder = 0;
+ scene04_coinPut = false;
+ scene04_soundPlaying = false;
+ scene04_dynamicPhaseIndex = 0;
+
+ scene04_sceneClickX = 0;
+ scene04_sceneClickY = 0;
+
+ scene04_dudePosX = 0;
+ scene04_dudePosY = 0;
+
+ scene04_var01 = 0;
+ scene04_var02 = 0;
+ scene04_var04 = 0;
+ scene04_walkingKozyawka = 0;
+ scene04_var06 = 0;
+ scene04_var07 = 0;
+ scene04_var08 = 0;
+ scene04_var09 = 0;
+ scene04_var10 = 0;
+ scene04_var11 = 0;
+ scene04_var12 = 0;
+ scene04_var13 = 0;
+ scene04_var14 = 0;
+ scene04_var15 = 0;
+ scene04_speakerVariant = 0;
+ scene04_speakerPhase = 0;
+ scene04_var18 = 0;
+ scene04_var19 = 0;
+ scene04_var20 = 0;
+ scene04_var24 = 0;
+ scene04_var26 = 0;
+
+ selector = 0;
+}
+
+static int scenes[] = {
+ SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7, SC_8, SC_9, SC_10,
+ SC_11, SC_12, SC_13, SC_14, SC_15, SC_16, SC_17, SC_18, SC_19, SC_20,
+ SC_21, SC_22, SC_23, SC_24, SC_25, SC_26, SC_27, SC_28, SC_29, SC_30,
+ SC_31, SC_32, SC_33, SC_34, SC_35, SC_36, SC_37, SC_38, SC_DBGMENU
+};
+
+int FullpipeEngine::convertScene(int scene) {
+ if (!scene || scene >= SC_1)
+ return scene;
+
+ if (scene < 1 || scene > 39)
+ return SC_1;
+
+ return scenes[scene - 1];
+}
+
+bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
+ GameVar *sceneVar;
+ Common::Point sceneDim;
+
+ Scene *scene = accessScene(entrance->_sceneId);
+
+ if (!scene)
+ return 0;
+
+ ((PictureObject *)scene->_picObjList.front())->getDimensions(&sceneDim);
+ _sceneWidth = sceneDim.x;
+ _sceneHeight = sceneDim.y;
+
+ _sceneRect.top = 0;
+ _sceneRect.left = 0;
+ _sceneRect.right = 799;
+ _sceneRect.bottom = 599;
+
+ scene->_x = 0;
+ scene->_y = 0;
+
+ _aniMan->setOXY(0, 0);
+ _aniMan->clearFlags();
+ _aniMan->_callback1 = 0;
+ _aniMan->_callback2 = 0;
+ _aniMan->_shadowsOn = 1;
+
+ _scrollSpeed = 8;
+
+ _isSaveAllowed = true;
+ _updateFlag = true;
+ _flgCanOpenMap = true;
+
+ if (entrance->_sceneId == SC_DBGMENU) {
+ _inventoryScene = 0;
+ } else {
+ _gameLoader->loadScene(SC_INV);
+ getGameLoaderInventory()->rebuildItemRects();
+ _inventoryScene = getGameLoaderInventory()->getScene();
+ }
+ if (_soundEnabled) {
+ if (scene->_soundList) {
+ _currSoundListCount = 2;
+ _currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
+ _currSoundList1[1] = scene->_soundList;
+
+ for (int i = 0; i < scene->_soundList->getCount(); i++) {
+ scene->_soundList->getSoundByIndex(i)->updateVolume();
+ }
+ } else {
+ _currSoundListCount = 1;
+ _currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
+ }
+ }
+
+ getGameLoaderInteractionController()->sortInteractions(scene->_sceneId);
+ _currentScene = scene;
+ scene->addStaticANIObject(_aniMan, 1);
+ _scene2 = scene;
+ _aniMan->_movement = 0;
+ _aniMan->_statics = _aniMan->getStaticsById(ST_MAN_EMPTY);
+ _aniMan->setOXY(0, 0);
+
+ _aniMan2 = _aniMan;
+ MctlCompound *cmp = getSc2MctlCompoundBySceneId(entrance->_sceneId);
+ cmp->initMovGraph2();
+ cmp->addObject(_aniMan);
+ cmp->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+ setInputDisabled(0);
+
+ scene->setPictureObjectsFlag4();
+
+ for (PtrList::iterator s = scene->_staticANIObjectList1.begin(); s != scene->_staticANIObjectList1.end(); ++s) {
+ StaticANIObject *o = (StaticANIObject *)*s;
+ o->setFlags(o->_flags & 0xFE7F);
+ }
+
+ PictureObject *p = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0);
+ p->setFlags(p->_flags & 0xFFFB);
+
+ removeMessageHandler(2, -1);
+ _updateScreenCallback = 0;
+
+ switch (entrance->_sceneId) {
+ case SC_INTRO1:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_INTRO1");
+ scene->preloadMovements(sceneVar);
+ sceneIntro_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_INTRO1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandlerIntro, 2);
+ _updateCursorCallback = sceneIntro_updateCursor;
+ break;
+
+ case SC_1:
+ scene01_fixEntrance();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_1");
+ scene->preloadMovements(sceneVar);
+ scene01_initScene(scene, entrance->_field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler01, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_2:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_2");
+ scene->preloadMovements(sceneVar);
+ scene02_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_2");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler02, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_3:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_3");
+ scene->preloadMovements(sceneVar);
+ scene03_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_3");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler03, 2);
+ scene03_setEaterState();
+ _updateCursorCallback = scene03_updateCursor;
+ break;
+
+ case SC_4:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_4");
+ scene->preloadMovements(sceneVar);
+ scene04_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_4");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler04, 2, 2);
+ _updateCursorCallback = scene04_updateCursor;
+ break;
+
+#if 0
+ case SC_5:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_5");
+ scene->preloadMovements(sceneVar);
+ scene05_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_5");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler05, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_6:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_6");
+ scene->preloadMovements(sceneVar);
+ scene06_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_6");
+ setSceneMusicParameters(sceneVar);
+ sub_415300();
+ insertMessageHandler(sceneHandler06, 2, 2);
+ _updateCursorCallback = scene06_updateCursor;
+ break;
+
+ case SC_7:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_7");
+ scene->preloadMovements(sceneVar);
+ scene07_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_7");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler07, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_8:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_8");
+ scene->preloadMovements(sceneVar);
+ scene08_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_8");
+ setSceneMusicParameters(sceneVar);
+ sub_416890();
+ addMessageHandler(sceneHandler08, 2);
+ _updateCursorCallback = scene08_updateCursor;
+ break;
+
+ case SC_9:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_9");
+ scene->preloadMovements(sceneVar);
+ scene09_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_9");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler09, 2, 2);
+ _updateCursorCallback = scene09_updateCursor;
+ break;
+
+ case SC_10:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_10");
+ scene->preloadMovements(sceneVar);
+ scene10_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_10");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler10, 2, 2);
+ _updateCursorCallback = scene10_updateCursor;
+ break;
+
+ case SC_11:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_11");
+ scene->preloadMovements(sceneVar);
+ scene11_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_11");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler11, 2, 2);
+ scene11_sub_41A980();
+ _updateCursorCallback = scene11_updateCursor;
+ break;
+
+ case SC_12:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_12");
+ scene->preloadMovements(sceneVar);
+ scene12_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_12");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler12, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_13:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_13");
+ scene->preloadMovements(sceneVar);
+ scene13_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_13");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler13, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_14:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_14");
+ scene->preloadMovements(sceneVar);
+ scene14_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_14");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler14, 2, 2);
+ scene14_sub_41D2B0();
+ _updateCursorCallback = scene14_updateCursor;
+ break;
+
+ case SC_15:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_15");
+ scene->preloadMovements(sceneVar);
+ scene15_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_15");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler15, 2, 2);
+ _updateCursorCallback = scene15_updateCursor;
+ break;
+
+ case SC_16:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_16");
+ scene->preloadMovements(sceneVar);
+ scene16_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_16");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler16, 2);
+ _updateCursorCallback = scene16_updateCursor;
+ break;
+
+ case SC_17:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_17");
+ scene->preloadMovements(sceneVar);
+ scene17_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_17");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler17, 2);
+ scene17_sub_41F060();
+ _updateCursorCallback = scene17_updateCursor;
+ break;
+
+ case SC_18:
+ sub_40E1B0();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_18");
+ scene->preloadMovements(sceneVar);
+ sub_4062D0();
+ if (dword_476C38)
+ scene18_initScene1(scene);
+ else
+ scene18_initScene2(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_18");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler18, 2, 2);
+ _updateCursorCallback = scene18_updateCursor;
+ break;
+
+ case SC_19:
+ if (!g_scene3) {
+ g_scene3 = accessScene(SC_18);
+ getGameLoader()->loadScene(SC_18);
+ scene18_initScene2(g_scene3);
+ sub_40C5F0();
+ scene19_sub_420B10(g_scene3, entrance->field_4);
+ dword_476C38 = 1;
+ }
+ sub_40C650();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_19");
+ scene->preloadMovements(sceneVar);
+ sub_4062D0();
+ if (dword_476C38)
+ scene18_initScene1(scene);
+ else
+ scene19_initScene2();
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_19");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler19, 2);
+ scene19_sub_4211D0(scene);
+ _updateCursorCallback = scene19_updateCursor;
+ break;
+
+ case SC_20:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_20");
+ scene->preloadMovements(sceneVar);
+ scene20_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_20");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler20, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_21:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_21");
+ scene->preloadMovements(sceneVar);
+ scene21_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_21");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler21, 2, 2);
+ _updateCursorCallback = scene21_updateCursor;
+ break;
+
+ case SC_22:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_22");
+ scene->preloadMovements(sceneVar);
+ scene22_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_22");
+ setSceneMusicParameters(sceneVar);
+ scene22_sub_4228A0();
+ insertMessageHandler(sceneHandler22, 2, 2);
+ _updateCursorCallback = scene22_updateCursor;
+ break;
+
+ case SC_23:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_23");
+ scene->preloadMovements(sceneVar);
+ scene23_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_23");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler23, 2, 2);
+ scene23_sub_423B00();
+ _updateCursorCallback = scene23_updateCursor;
+ break;
+
+ case SC_24:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_24");
+ scene->preloadMovements(sceneVar);
+ scene24_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_24");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler24, 2);
+ scene24_sub_423DD0();
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_25:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_25");
+ scene->preloadMovements(sceneVar);
+ scene25_initScene(scene, entrance->field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_25");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler25, 2);
+ scene25_sub_4253B0(scene, entrance->field_4);
+ _updateCursorCallback = scene25_updateCursor;
+ break;
+
+ case SC_26:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_26");
+ scene->preloadMovements(sceneVar);
+ scene26_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_26");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler26, 2, 2);
+ scene26_sub_426140(scene);
+ _updateCursorCallback = scene26_updateCursor;
+ break;
+
+ case SC_27:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_27");
+ scene->preloadMovements(sceneVar);
+ scene27_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_27");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler27, 2);
+ _updateCursorCallback = scene27_updateCursor;
+ break;
+
+ case SC_28:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_28");
+ scene->preloadMovements(sceneVar);
+ scene28_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_28");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler28, 2, 2);
+ _updateCursorCallback = scene28_updateCursor;
+ break;
+
+ case SC_29:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_29");
+ scene->preloadMovements(sceneVar);
+ scene29_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_29");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler29, 2);
+ _updateCursorCallback = scene29_updateCursor;
+ break;
+
+ case SC_30:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_30");
+ scene->preloadMovements(sceneVar);
+ scene30_initScene(scene, entrance->field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_30");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler30, 2);
+ _updateCursorCallback = scene30_updateCursor;
+ break;
+
+ case SC_31:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_31");
+ scene->preloadMovements(sceneVar);
+ scene31_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_31");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler31, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_32:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_32");
+ scene->preloadMovements(sceneVar);
+ scene32_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_32");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler32, 2, 2);
+ scene32_sub_42C5C0();
+ _updateCursorCallback = scene32_updateCursor;
+ break;
+
+ case SC_33:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_33");
+ scene->preloadMovements(sceneVar);
+ scene33_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_33");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler33, 2, 2);
+ scene33_sub_42CEF0();
+ _updateCursorCallback = scene33_updateCursor;
+ break;
+
+ case SC_34:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_34");
+ scene->preloadMovements(sceneVar);
+ scene34_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_34");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler34, 2, 2);
+ scene34_sub_42DEE0();
+ _updateCursorCallback = scene34_updateCursor;
+ break;
+
+ case SC_35:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_35");
+ scene->preloadMovements(sceneVar);
+ scene35_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_35");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler35, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_36:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_36");
+ scene->preloadMovements(sceneVar);
+ scene36_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_36");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler36, 2);
+ _updateCursorCallback = scene36_updateCursor;
+ break;
+
+ case SC_37:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_37");
+ scene->preloadMovements(sceneVar);
+ scene37_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_37");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler37, 2, 2);
+ _updateCursorCallback = scene37_updateCursor;
+ break;
+
+ case SC_38:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_38");
+ scene->preloadMovements(sceneVar);
+ scene38_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_38");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler38, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_FINAL1:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_FINAL1");
+ scene->preloadMovements(sceneVar);
+ sceneFinal1_initScene();
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_FINAL1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandlerFinal1, 2);
+ _updateCursorCallback = sceneFinal1_updateCursor;
+ break;
+#endif
+
+ case SC_DBGMENU:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_DBGMENU");
+ scene->preloadMovements(sceneVar);
+ sceneDbgMenu_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_DBGMENU");
+ addMessageHandler(sceneHandlerDbgMenu, 2);
+ break;
+
+ default:
+ _behaviorManager->initBehavior(0, 0);
+ break;
+ }
+
+ return true;
+}
+
+int defaultUpdateCursor() {
+ g_fullpipe->updateCursorCommon();
+
+ return g_fullpipe->_cursorId;
+}
+
+void FullpipeEngine::initArcadeKeys(const char *varname) {
+ warning("STUB: FullpipeEngine::initArcadeKeys(\"%s\")", varname);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h
new file mode 100644
index 0000000000..ed0da0a9db
--- /dev/null
+++ b/engines/fullpipe/scenes.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SCENES_H
+#define FULLPIPE_SCENES_H
+
+namespace Fullpipe {
+
+class StaticANIObject;
+
+int defaultUpdateCursor();
+
+int sceneIntro_updateCursor();
+void sceneIntro_initScene(Scene *sc);
+int sceneHandlerIntro(ExCommand *cmd);
+
+void scene01_fixEntrance();
+void scene01_initScene(Scene *sc, int entrance);
+int sceneHandler01(ExCommand *cmd);
+
+void scene02_initScene(Scene *sc);
+int sceneHandler02(ExCommand *ex);
+
+void scene03_setEaterState();
+int scene03_updateCursor();
+void scene03_initScene(Scene *sc);
+int sceneHandler03(ExCommand *cmd);
+
+int scene04_updateCursor();
+void scene04_initScene(Scene *sc);
+int sceneHandler04(ExCommand *cmd);
+
+void sceneDbgMenu_initScene(Scene *sc);
+int sceneHandlerDbgMenu(ExCommand *cmd);
+
+class Vars {
+public:
+ Vars();
+
+ GameVar *swallowedEgg1;
+ GameVar *swallowedEgg2;
+ GameVar *swallowedEgg3;
+
+ StaticANIObject *sceneIntro_aniin1man;
+ bool sceneIntro_needSleep;
+ bool sceneIntro_needGetup;
+ bool sceneIntro_skipIntro;
+ bool sceneIntro_playing;
+ bool sceneIntro_needBlackout;
+
+ PictureObject *scene01_picSc01Osk;
+ PictureObject *scene01_picSc01Osk2;
+
+ StaticANIObject *scene02_guvTheDrawer;
+ int scene02_boxDelay;
+ bool scene02_boxOpen;
+
+ StaticANIObject *scene03_eggeater;
+ StaticANIObject *scene03_domino;
+
+ PictureObject *scene04_bottle;
+ StaticANIObject *scene04_hand;
+ StaticANIObject *scene04_plank;
+ StaticANIObject *scene04_clock;
+ StaticANIObject *scene04_spring;
+ StaticANIObject *scene04_mamasha;
+ StaticANIObject *scene04_boot;
+ StaticANIObject *scene04_speaker;
+
+ Common::Point scene04_jumpingKozyawki[20];
+ Common::Point scene04_jumpRotateKozyawki[20];
+
+ Common::List<StaticANIObject *> scene04_kozyawkiObjList;
+ Common::List<GameObject *> scene04_bottleObjList;
+ Common::List<StaticANIObject *> scene04_kozyawkiAni;
+
+ int scene04_ladder;
+ bool scene04_coinPut;
+ bool scene04_soundPlaying;
+ int scene04_dynamicPhaseIndex;
+ int scene04_sceneClickX;
+ int scene04_sceneClickY;
+ int scene04_dudePosX;
+ int scene04_dudePosY;
+
+ int scene04_var01;
+ int scene04_var02;
+ int scene04_var04;
+ StaticANIObject *scene04_walkingKozyawka;
+ int scene04_var06;
+ int scene04_var07;
+ int scene04_var08;
+ int scene04_var09;
+ int scene04_var10;
+ int scene04_var11;
+ int scene04_var12;
+ int scene04_var13;
+ int scene04_var14;
+ int scene04_var15;
+ int scene04_speakerVariant;
+ int scene04_speakerPhase;
+ int scene04_var18;
+ int scene04_var19;
+ int scene04_var20;
+ StaticANIObject *scene04_var24;
+ int scene04_var26;
+
+ PictureObject *selector;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SCENES_H */
diff --git a/engines/fullpipe/scenes/scene01.cpp b/engines/fullpipe/scenes/scene01.cpp
new file mode 100644
index 0000000000..4181bbffe3
--- /dev/null
+++ b/engines/fullpipe/scenes/scene01.cpp
@@ -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.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene01_fixEntrance() {
+ GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+ if (var->getSubVarAsInt("Entrance") == TrubaLeft)
+ var->setSubVarAsInt("Entrance", TrubaRight);
+}
+
+void scene01_initScene(Scene *sc, int entrance) {
+ g_vars->scene01_picSc01Osk = sc->getPictureObjectById(PIC_SC1_OSK, 0);
+ g_vars->scene01_picSc01Osk->_flags &= 0xFFFB;
+
+ g_vars->scene01_picSc01Osk2 = sc->getPictureObjectById(PIC_SC1_OSK2, 0);
+ g_vars->scene01_picSc01Osk2->_flags &= 0xFFFB;
+
+ if (g_fullpipe->getObjectState(sO_EggCracker) == g_fullpipe->getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg)) {
+ PictureObject *pic = sc->getPictureObjectById(PIC_SC1_KUCHKA, 0);
+ if (pic)
+ pic->_flags &= 0xFFFB;
+ }
+
+ if (entrance != TrubaLeft) {
+ StaticANIObject *bootAnim = sc->getStaticANIObject1ById(ANI_BOOT_1, -1);
+ if (bootAnim)
+ bootAnim->_flags &= ~0x04;
+ }
+
+ g_fullpipe->lift_setButton(sO_Level2, ST_LBN_2N);
+}
+
+int sceneHandler01(ExCommand *cmd) {
+ int res = 0;
+
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ if (cmd->_messageNum > MSG_SC1_SHOWOSK) {
+ if (cmd->_messageNum == MSG_SC1_UTRUBACLICK)
+ handleObjectInteraction(g_fullpipe->_aniMan, g_fullpipe->_currentScene->getPictureObjectById(PIC_SC1_LADDER, 0), 0);
+
+ return 0;
+ }
+
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK) {
+ g_vars->scene01_picSc01Osk->_flags |= 4;
+
+ g_vars->scene01_picSc01Osk->_priority = 20;
+ g_vars->scene01_picSc01Osk2->_priority = 21;
+
+ return 0;
+ }
+
+ if (cmd->_messageNum != 0x21) {
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK2) {
+ g_vars->scene01_picSc01Osk2->_flags |= 4;
+ g_vars->scene01_picSc01Osk2->_priority = 20;
+ g_vars->scene01_picSc01Osk->_priority = 21;
+
+ return 0;
+ }
+
+ return 0;
+ }
+
+ if (g_fullpipe->_aniMan2) {
+ if (g_fullpipe->_aniMan2->_ox < g_fullpipe->_sceneRect.left + 200) {
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.left - 300;
+ }
+
+ if (g_fullpipe->_aniMan2->_ox > g_fullpipe->_sceneRect.right - 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.right + 300;
+
+ res = 1;
+ }
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ g_fullpipe->startSceneTrack();
+
+ return res;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene02.cpp b/engines/fullpipe/scenes/scene02.cpp
new file mode 100644
index 0000000000..dd01af4c4b
--- /dev/null
+++ b/engines/fullpipe/scenes/scene02.cpp
@@ -0,0 +1,137 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+
+namespace Fullpipe {
+
+void scene02_initScene(Scene *sc) {
+ g_vars->scene02_guvTheDrawer = sc->getStaticANIObject1ById(ANI_DADAYASHIK, -1);
+
+ if (g_fullpipe->getObjectState(sO_GuvTheDrawer) == g_fullpipe->getObjectEnumState(sO_GuvTheDrawer, sO_Sleeping)) {
+ Scene *s = g_fullpipe->_currentScene;
+
+ g_fullpipe->_currentScene = sc;
+ g_vars->scene02_guvTheDrawer->changeStatics2(ST_DYAS_LIES);
+ g_fullpipe->_currentScene = s;
+ }
+
+ g_vars->scene02_boxDelay = 0;
+
+ StaticANIObject *box = sc->getStaticANIObject1ById(ANI_SC2_BOX, -1);
+
+ if (box && box->_flags & 4) {
+ g_vars->scene02_boxOpen = false;
+ } else {
+ g_vars->scene02_boxOpen = true;
+ g_vars->scene02_boxDelay = 100 * g_fullpipe->_rnd->getRandomNumber(32767) + 150;
+ }
+
+ g_fullpipe->_floaters->init(g_fullpipe->_gameLoader->_gameVar->getSubVarByName("SC_2"));
+}
+
+void sceneHandler02_ladderClick() {
+ handleObjectInteraction(g_fullpipe->_aniMan2, g_fullpipe->_currentScene->getPictureObjectById(PIC_SC2_DTRUBA, 0), 0);
+}
+
+void sceneHandler02_showLadder() {
+ g_fullpipe->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags |= 4;
+}
+
+void sceneHandler02_hideLadder() {
+ g_fullpipe->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags &= 0xfffb;
+ g_fullpipe->_aniMan2->_priority = 25;
+}
+
+int sceneHandler02(ExCommand *ex) {
+ int res = 0;
+
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch(ex->_messageNum) {
+ case MSG_SC2_LADDERCLICK:
+ sceneHandler02_ladderClick();
+ return 0;
+
+ case MSG_SC2_SHOWLADDER:
+ sceneHandler02_showLadder();
+ return 0;
+
+ case MSG_SC2_PUTMANUP:
+ g_fullpipe->_aniMan2->_priority = 0;
+ return 0;
+
+ case MSG_SC2_HIDELADDER:
+ sceneHandler02_hideLadder();
+ return 0;
+
+ case 33:
+ if (g_fullpipe->_aniMan2) {
+ if (g_fullpipe->_aniMan2->_ox < g_fullpipe->_sceneRect.left + 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.left - 300;
+
+ if (g_fullpipe->_aniMan2->_ox > g_fullpipe->_sceneRect.right - 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ if (g_vars->scene02_boxOpen) {
+ if (g_vars->scene02_boxDelay >= 1) {
+ --g_vars->scene02_boxDelay;
+ } else if (g_fullpipe->_floaters->_array2.size() >= 1) {
+ if (g_fullpipe->_floaters->_array2[0]->val5 == -50) {
+ g_fullpipe->_floaters->stopAll();
+ g_vars->scene02_boxOpen = false;
+ g_vars->scene02_boxDelay = 100 * g_fullpipe->_rnd->getRandomNumber(32767) + 150;
+ } else {
+ g_fullpipe->_floaters->_array2[0]->val3 = -50;
+ }
+ } else {
+ g_fullpipe->_floaters->genFlies(g_fullpipe->_currentScene, g_fullpipe->_rnd->getRandomNumber(700) + 100, -50, 0, 0);
+ g_vars->scene02_boxDelay = 500 * g_fullpipe->_rnd->getRandomNumber(32767) + 1000;
+ }
+ }
+
+ g_fullpipe->_floaters->update();
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ g_fullpipe->startSceneTrack();
+ }
+
+ return res;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene03.cpp b/engines/fullpipe/scenes/scene03.cpp
new file mode 100644
index 0000000000..e9f8a240e8
--- /dev/null
+++ b/engines/fullpipe/scenes/scene03.cpp
@@ -0,0 +1,294 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+void FullpipeEngine::setSwallowedEggsState() {
+ GameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
+
+ g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
+ g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
+ g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+
+ g_vars->swallowedEgg1->_value.intValue = 0;
+ g_vars->swallowedEgg2->_value.intValue = 0;
+ g_vars->swallowedEgg3->_value.intValue = 0;
+}
+
+void scene03_initScene(Scene *sc) {
+ g_vars->scene03_eggeater = sc->getStaticANIObject1ById(ANI_EGGEATER, -1);
+ g_vars->scene03_domino = sc->getStaticANIObject1ById(ANI_DOMINO_3, -1);
+
+ GameVar *v = g_fullpipe->_gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
+
+ g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
+ g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
+ g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+
+ g_fullpipe->lift_setButton(sO_Level2, ST_LBN_2N);
+
+ g_fullpipe->lift_sub5(sc, QU_SC3_ENTERLIFT, QU_SC3_EXITLIFT);
+}
+
+void scene03_setEaterState() {
+ if (g_fullpipe->getObjectState(sO_EggGulperGaveCoin) == g_fullpipe->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes)) {
+ g_fullpipe->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_SLIM, QU_EGTR_SLIMSHOW, 0);
+ g_fullpipe->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID1, QU_EGTR_MD1_SHOW, 0);
+ g_fullpipe->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID2, QU_EGTR_MD2_SHOW, 0);
+ }
+}
+
+int scene03_updateCursor() {
+ g_fullpipe->updateCursorCommon();
+
+ if (g_fullpipe->_cursorId == PIC_CSR_DEFAULT && g_fullpipe->_objectIdAtCursor == PIC_SC3_DOMIN && g_vars->scene03_domino) {
+ if (g_vars->scene03_domino->_flags & 4)
+ g_fullpipe->_cursorId = PIC_CSR_ITN;
+ }
+
+ return g_fullpipe->_cursorId;
+}
+
+void sceneHandler03_eaterFat() {
+ g_vars->scene03_eggeater->_flags &= 0xFF7F;
+
+ g_vars->scene03_eggeater->startAnim(MV_EGTR_FATASK, 0, -1);
+}
+
+void sceneHandler03_swallowEgg(int item) {
+ if (!g_vars->swallowedEgg1->_value.intValue) {
+ g_vars->swallowedEgg1->_value.intValue = item;
+ } else if (!g_vars->swallowedEgg2->_value.intValue) {
+ g_vars->swallowedEgg2->_value.intValue = item;
+ } else if (!g_vars->swallowedEgg3->_value.intValue) {
+ g_vars->swallowedEgg3->_value.intValue = item;
+
+ g_fullpipe->setObjectState(sO_EggGulperGaveCoin, g_fullpipe->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes));
+
+ scene03_setEaterState();
+ }
+}
+
+void sceneHandler03_giveItem(ExCommand *ex) {
+ if (ex->_parentId == ANI_INV_EGGAPL || ex->_parentId == ANI_INV_EGGDOM ||
+ ex->_parentId == ANI_INV_EGGCOIN || ex->_parentId == ANI_INV_EGGBOOT ||
+ ex->_parentId == ANI_INV_EGGGLS)
+ sceneHandler03_swallowEgg(ex->_parentId);
+}
+
+int sceneHandler03_swallowedEgg1State() {
+ return g_vars->swallowedEgg1->_value.intValue;
+}
+
+void sceneHandler03_giveCoin(ExCommand *ex) {
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex->_parId);
+
+ if (mq && mq->getCount() > 0) {
+ ExCommand *ex0 = mq->getExCommandByIndex(0);
+ ExCommand *ex1 = mq->getExCommandByIndex(1);
+
+ if (sceneHandler03_swallowedEgg1State()) {
+ ex0->_messageKind = 1;
+ ex1->_messageKind = 1;
+
+ getGameLoaderInventory()->removeItem(ANI_INV_COIN, 1);
+ } else {
+ ex0->_messageKind = 0;
+ ex0->_excFlags |= 1;
+
+ ex1->_messageKind = 0;
+ ex1->_excFlags |= 1;
+
+ g_vars->scene03_eggeater->_flags &= 0xFF7Fu;
+ }
+ }
+}
+
+void sceneHandler03_goLadder() {
+ handleObjectInteraction(g_fullpipe->_aniMan, g_fullpipe->_currentScene->getPictureObjectById(PIC_SC3_LADDER, 0), 0);
+}
+
+void sceneHandler03_pushEggStack() {
+ g_vars->swallowedEgg1->_value.intValue = g_vars->swallowedEgg2->_value.intValue;
+ g_vars->swallowedEgg2->_value.intValue = g_vars->swallowedEgg3->_value.intValue;
+ g_vars->swallowedEgg3->_value.intValue = 0;
+
+ if (g_vars->swallowedEgg2->_value.intValue == ANI_INV_EGGBOOT
+ && g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL) {
+ g_vars->swallowedEgg1->_value.intValue = ANI_INV_EGGBOOT;
+ g_vars->swallowedEgg2->_value.intValue = ANI_INV_EGGAPL;
+ }
+}
+
+void sceneHandler03_releaseEgg() {
+ g_vars->scene03_eggeater->_flags &= 0xFF7F;
+
+ g_vars->scene03_eggeater->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler03_takeEgg(ExCommand *ex) {
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex->_parId);
+
+ if (mq && mq->getCount() > 0) {
+ ExCommand *ex0 = mq->getExCommandByIndex(0);
+ ExCommand *ex1 = mq->getExCommandByIndex(1);
+
+ int egg1 = sceneHandler03_swallowedEgg1State();
+
+ if (egg1 && ex0) {
+ ex0->_parentId = egg1;
+ sceneHandler03_pushEggStack();
+ }
+
+ if ( g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL
+ && !g_vars->swallowedEgg2->_value.intValue
+ && !g_vars->swallowedEgg3->_value.intValue
+ && ex1) {
+
+ if (ex1->_objtype == kObjTypeObjstateCommand) {
+ ObjstateCommand *com = (ObjstateCommand *)ex1;
+
+ com->_value = g_fullpipe->getObjectEnumState(sO_EggGulper, sO_WantsNothing);
+ }
+ }
+ }
+}
+
+int sceneHandler03(ExCommand *ex) {
+ if (ex->_messageKind != 17) {
+ if (ex->_messageKind == 57)
+ sceneHandler03_giveItem(ex);
+ return 0;
+ }
+
+ switch (ex->_messageNum) {
+ case MSG_LIFT_EXITLIFT:
+ g_fullpipe->lift_exitSeq(ex);
+ break;
+
+ case MSG_LIFT_CLOSEDOOR:
+ g_fullpipe->lift_closedoorSeq();
+ break;
+
+ case MSG_SC3_ONTAKECOIN:
+ sceneHandler03_eaterFat();
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fullpipe->lift_startExitQueue();
+ break;
+
+ case MSG_SC3_RELEASEEGG:
+ sceneHandler03_releaseEgg();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fullpipe->lift_animation3();
+ break;
+
+ case MSG_SC3_HIDEDOMINO:
+ g_vars->scene03_domino->_flags &= 0xFFFB;
+ break;
+
+ case MSG_SC3_TAKEEGG:
+ sceneHandler03_takeEgg(ex);
+ break;
+
+ case MSG_LIFT_GO:
+ g_fullpipe->lift_goAnimation();
+ break;
+
+ case MSG_SC3_UTRUBACLICK:
+ sceneHandler03_goLadder();
+ break;
+
+ case MSG_SC3_TESTFAT:
+ sceneHandler03_giveCoin(ex);
+ break;
+
+ case 64:
+ g_fullpipe->lift_sub05(ex);
+ break;
+
+ case 93:
+ {
+ StaticANIObject *ani = g_fullpipe->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fullpipe->lift_sub1(ani);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+
+ if (g_fullpipe->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY) == PIC_SC3_DOMIN) {
+ if (g_vars->scene03_domino)
+ if (g_vars->scene03_domino->_flags & 4)
+ if (g_fullpipe->_aniMan->isIdle())
+ if (!(g_fullpipe->_aniMan->_flags & 0x100) && g_fullpipe->_msgObjectId2 != g_vars->scene03_domino->_id) {
+ handleObjectInteraction(g_fullpipe->_aniMan, g_vars->scene03_domino, ex->_keyCode);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+ }
+
+ break;
+ }
+
+ case 97:
+ {
+ int res = 0;
+
+ if (g_fullpipe->_aniMan2) {
+ if (g_fullpipe->_aniMan2->_ox < g_fullpipe->_sceneRect.left + 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.left - 300;
+
+ if (g_fullpipe->_aniMan2->_ox > g_fullpipe->_sceneRect.right - 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ g_fullpipe->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
new file mode 100644
index 0000000000..f2fbfd3ef4
--- /dev/null
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -0,0 +1,731 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/utils.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+static const int scene04_speakerPhases[] = {
+ 0, 1, 2, 3, -1, -1,
+ 0, 2, 3, -1, -1, -1,
+ 0, 2, -1, -1, -1, -1
+};
+
+void scene04_speakerCallback(int *phase) {
+ if (g_vars->scene04_soundPlaying) {
+ if (g_vars->scene04_speakerPhase >= 0) {
+ *phase = scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant];
+
+ g_vars->scene04_speakerPhase++;
+
+ if (scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant] < 0) {
+ g_vars->scene04_speakerPhase = 0;
+ g_vars->scene04_speakerVariant = g_fullpipe->_rnd->getRandomNumber(2);
+ }
+ } else {
+ ++g_vars->scene04_speakerPhase;
+ }
+ }
+}
+
+void scene04_initScene(Scene *sc) {
+ g_vars->scene04_var01 = 0;
+ g_vars->scene04_bottle = sc->getPictureObjectById(PIC_SC4_BOTTLE, 0);
+ g_vars->scene04_hand = sc->getStaticANIObject1ById(ANI_HAND, -1);
+ g_vars->scene04_plank = sc->getStaticANIObject1ById(ANI_PLANK, -1);
+ g_vars->scene04_clock = sc->getStaticANIObject1ById(ANI_CLOCK, -1);
+ g_vars->scene04_spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
+ g_vars->scene04_mamasha = sc->getStaticANIObject1ById(ANI_MAMASHA_4, -1);
+ g_vars->scene04_boot = sc->getStaticANIObject1ById(ANI_SC4_BOOT, -1);
+ g_vars->scene04_ladder = 0;
+
+ StaticANIObject *koz = sc->getStaticANIObject1ById(ANI_KOZAWKA, -1);
+
+ if (koz) {
+ Movement *kozmov = koz->getMovementById(MV_KZW_JUMP);
+ if (kozmov) {
+ uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
+
+ for (uint i = 0; i < kozsize; i++) {
+ kozmov->setDynamicPhaseIndex(i);
+
+ if (kozmov->_framePosOffsets) {
+ g_vars->scene04_jumpingKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+ } else {
+ kozmov->_somePoint.x = 0;
+ kozmov->_somePoint.y = 0;
+ g_vars->scene04_jumpingKozyawki[i] = kozmov->_somePoint;
+ }
+ }
+ }
+
+ kozmov = koz->getMovementById(MV_KZW_JUMPROTATE);
+ if (kozmov) {
+ uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
+
+ for (uint i = 0; i < kozsize; i++) {
+ kozmov->setDynamicPhaseIndex(i);
+
+ if (kozmov->_framePosOffsets) {
+ g_vars->scene04_jumpRotateKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+ } else {
+ kozmov->_somePoint.x = 0;
+ kozmov->_somePoint.y = 0;
+ g_vars->scene04_jumpRotateKozyawki[i] = kozmov->_somePoint;
+ }
+ }
+ }
+ }
+
+ Interaction *plank = getGameLoaderInteractionController()->getInteractionByObjectIds(ANI_PLANK, 0, 0);
+ if (plank)
+ plank->_flags |= 8;
+
+ if (g_fullpipe->getObjectState(sO_Jar_4) == g_fullpipe->getObjectEnumState(sO_Jar_4, sO_UpsideDown)) {
+ g_vars->scene04_bottleObjList.clear();
+ g_vars->scene04_kozyawkiObjList.clear();
+
+ sc->getPictureObjectById(PIC_SC4_BOTTLE, 0)->_flags &= 0xfffb;
+ sc->getPictureObjectById(PIC_SC4_MASK, 0)->_flags &= 0xfffb;
+ sc->getStaticANIObject1ById(ANI_SPRING, 0)->_flags &= 0xfffb;
+
+ g_vars->scene04_var18 = 0;
+ g_vars->scene04_var19 = 0;
+ } else {
+ StaticANIObject *spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
+
+ if (spring)
+ spring->_callback2 = 0;
+
+ g_vars->scene04_bottleObjList.clear();
+ g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_BOTTLE, 0));
+ g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_MASK, 0));
+
+ g_vars->scene04_kozyawkiObjList.clear();
+
+ if (koz) {
+ koz->loadMovementsPixelData();
+
+ koz->_statics = koz->getStaticsById(ST_KZW_EMPTY);
+ koz->setOXY(0, 0);
+ koz->hide();
+
+ g_vars->scene04_kozyawkiObjList.push_back(koz);
+
+ for (int i = 0; i < 6; i++) {
+ StaticANIObject *koz1 = new StaticANIObject(koz);
+
+ sc->addStaticANIObject(koz1, 1);
+ koz1->_statics = koz->getStaticsById(ST_KZW_EMPTY);
+ koz1->setOXY(0, 0);
+ koz1->hide();
+ g_vars->scene04_kozyawkiObjList.push_back(koz1);
+ }
+ }
+ sc->getPictureObjectById(PIC_SC4_BOTTLE2, 0)->_flags &= 0xfffb;
+
+ g_vars->scene04_var18 = 1;
+ g_vars->scene04_var19 = 1;
+ }
+
+ g_vars->scene04_var02 = 0;
+ g_vars->scene04_soundPlaying = false;
+ g_vars->scene04_var04 = 0;
+ g_vars->scene04_walkingKozyawka = 0;
+ g_vars->scene04_var06 = 2;
+ g_vars->scene04_dynamicPhaseIndex = 0;
+
+ g_vars->scene04_kozyawkiAni.clear();
+
+ g_fullpipe->setObjectState(sO_LowerPipe, g_fullpipe->getObjectEnumState(sO_LowerPipe, sO_IsClosed));
+
+ g_vars->scene04_var07 = 0;
+ g_vars->scene04_var08 = 0;
+ g_vars->scene04_coinPut = 0;
+ g_vars->scene04_var09 = 0;
+ g_vars->scene04_var10 = 0;
+ g_vars->scene04_var11 = 0;
+ g_vars->scene04_var12 = 0;
+ g_vars->scene04_var13 = 1;
+ g_vars->scene04_var14 = 0;
+ g_vars->scene04_var15 = 1;
+
+ if (g_fullpipe->getObjectState(sO_BigMumsy) != g_fullpipe->getObjectEnumState(sO_BigMumsy, sO_Gone))
+ g_vars->scene04_mamasha->hide();
+
+ g_vars->scene04_speaker = sc->getStaticANIObject1ById(ANI_SPEAKER_4, -1);
+ g_vars->scene04_speaker->_callback2 = scene04_speakerCallback;
+ g_vars->scene04_speaker->startAnim(MV_SPK4_PLAY, 0, -1);
+
+ g_vars->scene04_speakerVariant = 0;
+ g_vars->scene04_speakerPhase = 0;
+
+ g_fullpipe->initArcadeKeys("SC_4");
+}
+
+bool sceneHandler04_friesAreWalking() {
+ warning("STUB: sceneHandler04_friesAreWalking()");
+
+ return false;
+}
+
+int scene04_updateCursor() {
+ g_fullpipe->updateCursorCommon();
+
+ if (g_fullpipe->_objectIdAtCursor == PIC_SC4_LRTRUBA) {
+ if (!g_vars->scene04_var19) {
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+
+ return g_fullpipe->_cursorId;
+ }
+ } else if (g_fullpipe->_objectIdAtCursor == ANI_PLANK || g_fullpipe->_objectIdAtCursor == PIC_SC4_PLANK) {
+ if (g_fullpipe->_objectIdAtCursor == ANI_PLANK && g_fullpipe->_cursorId != PIC_CSR_ITN)
+ return g_fullpipe->_cursorId;
+
+ if (g_fullpipe->_objectIdAtCursor == ANI_PLANK || (g_fullpipe->_objectIdAtCursor == PIC_SC4_PLANK && g_fullpipe->_cursorId == PIC_CSR_DEFAULT)) {
+ if (sceneHandler04_friesAreWalking()) {
+ g_fullpipe->_cursorId = PIC_CSR_ARCADE1;
+ return g_fullpipe->_cursorId;
+ }
+ if (g_vars->scene04_soundPlaying) {
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ return g_fullpipe->_cursorId;
+ }
+ }
+ }
+
+ if (g_fullpipe->_objectIdAtCursor == PIC_CSR_ITN && g_fullpipe->_objectIdAtCursor == PIC_SC4_DOWNTRUBA)
+ g_fullpipe->_cursorId = PIC_CSR_GOD;
+
+ return g_fullpipe->_cursorId;
+}
+
+void sceneHandlers_sub01(ExCommand *ex) {
+ warning("sceneHandlers_sub01()");
+}
+
+void sceneHandler04_checkBigBallClick() {
+ StaticANIObject *ball = g_fullpipe->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
+
+ if (ball)
+ for (uint i = 0; i < ball->_movements.size(); i++)
+ ((Movement *)ball->_movements[i])->_counterMax = 73;
+
+ g_vars->scene04_var13 = 1;
+}
+
+void sceneHandler04_clickBottle() {
+ if (!g_vars->scene04_var02)
+ g_vars->scene04_var20 += 5;
+}
+
+void sceneHandler04_clickButton() {
+ StaticANIObject *but = g_fullpipe->_currentScene->getStaticANIObject1ById(ANI_BUTTON, -1);
+
+ if (but) {
+ if (!g_vars->scene04_clock->_movement ||
+ (g_vars->scene04_clock->_movement->_id == MV_CLK_GO && g_vars->scene04_clock->_movement->_currDynamicPhaseIndex > 3 &&
+ g_vars->scene04_clock->_movement->_currDynamicPhaseIndex < 105)) {
+ if (!g_vars->scene04_hand->_movement && !g_vars->scene04_var02) {
+ but->startAnim(MV_BTN_CLICK, 0, -1);
+ g_vars->scene04_hand->startAnim(MV_HND_POINT, 0, -1);
+ }
+ }
+ }
+}
+
+void sceneHandler04_clickLadder() {
+ warning("sceneHandler04_clickLadder()");
+}
+
+void sceneHandler04_sub13() {
+ warning("sceneHandler04_sub13()");
+}
+
+void sceneHandler04_clickPlank() {
+ if (sceneHandler04_friesAreWalking())
+ sceneHandler04_sub13();
+ else if (g_vars->scene04_var01)
+ g_fullpipe->playSound(SND_4_033, 0);
+ else if (!g_vars->scene04_soundPlaying)
+ chainQueue(QU_PNK_CLICK, 0);
+}
+
+void sceneHandler04_dropBottle() {
+ g_vars->scene04_var12 = 1;
+ g_vars->scene04_var26 = 10;
+ g_vars->scene04_var06 = 0;
+
+ while (g_vars->scene04_kozyawkiAni.size()) {
+ StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front();
+ g_vars->scene04_kozyawkiAni.pop_front();
+
+ for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
+ if (*it == koz) {
+ g_vars->scene04_bottleObjList.erase(it);
+ break;
+ }
+
+ koz->queueMessageQueue(0);
+ koz->hide();
+
+ g_vars->scene04_kozyawkiObjList.push_back(koz);
+ }
+
+ g_vars->scene04_hand->changeStatics2(ST_HND_EMPTY);
+
+ g_vars->scene04_hand->setOXY(429, 21);
+ g_vars->scene04_hand->_priority = 15;
+}
+
+void sceneHandler04_gotoLadder(int par) {
+ warning("sceneHandler04_gotoLadder()");
+}
+
+void sceneHandler04_lowerPlank() {
+ g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTRIGHT, 0, -1);
+}
+
+void sceneHandler04_manFromBottle() {
+ warning("sceneHandler04_manFromBottle()");
+}
+
+void sceneHandler04_manToBottle() {
+ g_vars->scene04_bottleObjList.push_back(g_fullpipe->_aniMan);
+ g_vars->scene04_var20 = 5;
+ g_vars->scene04_var06 += 9;
+ g_fullpipe->_aniMan2 = g_fullpipe->_aniMan;
+ g_vars->scene04_var10 = 1;
+}
+
+void sceneHandler04_raisePlank() {
+ g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTLEFT, 0, -1);
+}
+
+void sceneHandler04_shootKozyawka() {
+ warning("sceneHandler04_shootKozyawka()");
+}
+
+void sceneHandler04_showCoin() {
+ StaticANIObject *ani = g_fullpipe->_currentScene->getStaticANIObject1ById(ANI_SC4_COIN, -1);
+
+ if (ani) {
+ ani->show1(MV_BDG_OPEN, MV_MAN_GOU, MV_SC4_COIN_default, 0);
+
+ ani->_priority = 40;
+ }
+}
+
+void sceneHandler04_stopSound() {
+ warning("sceneHandler04_stopSound()");
+}
+
+void sceneHandler04_sub1(ExCommand *ex) {
+ g_fullpipe->_aniMan->changeStatics2(ST_MAN_SIT);
+
+ MessageQueue *mq = new MessageQueue(g_fullpipe->_currentScene->getMessageQueueById(QU_SC4_MANFROMBOTTLE), 0, 0);
+
+ if (ex) {
+ ExCommand *newex = new ExCommand(ex);
+
+ mq->_exCommands.push_back(newex);
+ }
+
+ mq->_flags |= 1;
+ mq->chain(0);
+
+ g_vars->scene04_var10 = 0;
+ g_fullpipe->_behaviorManager->setFlagByStaticAniObject(g_fullpipe->_aniMan, 1);
+}
+
+void sceneHandler04_walkKozyawka() {
+ if (g_vars->scene04_kozyawkiObjList.size()) {
+ g_vars->scene04_walkingKozyawka = g_vars->scene04_kozyawkiObjList.front();
+ g_vars->scene04_kozyawkiObjList.pop_front();
+
+ MessageQueue *mq = new MessageQueue(g_fullpipe->_currentScene->getMessageQueueById(QU_KOZAW_WALK), 0, 1);
+ mq->replaceKeyCode(-1, g_vars->scene04_walkingKozyawka->_okeyCode);
+ mq->chain(0);
+ }
+}
+
+void sceneHandler04_sub4() {
+ warning("sceneHandler04_sub4()");
+}
+
+void sceneHandler04_sub5() {
+ warning("sceneHandler04_sub5()");
+}
+
+void sceneHandler04_sub6() {
+ warning("sceneHandler04_sub6()");
+}
+
+void sceneHandler04_sub7() {
+ warning("sceneHandler04_sub7()");
+}
+
+void sceneHandler04_sub8(ExCommand *ex) {
+ warning("sceneHandler04_sub8()");
+}
+
+void sceneHandler04_sub9(StaticANIObject *ani) {
+ warning("sceneHandler04_sub9()");
+}
+
+void sceneHandler04_sub15() {
+ warning("sceneHandler04_sub15()");
+}
+
+void sceneHandler04_sub17() {
+ warning("sceneHandler04_sub17()");
+}
+
+void sceneHandler04_takeBottle() {
+ warning("sceneHandler04_takeBottle()");
+}
+
+void sceneHandler04_takeKozyawka() {
+ warning("sceneHandler04_takeKozyawka()");
+}
+
+void sceneHandler04_testPlank(ExCommand *ex) {
+ warning("sceneHandler04_testPlank()");
+}
+
+void sceneHandler04_bottleUpdateObjects(int off) {
+ warning("sceneHandler04_bottleUpdateObjects()");
+}
+
+void sceneHandler04_updateBottle() {
+ Common::Point point;
+
+ int yoff;
+
+ if (g_vars->scene04_hand->_movement)
+ yoff = g_vars->scene04_hand->_movement->_oy;
+ else
+ yoff = g_vars->scene04_hand->_oy;
+
+ int newy = g_vars->scene04_hand->getSomeXY(point)->y + yoff + 140;
+
+ sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
+
+ g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, newy);
+}
+
+void sceneHandler04_winArcade() {
+ warning("sceneHandler04_winArcade()");
+}
+
+int sceneHandler04(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch (ex->_messageNum) {
+ case MSG_UPDATEBOTTLE:
+ sceneHandler04_updateBottle();
+ break;
+
+ case MSG_CLICKBOTTLE:
+ sceneHandler04_clickBottle();
+ break;
+
+ case MSG_SHOOTKOZAW:
+ sceneHandler04_shootKozyawka();
+ break;
+
+ case MSG_SHAKEBOTTLE:
+ if (!g_vars->scene04_var02)
+ ++g_vars->scene04_var20;
+ break;
+
+ case MSG_STARTHAND:
+ g_vars->scene04_var09 = 1;
+ g_vars->scene04_coinPut = 0;
+
+ if (g_vars->scene04_var10)
+ sceneHandler04_sub1(0);
+
+ sceneHandler04_sub15();
+ sceneHandler04_stopSound();
+ break;
+
+ case MSG_TAKEKOZAW:
+ sceneHandler04_takeKozyawka();
+ break;
+
+ case MSG_CLICKBUTTON:
+ sceneHandler04_clickButton();
+ break;
+
+ case MSG_CLICKPLANK:
+ sceneHandler04_clickPlank();
+ break;
+
+ case MSG_RAISEPLANK:
+ sceneHandler04_raisePlank();
+ break;
+
+ case MSG_KOZAWRESTART:
+ if (g_vars->scene04_walkingKozyawka) {
+ g_vars->scene04_kozyawkiObjList.push_back(g_vars->scene04_walkingKozyawka);
+ g_vars->scene04_walkingKozyawka->hide();
+ g_vars->scene04_walkingKozyawka = 0;
+ }
+
+ if (g_vars->scene04_soundPlaying)
+ sceneHandler04_walkKozyawka();
+
+ break;
+
+ case MSG_LOWERPLANK:
+ sceneHandler04_lowerPlank();
+ break;
+
+ case MSG_TESTPLANK:
+ sceneHandler04_testPlank(ex);
+ break;
+
+ case 33:
+ {
+ g_vars->scene04_dudePosX = g_fullpipe->_aniMan->_ox;
+ g_vars->scene04_dudePosY = g_fullpipe->_aniMan->_oy;
+
+ int res = 0;
+
+ if (g_fullpipe->_aniMan2) {
+ if (g_fullpipe->_aniMan->_ox < g_fullpipe->_sceneRect.left + 200) {
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan->_ox - g_fullpipe->_sceneRect.left - 300;
+ g_fullpipe->_aniMan->_ox = g_vars->scene04_dudePosX;
+ }
+ if (g_fullpipe->_aniMan->_ox > g_fullpipe->_sceneRect.right - 200) {
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan->_ox - g_fullpipe->_sceneRect.right + 300;
+ }
+
+ res = 1;
+
+ if (g_vars->scene04_soundPlaying) {
+ if (g_fullpipe->_aniMan->_movement) {
+ if (g_fullpipe->_aniMan->_movement->_id == MV_MAN_TOLADDER) {
+ g_fullpipe->_aniMan2 = 0;
+
+ if (g_fullpipe->_sceneRect.left > 380)
+ g_fullpipe->_currentScene->_x = 380 - g_fullpipe->_sceneRect.left;
+ }
+ }
+ }
+ } else {
+ if (g_fullpipe->_aniMan->_movement && g_fullpipe->_aniMan->_movement->_id == MV_MAN_GOD)
+ g_fullpipe->_aniMan2 = g_fullpipe->_aniMan;
+ }
+
+ sceneHandler04_sub4();
+
+ if (g_vars->scene04_var07 && !g_vars->scene04_var09)
+ sceneHandler04_sub5();
+
+ if (g_vars->scene04_var12)
+ sceneHandler04_sub6();
+
+ if (g_vars->scene04_var08)
+ sceneHandler04_clickLadder();
+
+ if (g_vars->scene04_var10 && g_vars->scene04_hand->_movement)
+ sceneHandler04_sub1(0);
+
+ if (g_vars->scene04_coinPut && g_vars->scene04_var18 && !g_vars->scene04_var09 && !g_vars->scene04_soundPlaying)
+ sceneHandler04_sub7();
+
+ if (g_vars->scene04_var01) {
+ if (!g_vars->scene04_soundPlaying) {
+ g_fullpipe->startSceneTrack();
+
+ g_fullpipe->_behaviorManager->updateBehaviors();
+ return res;
+ }
+
+ g_vars->scene04_var14++;
+
+ if (g_vars->scene04_var14 > 600)
+ sceneHandler04_sub17();
+ }
+
+ if (g_vars->scene04_soundPlaying) {
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ return res;
+ }
+
+ g_fullpipe->startSceneTrack();
+
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ return res;
+ }
+
+ case 29:
+ {
+ int picid = g_fullpipe->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if (g_vars->scene04_var10) {
+ sceneHandler04_sub1(ex);
+
+ break;
+ }
+
+ if (picid == PIC_SC4_LADDER) {
+ if (!g_vars->scene04_var04) {
+ g_vars->scene04_sceneClickX = ex->_sceneClickX;
+ g_vars->scene04_sceneClickY = ex->_sceneClickY;
+
+ sceneHandler04_clickLadder();
+
+ ex->_messageKind = 0;
+
+ break;
+ }
+
+ sceneHandler04_gotoLadder(0);
+
+ break;
+ }
+
+ StaticANIObject *ani = g_fullpipe->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if ((ani && ani->_id == ANI_PLANK) || picid == PIC_SC4_PLANK) {
+ sceneHandler04_clickPlank();
+
+ ex->_messageKind = 0;
+ } else if (g_vars->scene04_var01) {
+ sceneHandler04_sub8(ex);
+ } else if (!ani || !canInteractAny(g_fullpipe->_aniMan, ani, ex->_keyCode)) {
+ PictureObject *pic = g_fullpipe->_currentScene->getPictureObjectById(picid, 0);
+
+ if (!pic || !canInteractAny(g_fullpipe->_aniMan, pic,ex->_keyCode)) {
+ if ((g_fullpipe->_sceneRect.right - ex->_sceneClickX < 47 && g_fullpipe->_sceneRect.right < g_fullpipe->_sceneWidth - 1)
+ || (ex->_sceneClickX - g_fullpipe->_sceneRect.left < 47 && g_fullpipe->_sceneRect.left > 0))
+ sceneHandlers_sub01(ex);
+ }
+ }
+ }
+
+ break;
+
+ case MSG_SC4_HIDEBOOT:
+ g_vars->scene04_boot->_flags &= 0xfffb;
+ break;
+
+ case MSG_CMN_WINARCADE:
+ sceneHandler04_winArcade();
+ break;
+
+ case MSG_SC4_HANDOVER:
+ g_vars->scene04_var09 = 0;
+ g_vars->scene04_var19 = 1;
+ break;
+
+ case MSG_SC4_DROPBOTTLE:
+ sceneHandler04_dropBottle();
+ break;
+
+ case MSG_SC4_COINOUT:
+ g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
+ g_vars->scene04_coinPut = 0;
+ sceneHandler04_stopSound();
+
+ if (g_vars->scene04_kozyawkiAni.size() && !g_vars->scene04_var02) {
+ g_vars->scene04_var09 = 1;
+
+ if (g_vars->scene04_var10)
+ sceneHandler04_sub1(0);
+
+ sceneHandler04_sub15();
+ }
+
+ break;
+
+ case MSG_SC4_KOZAWFALL:
+ {
+ ExCommand *exnew;
+
+ if (g_vars->scene04_var11) {
+ sceneHandler04_sub9(g_vars->scene04_var24);
+
+ g_vars->scene04_var11 = 0;
+
+ exnew = new ExCommand(0, 35, SND_4_010, 0, 0, 0, 1, 0, 0, 0);
+ } else {
+ exnew = new ExCommand(0, 35, SND_4_012, 0, 0, 0, 1, 0, 0, 0);
+ }
+
+ exnew->_field_14 = 5;
+ exnew->_excFlags |= 2;
+ exnew->postMessage();
+ break;
+ }
+
+ case MSG_SC4_MANFROMBOTTLE:
+ sceneHandler04_manFromBottle();
+ break;
+
+ case MSG_SC4_CLICKLADDER:
+ sceneHandler04_clickLadder();
+ break;
+
+ case MSG_SC4_MANTOBOTTLE:
+ sceneHandler04_manToBottle();
+ break;
+
+ case MSG_SHOWCOIN:
+ sceneHandler04_showCoin();
+ break;
+
+ case MSG_TAKEBOTTLE:
+ sceneHandler04_takeBottle();
+ break;
+
+ case MSG_GOTOLADDER:
+ sceneHandler04_gotoLadder(0);
+ break;
+
+ case MSG_SC4_COINPUT:
+ g_vars->scene04_coinPut = 1;
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/sceneDbg.cpp b/engines/fullpipe/scenes/sceneDbg.cpp
new file mode 100644
index 0000000000..83f3b64ee5
--- /dev/null
+++ b/engines/fullpipe/scenes/sceneDbg.cpp
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+void sceneDbgMenu_initScene(Scene *sc) {
+ g_vars->selector = sc->getPictureObjectById(PIC_SCD_SEL, 0);
+ getGameLoaderInteractionController()->disableFlag24();
+ setInputDisabled(0);
+}
+
+GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
+ if (g_fullpipe->_currentScene)
+ for (uint i = 0; i < g_fullpipe->_currentScene->_picObjList.size(); i++) {
+ PictureObject *pic = (PictureObject *)g_fullpipe->_currentScene->_picObjList[i];
+
+ if (x >= pic->_ox && y >= pic->_oy) {
+ Common::Point point;
+
+ pic->getDimensions(&point);
+
+ if (x <= pic->_ox + point.x && y <= pic->_oy + point.y && pic != g_vars->selector)
+ return pic;
+ }
+ }
+
+ return 0;
+}
+
+int sceneHandlerDbgMenu(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ int mx = g_fullpipe->_mouseScreenPos.x + g_fullpipe->_sceneRect.left;
+ int my = g_fullpipe->_mouseScreenPos.y + g_fullpipe->_sceneRect.top;
+
+ if (ex->_messageNum == 29) {
+ GameObject *obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ getGameLoaderInteractionController()->enableFlag24();
+ handleObjectInteraction(0, obj, 0);
+ }
+ return 0;
+ }
+ if (ex->_messageNum != 33) {
+ if (ex->_messageNum == MSG_RESTARTGAME) {
+ g_fullpipe->_needRestart = true;
+ return 0;
+ }
+ return 0;
+ }
+
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ GameObject *obj = g_fullpipe->_currentScene->getStaticANIObjectAtPos(mx, my);
+ if (obj) {
+ if (canInteractAny(0, obj, -3)) {
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ g_fullpipe->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ } else {
+ obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ g_vars->selector->_flags |= 4;
+ g_vars->selector->setOXY(obj->_ox, obj->_oy);
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ g_fullpipe->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ g_vars->selector->_flags &= 0xFFFB;
+ }
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/sceneIntro.cpp b/engines/fullpipe/scenes/sceneIntro.cpp
new file mode 100644
index 0000000000..d60f90faf7
--- /dev/null
+++ b/engines/fullpipe/scenes/sceneIntro.cpp
@@ -0,0 +1,109 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/statics.h"
+
+namespace Fullpipe {
+
+int sceneIntro_updateCursor() {
+ g_fullpipe->_cursorId = 0;
+
+ return 0;
+}
+
+void sceneIntro_initScene(Scene *sc) {
+ g_fullpipe->_gameLoader->loadScene(SC_INTRO2);
+
+ g_vars->sceneIntro_aniin1man = sc->getStaticANIObject1ById(ANI_IN1MAN, -1);
+ g_vars->sceneIntro_needSleep = true;
+ g_vars->sceneIntro_needGetup = false;
+ g_vars->sceneIntro_playing = true;
+ g_vars->sceneIntro_needBlackout = false;
+
+ if (g_fullpipe->_recordEvents || g_fullpipe->_inputArFlag)
+ g_vars->sceneIntro_skipIntro = false;
+
+ g_fullpipe->_modalObject = new ModalIntro;
+}
+
+void sceneHandlerIntro_part1() {
+ g_fullpipe->_currentScene = g_fullpipe->accessScene(SC_INTRO1);
+ chainQueue(QU_INTR_FINISH, 0);
+}
+
+void sceneHandlerIntro_part2() {
+ g_fullpipe->_currentScene = g_fullpipe->accessScene(SC_INTRO2);
+ chainQueue(QU_IN2_DO, 0);
+}
+
+int sceneHandlerIntro(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch (ex->_messageNum) {
+ case MSG_INTR_ENDINTRO:
+ g_vars->sceneIntro_playing = 0;
+ return 0;
+
+ case MSG_INTR_SWITCHTO1:
+ sceneHandlerIntro_part1();
+ return 0;
+
+ case MSG_INTR_GETUPMAN:
+ g_vars->sceneIntro_needSleep = 0;
+ g_vars->sceneIntro_needGetup = 1;
+ return 0;
+
+ case MSG_INTR_SWITCHTO2:
+ sceneHandlerIntro_part2();
+ return 0;
+
+ case 33:
+ // fall through
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (g_vars->sceneIntro_needSleep) {
+ if (!g_vars->sceneIntro_aniin1man->_movement && g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP)
+ g_vars->sceneIntro_aniin1man->startAnim(MV_IN1MAN_SLEEP, 0, -1);
+ } else if (g_vars->sceneIntro_needGetup && !g_vars->sceneIntro_aniin1man->_movement &&
+ g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP) {
+ g_vars->sceneIntro_needGetup = 0;
+
+ chainQueue(QU_INTR_GETUPMAN, 0);
+ }
+
+ g_fullpipe->startSceneTrack();
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
new file mode 100644
index 0000000000..6da848a621
--- /dev/null
+++ b/engines/fullpipe/sound.cpp
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/sound.h"
+#include "fullpipe/ngiarchive.h"
+
+namespace Fullpipe {
+
+SoundList::SoundList() {
+ _soundItems = 0;
+ _soundItemsCount = 0;
+ _libHandle = 0;
+}
+
+bool SoundList::load(MfcArchive &file, char *fname) {
+ debug(5, "SoundList::load()");
+
+ _soundItemsCount = file.readUint32LE();
+ _soundItems = (Sound **)calloc(_soundItemsCount, sizeof(Sound *));
+
+ if (fname) {
+ _libHandle = (NGIArchive *)makeNGIArchive(fname);
+ } else {
+ _libHandle = 0;
+ }
+
+ for (int i = 0; i < _soundItemsCount; i++) {
+ Sound *snd = new Sound();
+
+ _soundItems[i] = snd;
+ snd->load(file, _libHandle);
+ }
+
+ return true;
+
+}
+
+bool SoundList::loadFile(const char *fname, char *libname) {
+ Common::File file;
+
+ if (!file.open(fname))
+ return false;
+
+ MfcArchive archive(&file);
+
+ return load(archive, libname);
+}
+
+Sound::Sound() {
+ _id = 0;
+ _directSoundBuffer = 0;
+ _soundData = 0;
+ _objectId = 0;
+ memset(_directSoundBuffers, 0, sizeof(_directSoundBuffers));
+ _description = 0;
+}
+
+
+bool Sound::load(MfcArchive &file, NGIArchive *archive) {
+ debug(5, "Sound::load()");
+
+ MemoryObject::load(file);
+
+ _id = file.readUint32LE();
+ _description = file.readPascalString();
+
+ assert(g_fullpipe->_gameProjectVersion >= 6);
+
+ _objectId = file.readUint16LE();
+
+ if (archive && archive->hasFile(_memfilename)) {
+ Common::SeekableReadStream *s = archive->createReadStreamForMember(_memfilename);
+
+ _soundData = (byte *)calloc(s->size(), 1);
+
+ s->read(_soundData, s->size());
+
+ delete s;
+ }
+
+ return true;
+}
+
+void Sound::updateVolume() {
+ debug(3, "STUB Sound::updateVolume()");
+}
+
+void Sound::setPanAndVolumeByStaticAni() {
+ debug(3, "STUB Sound::setPanAndVolumeByStaticAni()");
+}
+
+void FullpipeEngine::setSceneMusicParameters(GameVar *var) {
+ warning("STUB: FullpipeEngine::setSceneMusicParameters()");
+}
+
+void FullpipeEngine::startSceneTrack() {
+ debug(3, "STUB: FullpipeEngine::startSceneTrack()");
+}
+
+void FullpipeEngine::stopAllSounds() {
+ warning("STUB: FullpipeEngine::stopAllSounds()");
+}
+
+void FullpipeEngine::toggleMute() {
+ warning("STUB: FullpipeEngine::toggleMute()");
+}
+
+void FullpipeEngine::playSound(int id, int flag) {
+ warning("STUB: FullpipeEngine::playSounds(%d, %d)", id, flag);
+}
+
+void global_messageHandler_handleSound(ExCommand *cmd) {
+ debug(0, "STUB: global_messageHandler_handleSound()");
+}
+
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h
new file mode 100644
index 0000000000..e2b271fe2c
--- /dev/null
+++ b/engines/fullpipe/sound.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SOUND_H
+#define FULLPIPE_SOUND_H
+
+namespace Fullpipe {
+
+class Sound : public MemoryObject {
+ int _id;
+ char *_description;
+ int16 _objectId;
+ int _directSoundBuffer;
+ int _directSoundBuffers[7];
+ byte *_soundData;
+
+ public:
+ Sound();
+ virtual bool load(MfcArchive &file, NGIArchive *archive);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
+ void updateVolume();
+
+ void setPanAndVolumeByStaticAni();
+};
+
+class SoundList : public CObject {
+ Sound **_soundItems;
+ int _soundItemsCount;
+ NGIArchive *_libHandle;
+
+ public:
+ SoundList();
+ virtual bool load(MfcArchive &file, char *fname);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
+ bool loadFile(const char *fname, char *libname);
+
+ int getCount() { return _soundItemsCount; }
+ Sound *getSoundByIndex(int idx) { return _soundItems[idx]; }
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SOUND_H */
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
new file mode 100644
index 0000000000..747015e9a1
--- /dev/null
+++ b/engines/fullpipe/stateloader.cpp
@@ -0,0 +1,321 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/array.h"
+#include "common/list.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+bool FullpipeEngine::loadGam(const char *fname, int scene) {
+ _gameLoader = new GameLoader();
+
+ if (!_gameLoader->loadFile(fname))
+ return false;
+
+ _currSoundListCount = 0;
+ initObjectStates();
+ // set_g_messageQueueCallback1(messageQueueCallback1); // substituted with direct call
+
+ addMessageHandlerByIndex(global_messageHandler1, 0, 4);
+
+ _inventory = getGameLoaderInventory();
+ _inventory->setItemFlags(ANI_INV_MAP, 0x10003);
+ _inventory->addItem(ANI_INV_MAP, 1);
+
+ _inventory->rebuildItemRects();
+
+ for (PtrList::iterator p = _inventory->getScene()->_picObjList.begin(); p != _inventory->getScene()->_picObjList.end(); ++p) {
+ ((MemoryObject *)((PictureObject *)*p)->_picture)->load();
+ }
+
+ // _sceneSwitcher = sceneSwitcher; // substituted with direct call
+ _gameLoader->_preloadCallback = preloadCallback;
+ // _readSavegameCallback = gameLoaderReadSavegameCallback; // TODO
+
+ _aniMan = accessScene(SC_COMMON)->getAniMan();
+ _scene2 = 0;
+
+ _movTable = _aniMan->countMovements();
+
+ _aniMan->setSpeed(1);
+
+ PictureObject *pic = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0);
+
+ pic->setFlags(pic->_flags & 0xFFFB);
+
+ // Not used in full game
+ //_evalVersionPic = accessScene(SC_COMMON)->getPictureObjectById(PIC_CMN_EVAL, 0);
+
+ initMap();
+ initCursors();
+
+ setMusicAllowed(_gameLoader->_gameVar->getSubVarAsInt("MUSIC_ALLOWED"));
+
+ if (scene) {
+ _gameLoader->loadScene(scene);
+ _gameLoader->gotoScene(scene, TrubaLeft);
+ } else {
+ if (_flgPlayIntro) {
+ _gameLoader->loadScene(SC_INTRO1);
+ _gameLoader->gotoScene(SC_INTRO1, TrubaUp);
+ } else {
+ _gameLoader->loadScene(SC_1);
+ _gameLoader->gotoScene(SC_1, TrubaLeft);
+ }
+ }
+
+ if (!_currentScene)
+ return false;
+
+ return true;
+}
+
+GameProject::GameProject() {
+ _field_4 = 0;
+ _headerFilename = 0;
+ _field_10 = 12;
+
+ _sceneTagList = 0;
+}
+
+bool GameProject::load(MfcArchive &file) {
+ debug(5, "GameProject::load()");
+
+ _field_4 = 0;
+ _headerFilename = 0;
+ _field_10 = 12;
+
+ g_fullpipe->_gameProjectVersion = file.readUint32LE();
+ g_fullpipe->_pictureScale = file.readUint16LE();
+ g_fullpipe->_scrollSpeed = file.readUint32LE();
+
+ _headerFilename = file.readPascalString();
+
+ debug(1, "_gameProjectVersion = %d", g_fullpipe->_gameProjectVersion);
+ debug(1, "_pictureScale = %d", g_fullpipe->_pictureScale);
+ debug(1, "_scrollSpeed = %d", g_fullpipe->_scrollSpeed);
+ debug(1, "_headerFilename = %s", _headerFilename);
+
+ _sceneTagList = new SceneTagList();
+
+ _sceneTagList->load(file);
+
+ if (g_fullpipe->_gameProjectVersion >= 3)
+ _field_4 = file.readUint32LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 5) {
+ file.readUint32LE();
+ file.readUint32LE();
+ }
+
+ return true;
+}
+
+GameProject::~GameProject() {
+ free(_headerFilename);
+}
+
+GameVar::GameVar() {
+ _subVars = 0;
+ _parentVarObj = 0;
+ _nextVarObj = 0;
+ _prevVarObj = 0;
+ _field_14 = 0;
+ _varType = 0;
+ _value.floatValue = 0;
+ _varName = 0;
+}
+
+bool GameVar::load(MfcArchive &file) {
+ _varName = file.readPascalString();
+ _varType = file.readUint32LE();
+
+ debugN(6, "[%03d] ", file.getLevel());
+ for (int i = 0; i < file.getLevel(); i++)
+ debugN(6, " ");
+
+ debugN(6, "<%s>: ", transCyrillic((byte *)_varName));
+
+ switch (_varType) {
+ case 0:
+ _value.intValue = file.readUint32LE();
+ debug(6, "d --> %d", _value.intValue);
+ break;
+ case 1:
+ _value.intValue = file.readUint32LE(); // FIXME
+ debug(6, "f --> %f", _value.floatValue);
+ break;
+ case 2:
+ _value.stringValue = file.readPascalString();
+ debug(6, "s --> %s", _value.stringValue);
+ break;
+ default:
+ error("Unknown var type: %d (0x%x)", _varType, _varType);
+ }
+
+ file.incLevel();
+ _parentVarObj = (GameVar *)file.readClass();
+ _prevVarObj = (GameVar *)file.readClass();
+ _nextVarObj = (GameVar *)file.readClass();
+ _field_14 = (GameVar *)file.readClass();
+ _subVars = (GameVar *)file.readClass();
+ file.decLevel();
+
+ return true;
+}
+
+GameVar *GameVar::getSubVarByName(const char *name) {
+ GameVar *sv = 0;
+
+ if (_subVars != 0) {
+ sv = _subVars;
+ for (;sv && scumm_stricmp(sv->_varName, name); sv = sv->_nextVarObj)
+ ;
+ }
+ return sv;
+}
+
+bool GameVar::setSubVarAsInt(const char *name, int value) {
+ GameVar *var = getSubVarByName(name);
+
+ if (var) {
+ if (var->_varType == 0) {
+ var->_value.intValue = value;
+
+ return true;
+ }
+ return false;
+ }
+
+ var = new GameVar();
+ var->_varType = 0;
+ var->_value.intValue = value;
+ var->_varName = (char *)calloc(strlen(name) + 1, 1);
+ strcpy(var->_varName, name);
+
+ return addSubVar(var);
+}
+
+int GameVar::getSubVarAsInt(const char *name) {
+ GameVar *var = getSubVarByName(name);
+
+ if (var)
+ return var->_value.intValue;
+ else
+ return 0;
+}
+
+GameVar *GameVar::addSubVarAsInt(const char *name, int value) {
+ if (getSubVarByName(name)) {
+ return 0;
+ } else {
+ GameVar *var = new GameVar();
+
+ var->_varType = 0;
+ var->_value.intValue = value;
+
+ var->_varName = (char *)calloc(strlen(name) + 1, 1);
+ strcpy(var->_varName, name);
+
+ return (addSubVar(var) != 0) ? var : 0;
+ }
+}
+
+bool GameVar::addSubVar(GameVar *subvar) {
+ GameVar *var = _subVars;
+
+ if (var) {
+ for (GameVar *i = var->_nextVarObj; i; i = i->_nextVarObj)
+ var = i;
+
+ var->_nextVarObj = subvar;
+ subvar->_prevVarObj = var;
+ subvar->_parentVarObj = this;
+
+ return true;
+ } else {
+ _subVars = subvar;
+ subvar->_parentVarObj = this;
+
+ return true;
+ }
+
+ return false;
+}
+
+int GameVar::getSubVarsCount() {
+ int res;
+ GameVar *sub = _subVars;
+
+ for (res = 0; sub; res++)
+ sub = sub->_nextVarObj;
+
+ return res;
+}
+
+GameVar *GameVar::getSubVarByIndex(int idx) {
+ GameVar *sub = _subVars;
+
+ while (idx--) {
+ sub = sub->_nextVarObj;
+
+ if (!sub)
+ return 0;
+ }
+
+ return sub;
+}
+
+bool PicAniInfo::load(MfcArchive &file) {
+ debug(5, "PicAniInfo::load()");
+
+ type = file.readUint32LE();
+ objectId = file.readUint16LE();
+ field_6 = file.readUint16LE();
+ field_8 = file.readUint32LE();
+ sceneId = file.readUint16LE();
+ field_E = file.readUint16LE();
+ ox = file.readUint32LE();
+ oy = file.readUint32LE();
+ priority = file.readUint32LE();
+ staticsId = file.readUint16LE();
+ movementId = file.readUint16LE();
+ dynamicPhaseIndex = file.readUint16LE();
+ flags = file.readUint16LE();
+ field_24 = file.readUint32LE();
+ someDynamicPhaseIndex = file.readUint32LE();
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
new file mode 100644
index 0000000000..b82875f638
--- /dev/null
+++ b/engines/fullpipe/statics.cpp
@@ -0,0 +1,1910 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/interaction.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/objectnames.h"
+
+namespace Fullpipe {
+
+StepArray::StepArray() {
+ _points = 0;
+ _maxPointIndex = 0;
+ _currPointIndex = 0;
+ _pointsCount = 0;
+ _isEos = 0;
+}
+
+StepArray::~StepArray() {
+ if (_pointsCount) {
+ for (int i = 0; i < _pointsCount; i++)
+ delete _points[i];
+
+ delete _points;
+
+ _points = 0;
+ }
+}
+
+void StepArray::clear() {
+ _currPointIndex = 0;
+ _maxPointIndex = 0;
+ _isEos = 0;
+
+ for (int i = 0; i < _pointsCount; i++) {
+ _points[i]->x = 0;
+ _points[i]->y = 0;
+ }
+}
+
+Common::Point *StepArray::getCurrPoint(Common::Point *point) {
+ if (_isEos || _points == 0) {
+ point->x = 0;
+ point->y = 0;
+ } else {
+ point = _points[_currPointIndex];
+ }
+ return point;
+}
+
+Common::Point *StepArray::getPoint(Common::Point *point, int index, int offset) {
+ if (index == -1)
+ index = _currPointIndex;
+
+ if (index + offset > _maxPointIndex - 1)
+ offset = _maxPointIndex - index;
+
+ point->x = 0;
+ point->y = 0;
+
+ while (offset >= 1) {
+ point->x += _points[index]->x;
+ point->y += _points[index]->y;
+
+ index++;
+ offset--;
+ }
+
+ return point;
+}
+
+bool StepArray::gotoNextPoint() {
+ if (_currPointIndex < _maxPointIndex) {
+ _currPointIndex++;
+ return true;
+ } else {
+ _isEos = 1;
+ return false;
+ }
+}
+
+StaticANIObject::StaticANIObject() {
+ _shadowsOn = 1;
+ _field_30 = 0;
+ _field_34 = 1;
+ _initialCounter = 0;
+ _messageQueueId = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _movement = 0;
+ _statics = 0;
+ _flags = 0;
+ _callback1 = 0;
+ _callback2 = 0;
+ _sceneId = -1;
+ _someDynamicPhaseIndex = -1;
+
+ _field_32 = 0;
+ _field_96 = 0;
+ _messageNum = 0;
+ _objtype = kObjTypeStaticANIObject;
+}
+
+StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
+ _shadowsOn = src->_shadowsOn;
+ _field_30 = src->_field_30;
+ _field_34 = 1;
+ _initialCounter = 0;
+
+ _field_32 = 0;
+ _field_96 = 0;
+ _messageNum = 0;
+
+ _messageQueueId = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _someDynamicPhaseIndex = -1;
+ _sceneId = src->_sceneId;
+ _callback1 = src->_callback1;
+ _callback2 = src->_callback2;
+ _objtype = kObjTypeStaticANIObject;
+
+ for (uint i = 0; i < src->_staticsList.size(); i++)
+ _staticsList.push_back(new Statics((Statics *)src->_staticsList[i], 0));
+
+ _movement = 0;
+ _statics = 0;
+
+ for (uint i = 0; i < src->_movements.size(); i++) {
+ Movement *newmov;
+ Movement *mov = (Movement *)src->_movements[i];
+
+ if (mov->_currMovement) {
+ // WORKAROUND: Original uses weird construction here:
+ // new Movement(getMovementById(src->getMovementIdById(mov->_id)), this);
+ newmov = new Movement(src->getMovementById(src->getMovementIdById(mov->_id)), this);
+ newmov->_id = mov->_id;
+ } else {
+ newmov = new Movement(mov, 0, -1, this);
+ }
+
+ _movements.push_back(newmov);
+ }
+}
+
+bool StaticANIObject::load(MfcArchive &file) {
+ debug(5, "StaticANIObject::load()");
+
+ GameObject::load(file);
+
+ int count = file.readUint16LE();
+
+ for (int i = 0; i < count; i++) {
+ Statics *st = new Statics();
+
+ st->load(file);
+ _staticsList.push_back(st);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "Movements: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int movNum = file.readUint16LE();
+
+ char *movname = genFileName(_id, movNum, "mov");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(movname);
+
+ Movement *mov = new Movement();
+
+ MfcArchive archive(f);
+
+ mov->load(archive, this);
+
+ _movements.push_back(mov);
+
+ delete f;
+ free(movname);
+ }
+
+ Common::Point pt;
+ if (count) { // We have movements
+ ((Movement *)_movements[0])->getCurrDynamicPhaseXY(pt);
+ } else {
+ pt.x = pt.y = 100;
+ }
+
+ setOXY(pt.x, pt.y);
+
+ return true;
+}
+
+void StaticANIObject::setOXY(int x, int y) {
+ _ox = x;
+ _oy = y;
+
+ if (_movement)
+ _movement->setOXY(x, y);
+}
+
+void StaticANIObject::clearFlags() {
+ _flags = 0;
+
+ deleteFromGlobalMessageQueue();
+ _messageQueueId = 0;
+ _movement = 0;
+ _statics = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _messageNum = 0;
+ _stepArray.clear();
+}
+
+void StaticANIObject::setFlags40(bool state) {
+ if (state) {
+ _flags |= 0x40;
+ } else {
+ if (_flags & 0x40)
+ _flags ^= 0x40;
+ }
+}
+
+void StaticANIObject::deleteFromGlobalMessageQueue() {
+ while (_messageQueueId) {
+ if (g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId)) {
+ if (!isIdle())
+ return;
+
+ g_fullpipe->_globalMessageQueueList->deleteQueueById(_messageQueueId);
+ } else {
+ _messageQueueId = 0;
+ }
+ }
+}
+
+void StaticANIObject::queueMessageQueue(MessageQueue *mq) {
+ if (isIdle() && !(_flags & 0x80)) {
+ deleteFromGlobalMessageQueue();
+ _messageQueueId = 0;
+ _messageNum = 0;
+
+ if (_flags & 2)
+ _flags ^= 2;
+
+ if (mq) {
+ _animExFlag = 0;
+ if (_movement)
+ _messageQueueId = mq->_id;
+ else
+ mq->sendNextCommand();
+ } else {
+ _messageQueueId = 0;
+ }
+ }
+}
+
+MessageQueue *StaticANIObject::getMessageQueue() {
+ if (this->_messageQueueId <= 0)
+ return 0;
+
+ return g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+}
+
+bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) {
+ if (_messageQueueId || !msgNum) {
+ updateGlobalMessageQueue(qId, _id);
+ return false;
+ }
+
+ _flags |= 2;
+
+ _messageNum = msgNum;
+ _messageQueueId = qId;
+
+ return true;
+}
+
+bool StaticANIObject::isIdle() {
+ if (_messageQueueId) {
+ MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+
+ if (m && m->getFlags() & 1)
+ return false;
+ }
+
+ return true;
+}
+
+Statics *StaticANIObject::getStaticsById(int itemId) {
+ for (uint i = 0; i < _staticsList.size(); i++)
+ if (((Statics *)_staticsList[i])->_staticsId == itemId)
+ return (Statics *)_staticsList[i];
+
+ return 0;
+}
+
+Statics *StaticANIObject::getStaticsByName(char *name) {
+ for (uint i = 0; i < _staticsList.size(); i++)
+ if (!strcmp(((Statics *)_staticsList[i])->_staticsName, name))
+ return (Statics *)_staticsList[i];
+
+ return 0;
+}
+
+Movement *StaticANIObject::getMovementById(int itemId) {
+ for (uint i = 0; i < _movements.size(); i++)
+ if (((Movement *)_movements[i])->_id == itemId)
+ return (Movement *)_movements[i];
+
+ return 0;
+}
+
+int StaticANIObject::getMovementIdById(int itemId) {
+ for (uint i = 0; i < _movements.size(); i++) {
+ Movement *mov = (Movement *)_movements[i];
+ if (mov->_currMovement) {
+ if (mov->_id == itemId)
+ return mov->_id;
+ if (mov->_currMovement->_id == itemId)
+ return mov->_id;
+ }
+ }
+
+ return 0;
+}
+
+Movement *StaticANIObject::getMovementByName(char *name) {
+ for (uint i = 0; i < _movements.size(); i++)
+ if (!strcmp(((Movement *)_movements[i])->_objectName, name))
+ return (Movement *)_movements[i];
+
+ return 0;
+}
+
+bool StaticANIObject::getPixelAtPos(int x, int y, int *pixel) {
+ bool res = false;
+ Picture *pic;
+
+ if (_movement)
+ pic = _movement->_currDynamicPhase;
+ else
+ pic = _statics;
+
+ if (!pic)
+ return false;
+
+ int ongoing;
+ int xani, yani;
+ int oxani, oyani;
+ Common::Point point;
+
+ if (_movement)
+ ongoing = _movement->_currMovement != 0;
+ else
+ ongoing = _statics->_staticsId & 0x4000;
+
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(point);
+ xani = point.x;
+ yani = point.y;
+ oxani = _movement->_ox;
+ oyani = _movement->_oy;
+ } else {
+ _statics->getSomeXY(point);
+ xani = point.x;
+ yani = point.y;
+ oxani = _ox;
+ oyani = _oy;
+ }
+
+ int xtarget = x - (oxani - xani);
+ int ytarget = y - (oyani - yani);
+
+ if (ongoing && _movement)
+ xtarget = pic->getDimensions(&point)->x - xtarget;
+
+ x = pic->_x;
+ y = pic->_y;
+ pic->_x = 0;
+ pic->_y = 0;
+ if (pic->isPixelHitAtPos(xtarget, ytarget)) {
+ *pixel = pic->getPixelAtPos(xtarget, ytarget);
+
+ res = true;
+ } else {
+ res = false;
+ }
+ pic->_x = x;
+ pic->_y = y;
+
+ return res;
+}
+
+void Movement::draw(bool flipFlag, int angle) {
+ debug(3, "Movement::draw(%d, %d)", flipFlag, angle);
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+
+ int x = _ox - point.x;
+ int y = _oy - point.y;
+
+ if (_currDynamicPhase->getPaletteData())
+ g_fullpipe->_globalPalette = _currDynamicPhase->getPaletteData();
+
+ if (_currDynamicPhase->getAlpha() < 0xFF) {
+ warning("Movement::draw: alpha < 0xff: %d", _currDynamicPhase->getAlpha());
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, _currDynamicPhase->getAlpha());
+ }
+
+ Bitmap *bmp;
+ if (_currMovement) {
+ bmp = _currDynamicPhase->getPixelData()->reverseImage();
+ } else {
+ bmp = _currDynamicPhase->getPixelData();
+ }
+
+ if (flipFlag) {
+ bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->_paletteData);
+ } if (angle) {
+ bmp->drawRotated(x, y, angle, _currDynamicPhase->_paletteData);
+ } else {
+ bmp->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ }
+
+ if (_currDynamicPhase->_rect->top) {
+ if (!_currDynamicPhase->_convertedBitmap) {
+ //v12 = Picture_getPixelData(v5);
+ //v13 = Bitmap_convertTo16Bit565(v12, (unsigned int *)&_currDynamicPhase->rect);
+ //_currDynamicPhase->convertedBitmap = v13;
+ }
+
+ if (_currDynamicPhase->_convertedBitmap) {
+ if (_currMovement) {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
+ _currDynamicPhase->_convertedBitmap->reverseImage()->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
+ } else {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
+ _currDynamicPhase->_convertedBitmap->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
+ }
+ }
+ }
+}
+
+
+void StaticANIObject::loadMovementsPixelData() {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->loadPixelData();
+}
+
+Statics *StaticANIObject::addReverseStatics(Statics *st) {
+ Statics *res = getStaticsById(st->_staticsId ^ 0x4000);
+
+ if (!res) {
+ res = new Statics(st, true);
+
+ _staticsList.push_back(res);
+ }
+
+ return res;
+}
+
+void StaticANIObject::draw() {
+ if ((_flags & 4) == 0)
+ return;
+
+ Common::Point point;
+ Common::Rect rect;
+
+ debug(0, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if (_shadowsOn && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_shadows
+ && (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) {
+
+ DynamicPhase *dyn;
+
+ if (!_movement || _flags & 0x20)
+ dyn = _statics;
+ else
+ dyn = _movement->_currDynamicPhase;
+
+ if (!dyn) {
+ warning("HACK: StaticANIObject::draw(): dyn is missing");
+ return;
+ }
+
+ if (dyn->getDynFlags() & 4) {
+ rect = *dyn->_rect;
+
+ DynamicPhase *shd = g_fullpipe->_currentScene->_shadows->findSize(rect.width(), rect.height());
+ if (shd) {
+ shd->getDimensions(&point);
+ int midx = _ox - point.x / 2 - dyn->_someX;
+ int midy = _oy - point.y / 2 - dyn->_someY + rect.bottom - 3;
+ int shdw = point.y;
+
+ int px;
+ if (!_movement || (_flags & 0x20))
+ px = _statics->getCenter(&point)->x;
+ else
+ px = _movement->getCenter(&point)->x;
+
+ if (_shadowsOn != 1)
+ midy = _shadowsOn - shdw / 2;
+
+ shd->draw(px + midx, midy, 0, 0);
+ }
+ }
+ }
+
+ int angle = 0;
+ if (_field_30 & 0xC000) {
+ if (_field_30 & 0x8000)
+ angle = -(_field_30 ^ 0x8000);
+ else
+ angle = _field_30 ^ 0x4000;
+ }
+
+ if (!_movement || (_flags & 0x20)) {
+ _statics->getSomeXY(point);
+ _statics->_x = _ox - point.x;
+ _statics->_y = _oy - point.y;
+ _statics->draw(_statics->_x, _statics->_y, 0, angle);
+ } else {
+ _movement->draw(0, angle);
+ }
+}
+
+void StaticANIObject::draw2() {
+ debug(0, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if ((_flags & 4) && (_flags & 0x10)) {
+ if (_movement) {
+ _movement->draw(1, 0);
+ } else {
+ Common::Point point;
+
+ _statics->getSomeXY(point);
+
+ _statics->draw(_ox - point.x, _oy - point.y, 1, 0);
+ }
+ }
+}
+
+MovTable *StaticANIObject::countMovements() {
+ GameVar *preloadSubVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD");
+
+ if (!preloadSubVar || preloadSubVar->getSubVarsCount() == 0)
+ return 0;
+
+ MovTable *movTable = new MovTable;
+
+ movTable->count = _movements.size();
+ movTable->movs = (int16 *)calloc(_movements.size(), sizeof(int16));
+
+ for (uint i = 0; i < _movements.size(); i++) {
+ GameObject *obj = (GameObject *)_movements[i];
+ movTable->movs[i] = 2;
+
+ for (GameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) {
+ if (scumm_stricmp(obj->getName(), sub->_varName) == 0) {
+ movTable->movs[i] = 1;
+ break;
+ }
+ }
+ }
+
+ return movTable;
+}
+
+void StaticANIObject::setSpeed(int speed) {
+ GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("SpeedUp");
+
+ if (!var)
+ return;
+
+ for (var = var->_subVars; var; var = var->_nextVarObj) {
+ Movement *mov = getMovementById(var->_value.intValue);
+
+ if (mov) {
+ if (speed) {
+ if (mov->_counterMax == 83)
+ mov->_counterMax = 41;
+ } else if (mov->_counterMax == 41) {
+ mov->_counterMax = 83;
+ }
+ }
+ }
+
+}
+
+void StaticANIObject::setAlpha(int alpha) {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->setAlpha(alpha);
+
+ for (uint i = 0; i < _staticsList.size(); i++)
+ ((Statics *)_staticsList[i])->setAlpha(alpha);
+}
+
+void StaticANIObject::initMovements() {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->removeFirstPhase();
+}
+
+Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
+ Picture *pic;
+
+ if (_movement)
+ pic = _movement->_currDynamicPhase;
+ else
+ pic = _statics;
+
+ if (pic) {
+ Common::Point point;
+
+ pic->getDimensions(&point);
+ p.x = point.x;
+ p.y = point.y;
+ } else {
+ p.x = 0;
+ p.y = 0;
+ }
+
+ return &p;
+}
+
+Common::Point *StaticANIObject::getSomeXY(Common::Point &p) {
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(p);
+
+ return &p;
+ }
+
+ if (_statics)
+ _statics->getSomeXY(p);
+
+ return &p;
+}
+
+void StaticANIObject::update(int counterdiff) {
+ int mqid;
+
+ debug(6, "StaticANIObject::update() (%s) [%d] [%d, %d] fl: %x", transCyrillic((byte *)_objectName), _id, _ox, _oy, _flags);
+
+ if (_flags & 2) {
+ _messageNum--;
+ if (_messageNum)
+ return;
+
+ mqid = _messageQueueId;
+ _messageQueueId = 0;
+ _flags ^= 2;
+
+ updateGlobalMessageQueue(mqid, _id);
+ return;
+ }
+
+ Common::Point point;
+ ExCommand *ex, *newex;
+
+ if (_movement) {
+ _movement->_counter += counterdiff;
+
+ if (_movement->_counter < _movement->_counterMax)
+ return;
+
+ _movement->_counter = 0;
+
+ if (_flags & 1) {
+ if (_counter) {
+ _counter--;
+
+ return;
+ }
+
+ DynamicPhase *dyn = _movement->_currDynamicPhase;
+ if (dyn->_initialCountdown == dyn->_countdown) {
+
+ ex = dyn->getExCommand();
+ if (ex && ex->_messageKind != 35) {
+ newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ if (newex->_messageKind == 17) {
+ newex->_parentId = _id;
+ newex->_keyCode = _okeyCode;
+ }
+ newex->sendMessage();
+
+ if (!_movement)
+ return;
+ }
+ }
+
+ if (dyn->_initialCountdown != dyn->_countdown || dyn->_field_68 == 0) {
+ newex = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0);
+ newex->_excFlags = 2;
+ newex->_keyCode = _okeyCode;
+ newex->sendMessage();
+
+ if (!_movement)
+ return;
+ }
+
+ if (!_movement->gotoNextFrame(_callback1, _callback2)) {
+ stopAnim_maybe();
+ } else {
+ setOXY(_movement->_ox, _movement->_oy);
+ _counter = _initialCounter;
+
+ if (dyn->_initialCountdown == dyn->_countdown) {
+ ex = dyn->getExCommand();
+ if (ex) {
+ if (ex->_messageKind == 35) {
+ newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ newex->sendMessage();
+ }
+ }
+ }
+ if (!_movement)
+ return;
+
+ _stepArray.getCurrPoint(&point);
+ setOXY(point.x + _ox, point.y + _oy);
+ _stepArray.gotoNextPoint();
+ if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex)
+ adjustSomeXY();
+ }
+ } else if (_flags & 0x20) {
+ _flags ^= 0x20;
+ _flags |= 1;
+
+ _movement->gotoFirstFrame();
+ _movement->getCurrDynamicPhaseXY(point);
+
+ Common::Point pointS;
+ _statics->getSomeXY(pointS);
+ _movement->setOXY(_ox + point.x + _movement->_mx - pointS.x,
+ _oy + point.y + _movement->_my - pointS.y);
+ }
+ } else {
+ if (_statics) {
+ if (_messageQueueId) {
+ if (_statics->_countdown) {
+ _statics->_countdown--;
+ return;
+ }
+ mqid = _messageQueueId;
+ _messageQueueId = 0;
+ updateGlobalMessageQueue(mqid, _id);
+ }
+ }
+ }
+}
+
+void StaticANIObject::updateStepPos() {
+ Common::Point point;
+
+ int ox = _movement->_ox;
+ int oy = _movement->_oy;
+
+ _movement->calcSomeXY(point, 1);
+ int x = point.x;
+ int y = point.y;
+
+ _stepArray.getPoint(&point, -1, _stepArray.getPointsCount());
+ x += point.x;
+ y += point.y;
+
+ _statics = _movement->_staticsObj2;
+ _movement = 0;
+
+ setOXY(ox + x, oy + y);
+}
+
+void StaticANIObject::stopAnim_maybe() {
+ debug(6, "StaticANIObject::stopAnim_maybe()");
+
+ if (!(_flags & 1))
+ return;
+
+ _flags ^= 1;
+
+ int oid = 0;
+ int oldmqid = _messageQueueId;
+ Common::Point point;
+
+ if (_movement) {
+ setOXY(_movement->_ox, _movement->_oy);
+
+ if (_flags & 0x40) {
+ if (!_movement->_currMovement && !_movement->_currDynamicPhaseIndex) {
+ _statics = _movement->_staticsObj1;
+ _movement->getCurrDynamicPhaseXY(point);
+ _ox -= point.x;
+ _oy -= point.y;
+
+ _ox -= _movement->_mx;
+ _oy -= _movement->_my;
+
+ _statics->getSomeXY(point);
+ if (_movement->_currMovement) {
+ _oy += point.y;
+ _ox -= point.x;
+ _ox += _statics->getDimensions(&point)->x;
+ } else {
+ _ox += point.x;
+ _oy += point.y;
+ }
+ }
+ }
+
+ if (_movement->_currDynamicPhaseIndex || !(_flags & 0x40))
+ _statics = _movement->_staticsObj2;
+
+ _statics->getSomeXY(point);
+
+ _statics->_x = _ox - point.x;
+ _statics->_y = _oy - point.y;
+ oid = _movement->_id;
+ _movement = 0;
+
+ ExCommand *ex = new ExCommand(_id, 17, 24, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = _okeyCode;
+ ex->_excFlags = 2;
+ ex->postMessage();
+ }
+
+ int mqid = _messageQueueId;
+
+ if (_animExFlag) {
+ _messageQueueId = 0;
+ startAnimEx(oid, mqid, -1, -1);
+ } else {
+ if (_messageQueueId == oldmqid) {
+ _messageQueueId = 0;
+ if (_field_34 == 1)
+ updateGlobalMessageQueue(mqid, _id);
+ }
+ }
+}
+
+void StaticANIObject::adjustSomeXY() {
+ warning("STUB: StaticANIObject::adjustSomeXY()");
+}
+
+MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
+ warning("STUB: StaticANIObject::changeStatics1(%d)", msgNum);
+
+ return 0;
+}
+
+void StaticANIObject::changeStatics2(int objId) {
+ warning("STUB: StaticANIObject::changeStatics2(%d)", objId);
+}
+
+void StaticANIObject::hide() {
+ if (!_messageQueueId) {
+ if (_flags & 4)
+ _flags ^= 4;
+ }
+}
+
+void StaticANIObject::show1(int x, int y, int movId, int mqId) {
+ debug(0, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId);
+
+ if (_messageQueueId)
+ return;
+
+ if (movId == -1) {
+ _flags |= 4u;
+ if (x != -1 && y != -1) {
+ setOXY(x, y);
+ }
+
+ return;
+ }
+
+ Movement *mov = getMovementById(movId);
+ if (!mov)
+ return;
+
+ if (x != -1 && y != -1) {
+ setOXY(x, y);
+ }
+
+ _statics = mov->_staticsObj1;
+
+ Common::Point point;
+
+ mov->_staticsObj1->getSomeXY(point);
+ _statics->_x = x - point.x;
+ _statics->_y = y - point.y;
+
+ _statics->_countdown = _statics->_initialCountdown;
+
+ _flags |= 4;
+ _ox = x;
+ _oy = y;
+ _movement = 0;
+
+ if (mov->_currMovement)
+ _flags |= 8;
+ else if (_flags & 8)
+ _flags ^= 8;
+
+ if (_flags & 1)
+ _flags ^= 1;
+
+ _messageQueueId = mqId;
+}
+
+void StaticANIObject::show2(int x, int y, int movementId, int mqId) {
+ warning("STUB: StaticANIObject::show2(%d, %d, %d, %d)", x, y, movementId, mqId);
+}
+
+void StaticANIObject::playIdle() {
+ if (isIdle())
+ adjustSomeXY();
+}
+
+void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex) {
+ warning("STUB: StaticANIObject::startAnimSteps()");
+}
+
+bool StaticANIObject::startAnimEx(int movid, int parId, int flag1, int flag2) {
+ bool res = startAnim(movid, parId, -1);
+ if (res)
+ _animExFlag = 1;
+
+ _someDynamicPhaseIndex = -1;
+ return res;
+}
+
+bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhaseIdx) {
+ if (_flags & 0x80)
+ return false;
+
+ debug(0, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if (_messageQueueId) {
+ updateGlobalMessageQueue(messageQueueId, _id);
+ return false;
+ }
+
+ Movement *mov = 0;
+
+ for (uint i = 0; i < _movements.size(); i++) {
+
+ if (((Movement *)_movements[i])->_id == movementId) {
+ mov = (Movement *)_movements[i];
+ break;
+ }
+ }
+
+ if (!mov) {
+ updateGlobalMessageQueue(messageQueueId, _id);
+ return false;
+ }
+
+ if (mov == _movement) {
+ _flags |= 1;
+ _messageQueueId = messageQueueId;
+
+ return true;
+ }
+
+ int newx = _ox;
+ int newy = _oy;
+ Common::Point point;
+
+ debug(0, "0 %d %d", newx, newy);
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(point);
+
+ newx -= point.x;
+ newy -= point.y;
+
+ debug(0, "1 %d %d", newx, newy);
+ } else if (_statics) {
+ _statics->getSomeXY(point);
+
+ newx -= point.x;
+ newy -= point.y;
+ debug(0, "2 %d %d - %d %d assa", newx, newy, point.x, point.y);
+ }
+
+ _movement = mov;
+
+ _stepArray.clear();
+
+ if (_flags & 0x40)
+ _movement->gotoLastFrame();
+ else
+ _movement->gotoFirstFrame();
+
+ if (!(_flags & 0x40)) {
+ if (!_movement->_currDynamicPhaseIndex) {
+ _stepArray.getCurrPoint(&point);
+ newx += point.x + _movement->_mx;
+ newy += point.y + _movement->_my;
+
+ debug(0, "3 %d %d", newx, newy);
+ _stepArray.gotoNextPoint();
+
+ ExCommand *ex = _movement->_currDynamicPhase->getExCommand();
+ if (ex) {
+ if (ex->_messageKind == 35) {
+ ExCommand *newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ newex->sendMessage();
+ }
+ }
+ }
+ }
+
+ _movement->getCurrDynamicPhaseXY(point);
+ setOXY(point.x + newx, point.y + newy);
+
+ if (_movement->_staticsObj2->_staticsId & 0x4000)
+ _flags |= 8;
+ else
+ _flags &= 0xFFF7;
+
+ _flags |= 1;
+
+ _messageQueueId = messageQueueId;
+ _movement->_currDynamicPhase->_countdown = _movement->_currDynamicPhase->_initialCountdown;
+ _movement->_counter = 0;
+
+ _counter = _initialCounter;
+ _someDynamicPhaseIndex = dynPhaseIdx;
+
+ _stepArray.clear();
+
+ ExCommand *newex = new ExCommand(_id, 17, 23, 0, 0, movementId, 1, 0, 0, 0);
+
+ newex->_keyCode = _okeyCode;
+ newex->_excFlags = 2;
+
+ newex->postMessage();
+
+ return true;
+}
+
+Statics::Statics() {
+ _staticsId = 0;
+ _picture = 0;
+ _staticsName = 0;
+}
+
+Statics::~Statics() {
+ delete _picture;
+ free(_staticsName);
+}
+
+Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) {
+ _staticsId = src->_staticsId;
+
+ if (reverse) {
+ _staticsId ^= 0x4000;
+ int newlen = strlen(src->_staticsName) + strlen(sO_MirroredTo) + 1;
+ _staticsName = (char *)calloc(newlen, 1);
+
+ snprintf(_staticsName, newlen, "%s%s", sO_MirroredTo, src->_staticsName);
+ } else {
+ _staticsName = (char *)calloc(strlen(src->_staticsName) + 1, 1);
+ strncpy(_staticsName, src->_staticsName, strlen(src->_staticsName) + 1);
+ }
+
+ _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1);
+ strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1);
+
+ _picture = new Picture();
+}
+
+bool Statics::load(MfcArchive &file) {
+ debug(5, "Statics::load()");
+
+ DynamicPhase::load(file);
+
+ _staticsId = file.readUint16LE();
+
+ _staticsName = file.readPascalString();
+ debug(7, "statics: <%s> id: %d (%x)", transCyrillic((byte *)_staticsName), _staticsId, _staticsId);
+
+ _picture = new Picture();
+ _picture->load(file);
+
+ return true;
+}
+
+Common::Point *Statics::getSomeXY(Common::Point &p) {
+ p.x = _someX;
+ p.y = _someY;
+
+ return &p;
+}
+
+Common::Point *Statics::getCenter(Common::Point *p) {
+ Common::Rect rect;
+
+ rect = *_rect;
+
+ if (_staticsId & 0x4000) {
+ Common::Point point;
+
+ getDimensions(&point);
+ rect.moveTo(point.x - _rect->right, _rect->top);
+ }
+
+ p->x = rect.left + _rect->width() / 2;
+ p->y = rect.top + _rect->height() / 2;
+
+ return p;
+}
+
+Movement::Movement() {
+ _lastFrameSpecialFlag = 0;
+ _flipFlag = 0;
+ _updateFlag1 = 0;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+ _field_50 = 1;
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = 0;
+ _field_94 = 0;
+ _currMovement = 0;
+ _counter = 0;
+ _counterMax = 83;
+
+ _somePoint.x = 0;
+ _somePoint.y = 0;
+}
+
+Movement::Movement(Movement *src, StaticANIObject *ani) {
+ _lastFrameSpecialFlag = 0;
+ _flipFlag = src->_flipFlag;
+ _updateFlag1 = src->_updateFlag1;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = src->_currDynamicPhaseIndex;
+ _field_94 = 0;
+
+ _somePoint.x = 0;
+ _somePoint.y = 0;
+
+ _currMovement = src;
+ _ox = src->_ox;
+ _oy = src->_oy;
+
+ initStatics(ani);
+
+ _counterMax = src->_counterMax;
+ _counter = src->_counter;
+ _field_50 = src->_field_50;
+
+ updateCurrDynamicPhase();
+}
+
+Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *ani) : GameObject(src) {
+ _lastFrameSpecialFlag = 0;
+ _updateFlag1 = 1;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = 0;
+ _field_94 = 0;
+
+ _somePoint.x = 0;
+ _somePoint.y = 0;
+
+ _field_50 = src->_field_50;
+ _flipFlag = src->_flipFlag;
+ _currMovement = 0;
+ _mx = src->_mx;
+ _my = src->_my;
+ _m2x = src->_m2x;
+ _m2y = src->_m2y;
+
+ if (newSize != -1) {
+ if (newSize >= (int)src->_dynamicPhases.size() + 1)
+ newSize = src->_dynamicPhases.size() + 1;
+ } else {
+ newSize = src->_dynamicPhases.size();
+ }
+
+ _framePosOffsets = (Common::Point **)calloc(newSize, sizeof(Common::Point *));
+
+ for (int i = 0; i < newSize; i++)
+ _framePosOffsets[i] = new Common::Point();
+
+ if (oldIdxs) {
+ for (int i = 0; i < newSize - 1; i++, oldIdxs++) {
+ if (oldIdxs[i] == -1) {
+ _dynamicPhases.push_back(src->_staticsObj1);
+
+ _framePosOffsets[i]->x = 0;
+ _framePosOffsets[i]->y = 0;
+ } else {
+ src->setDynamicPhaseIndex(oldIdxs[i]);
+
+ _dynamicPhases.push_back(src->_currDynamicPhase);
+
+ _framePosOffsets[i]->x = src->_framePosOffsets[oldIdxs[i]]->x;
+ _framePosOffsets[i]->y = src->_framePosOffsets[oldIdxs[i]]->y;
+ }
+ }
+ _staticsObj1 = (Statics *)_dynamicPhases.front();
+ _staticsObj2 = (Statics *)_dynamicPhases.back();
+ } else {
+ for (int i = 0; i < newSize; i++) {
+ src->setDynamicPhaseIndex(i);
+
+ if (i < newSize - 1)
+ _dynamicPhases.push_back(new DynamicPhase(src->_currDynamicPhase, 0));
+
+ _framePosOffsets[i]->x = src->_framePosOffsets[i]->x;
+ _framePosOffsets[i]->y = src->_framePosOffsets[i]->y;
+ }
+
+ _staticsObj1 = ani->getStaticsById(src->_staticsObj1->_staticsId);
+ _staticsObj2 = ani->getStaticsById(src->_staticsObj2->_staticsId);
+
+ _dynamicPhases.push_back(_staticsObj2);
+
+ this->_updateFlag1 = src->_updateFlag1;
+ }
+
+ updateCurrDynamicPhase();
+ removeFirstPhase();
+
+ _counterMax = src->_counterMax;
+ _counter = src->_counter;
+}
+
+bool Movement::load(MfcArchive &file) {
+ warning("STUB: Movement::load");
+ return true;
+}
+
+bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
+ GameObject::load(file);
+
+ int dynCount = file.readUint16LE();
+
+ debug(7, "dynCount: %d _id: %d", dynCount, _id);
+ if (dynCount != 0xffff || _id == MV_MAN_TURN_LU) {
+ _framePosOffsets = (Common::Point **)calloc(dynCount + 2, sizeof(Common::Point *));
+
+ for (int i = 0; i < dynCount + 2; i++)
+ _framePosOffsets[i] = new Common::Point();
+
+ for (int i = 0; i < dynCount; i++) {
+ DynamicPhase *ph = new DynamicPhase();
+ ph->load(file);
+
+ _dynamicPhases.push_back(ph);
+
+ _framePosOffsets[i]->x = ph->_x;
+ _framePosOffsets[i]->y = ph->_y;
+ }
+
+ int staticsid = file.readUint16LE();
+
+ _staticsObj1 = ani->getStaticsById(staticsid);
+
+ if (!_staticsObj1 && (staticsid & 0x4000)) {
+ Statics *s = ani->getStaticsById(staticsid ^ 0x4000);
+ _staticsObj1 = ani->addReverseStatics(s);
+ }
+
+ _mx = file.readUint32LE();
+ _my = file.readUint32LE();
+
+ staticsid = file.readUint16LE();
+
+ _staticsObj2 = ani->getStaticsById(staticsid);
+
+ if (!_staticsObj2 && (staticsid & 0x4000)) {
+ Statics *s = ani->getStaticsById(staticsid ^ 0x4000);
+ _staticsObj2 = ani->addReverseStatics(s);
+ }
+
+ _m2x = file.readUint32LE();
+ _m2y = file.readUint32LE();
+
+ if (_staticsObj2) {
+ _dynamicPhases.push_back(_staticsObj2);
+
+ _framePosOffsets[_dynamicPhases.size() - 1]->x = _m2x;
+ _framePosOffsets[_dynamicPhases.size() - 1]->y = _m2y;
+ }
+
+ } else {
+ int movid = file.readUint16LE();
+
+ _currMovement = ani->getMovementById(movid);
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+
+ initStatics(ani);
+ }
+
+ if (_staticsObj1 && _staticsObj2) {
+ if ((_staticsObj1->_staticsId ^ _staticsObj2->_staticsId) & 0x4000)
+ _flipFlag = 1;
+ }
+
+ if (g_fullpipe->_gameProjectVersion >= 8)
+ _field_50 = file.readUint32LE();
+
+ if (g_fullpipe->_gameProjectVersion < 12)
+ _counterMax = 83;
+ else
+ _counterMax = file.readUint32LE();
+
+ _counter = 0;
+ updateCurrDynamicPhase();
+
+ return true;
+}
+
+Common::Point *Movement::getCurrDynamicPhaseXY(Common::Point &p) {
+ p.x = _currDynamicPhase->_someX;
+ p.y = _currDynamicPhase->_someY;
+
+ return &p;
+}
+
+Common::Point *Movement::calcSomeXY(Common::Point &p, int idx) {
+ int oldox = _ox;
+ int oldoy = _oy;
+ int oldidx = _currDynamicPhaseIndex;
+
+ int x = 0;
+ int y = 0;
+
+ if (!idx) {
+ Common::Point point;
+
+ _staticsObj1->getSomeXY(point);
+ int y1 = _my - point.y;
+ int x1 = _mx - point.x;
+
+ setDynamicPhaseIndex(0);
+
+ x = _currDynamicPhase->_someX + x1;
+ y = _currDynamicPhase->_someY + y1;
+ }
+
+ setOXY(x, y);
+
+ while (_currDynamicPhaseIndex != idx)
+ gotoNextFrame(0, 0);
+
+ p.x = _ox;
+ p.y = _oy;
+
+ setDynamicPhaseIndex(oldidx);
+ setOXY(oldox, oldoy);
+
+ return &p;
+}
+
+void Movement::setAlpha(int alpha) {
+ if (_currMovement)
+ for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
+ ((DynamicPhase *)_currMovement->_dynamicPhases[i])->setAlpha(alpha);
+ }
+ else
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ ((DynamicPhase *)_dynamicPhases[i])->setAlpha(alpha);
+ }
+}
+
+Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex) {
+ int idx = phaseIndex;
+
+ if (idx == -1)
+ idx = _currDynamicPhaseIndex;
+
+ DynamicPhase *dyn;
+
+ if (_currMovement)
+ dyn = (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ else
+ dyn = (DynamicPhase *)_dynamicPhases[idx];
+
+ Common::Point point;
+
+ dyn->getDimensions(&point);
+
+ *p = point;
+
+ return p;
+}
+
+void Movement::initStatics(StaticANIObject *ani) {
+ if (!_currMovement)
+ return;
+
+ debug(7, "Movement::initStatics()");
+
+ _staticsObj2 = ani->addReverseStatics(_currMovement->_staticsObj2);
+ _staticsObj1 = ani->addReverseStatics(_currMovement->_staticsObj1);
+
+ _mx = _currMovement->_mx;
+ _my = _currMovement->_my;
+
+ _currMovement->setDynamicPhaseIndex(_currMovement->_updateFlag1 != 0 ? 1 : 0);
+
+ Common::Point point;
+
+ int x1 = _currMovement->_staticsObj1->getDimensions(&point)->x - _mx;
+
+ _mx = x1 - _currMovement->_currDynamicPhase->getDimensions(&point)->x;
+
+ _currMovement->setDynamicPhaseIndex(_currMovement->_currDynamicPhaseIndex);
+
+ _m2x = _currMovement->_m2x;
+ _m2y = _currMovement->_m2y;
+ _currMovement->gotoLastFrame();
+
+ x1 = _currMovement->_staticsObj2->getDimensions(&point)->x;
+ _m2x = _currMovement->_currDynamicPhase->getDimensions(&point)->x - _m2x - x1;
+}
+
+void Movement::updateCurrDynamicPhase() {
+ debug(7, "Movement::updateCurrDynamicPhase()");
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _currMovement->_dynamicPhases.size())
+ return;
+
+ if (_currMovement->_dynamicPhases[_currDynamicPhaseIndex])
+ _currDynamicPhase = (DynamicPhase *)_currMovement->_dynamicPhases[_currDynamicPhaseIndex];
+ } else {
+ if (_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _dynamicPhases.size())
+ return;
+
+ if (_dynamicPhases[_currDynamicPhaseIndex])
+ _currDynamicPhase = (DynamicPhase *)_dynamicPhases[_currDynamicPhaseIndex];
+ }
+}
+
+int Movement::calcDuration() {
+ int res = 0;
+
+ if (_currMovement)
+ for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
+ res += ((DynamicPhase *)_currMovement->_dynamicPhases[i])->_initialCountdown;
+ }
+ else
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ res += ((DynamicPhase *)_dynamicPhases[i])->_initialCountdown;
+ }
+
+ return res;
+}
+
+void Movement::setDynamicPhaseIndex(int index) {
+ debug(7, "Movement::setDynamicPhaseIndex(%d)", index);
+ while (_currDynamicPhaseIndex < index)
+ gotoNextFrame(0, 0);
+
+ while (_currDynamicPhaseIndex > index)
+ gotoPrevFrame();
+}
+
+DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) {
+ debug(7, "Movement::updateCurrDynamicPhase()");
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size())
+ return 0;
+
+ return (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ } else {
+ if (_dynamicPhases.size() == 0 || (uint)idx >= _dynamicPhases.size())
+ return 0;
+
+ return (DynamicPhase *)_dynamicPhases[idx];
+ }
+}
+
+void Movement::loadPixelData() {
+ Movement *mov = this;
+ for (Movement *i = _currMovement; i; i = i->_currMovement)
+ mov = i;
+
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ if ((Statics *)_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000))
+ ((Statics *)_dynamicPhases[i])->getPixelData();
+ }
+
+ if (!(mov->_staticsObj1->_staticsId & 0x4000))
+ mov->_staticsObj1->getPixelData();
+}
+
+void Movement::removeFirstPhase() {
+ if (_updateFlag1) {
+ if (!_currDynamicPhaseIndex)
+ gotoNextFrame(0, 0);
+
+ if (!_currMovement) {
+ _dynamicPhases.remove_at(0);
+
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ _framePosOffsets[i - 1]->x = _framePosOffsets[i]->x;
+ _framePosOffsets[i - 1]->y = _framePosOffsets[i]->y;
+ }
+ }
+ _currDynamicPhaseIndex--;
+ }
+
+ updateCurrDynamicPhase();
+ _updateFlag1 = 0;
+}
+
+bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) {
+ debug(8, "Movement::gotoNextFrame()");
+
+ if (!callback2) {
+ if (_currMovement) {
+ if ((uint)_currDynamicPhaseIndex == _currMovement->_dynamicPhases.size() - 1
+ && !(((DynamicPhase *)(_currMovement->_dynamicPhases.back()))->_countdown)) {
+ return false;
+ }
+ } else if ((uint)_currDynamicPhaseIndex == _dynamicPhases.size() - 1
+ && !(((DynamicPhase *)(_dynamicPhases.back()))->_countdown)) {
+ return false;
+ }
+ }
+
+ if (_currDynamicPhase->_countdown) {
+ _currDynamicPhase->_countdown--;
+ return true;
+ }
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+ _ox -= point.x;
+ _oy -= point.y;
+
+ int deltax = 0;
+
+ if (_currMovement)
+ deltax = _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+
+ int oldDynIndex = _currDynamicPhaseIndex;
+
+ if (callback2)
+ callback2(&_currDynamicPhaseIndex);
+ else
+ _currDynamicPhaseIndex++;
+
+ bool result = true;
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) {
+ _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
+ result = (callback2 == 0);
+ }
+ if (_currDynamicPhaseIndex < 0) {
+ _currDynamicPhaseIndex = 0;
+ result = false;
+ }
+ if (_currMovement->_framePosOffsets) {
+ if (callback1) {
+ point = *_currMovement->_framePosOffsets[_currDynamicPhaseIndex];
+ //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+
+ _ox += deltax - point.x;
+ _oy += point.y;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ } else if (oldDynIndex >= _currDynamicPhaseIndex) {
+ while (oldDynIndex > _currDynamicPhaseIndex) {
+ _ox += deltax;
+ deltax = _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+
+ _ox += _currMovement->_framePosOffsets[oldDynIndex]->x;
+ _oy -= _currMovement->_framePosOffsets[oldDynIndex]->y;
+ oldDynIndex--;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+ }
+ } else {
+ for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
+ _ox += deltax;
+ deltax = _currMovement->getDimensionsOfPhase(&point, i)->x;
+ _ox -= _currMovement->_framePosOffsets[i]->x;
+ _oy += _currMovement->_framePosOffsets[i]->y;
+ _ox -= _currMovement->getDimensionsOfPhase(&point, i)->x;
+ }
+ }
+ }
+ } else {
+ if (_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) {
+ _currDynamicPhaseIndex = _dynamicPhases.size() - 1;
+ result = (callback2 == 0);
+ }
+ if (_currDynamicPhaseIndex < 0) {
+ _currDynamicPhaseIndex = 0;
+ result = false;
+ }
+
+ if (_framePosOffsets) {
+ if (callback1) {
+ point.x = _framePosOffsets[_currDynamicPhaseIndex]->x;
+ point.y = _framePosOffsets[_currDynamicPhaseIndex]->y;
+
+ //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+ _ox += point.x;
+ _oy += point.y;
+ } else if (oldDynIndex >= _currDynamicPhaseIndex) {
+ for (int i = oldDynIndex; i > _currDynamicPhaseIndex; i--) {
+ _ox -= _framePosOffsets[i]->x;
+ _oy -= _framePosOffsets[i]->y;
+ }
+ } else {
+ for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
+ _ox += _framePosOffsets[i]->x;
+ _oy += _framePosOffsets[i]->y;
+ }
+ }
+ }
+ }
+
+ updateCurrDynamicPhase();
+ getCurrDynamicPhaseXY(point);
+ _ox += point.x;
+ _oy += point.y;
+
+ _currDynamicPhase->_countdown = _currDynamicPhase->_initialCountdown;
+
+ return result;
+}
+
+bool Movement::gotoPrevFrame() {
+ debug(8, "Movement::gotoPrevFrame()");
+
+ if (!_currDynamicPhaseIndex) {
+ gotoLastFrame();
+ return false;
+ }
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+
+ _ox -= point.x;
+ _oy -= point.y;
+
+ if (_currMovement) {
+ if (_currMovement->_framePosOffsets) {
+ _ox += _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ _ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->x;
+ _oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->y;
+ }
+
+ _currDynamicPhaseIndex--;
+ if (_currDynamicPhaseIndex < 0)
+ _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ } else {
+ if (_framePosOffsets) {
+ _ox -= _framePosOffsets[_currDynamicPhaseIndex]->x;
+ _oy -= _framePosOffsets[_currDynamicPhaseIndex]->y;
+ }
+
+ _currDynamicPhaseIndex--;
+ if (_currDynamicPhaseIndex < 0)
+ _currDynamicPhaseIndex = _dynamicPhases.size() - 1;
+ }
+
+ updateCurrDynamicPhase();
+ getCurrDynamicPhaseXY(point);
+
+ _ox += point.x;
+ _oy += point.y;
+
+ return true;
+}
+
+void Movement::gotoFirstFrame() {
+ while (_currDynamicPhaseIndex)
+ gotoPrevFrame();
+}
+
+void Movement::gotoLastFrame() {
+ if (_currMovement) {
+ while ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1)
+ gotoNextFrame(0, 0);
+ } else {
+ while ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1)
+ gotoNextFrame(0, 0);
+ }
+}
+
+Common::Point *Movement::getCenter(Common::Point *p) {
+ Common::Rect rect;
+
+ rect = *_currDynamicPhase->_rect;
+
+ if (_currMovement) {
+ Common::Point point;
+
+ _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex);
+
+ rect.moveTo(point.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top);
+ }
+
+ p->x = rect.left + _currDynamicPhase->_rect->width() / 2;
+ p->y = rect.top + _currDynamicPhase->_rect->height() / 2;
+
+ return p;
+}
+
+DynamicPhase::DynamicPhase() {
+ _someX = 0;
+ _rect = 0;
+ _field_7C = 0;
+ _field_7E = 0;
+ _dynFlags = 0;
+ _someY = 0;
+}
+
+DynamicPhase::~DynamicPhase() {
+ delete _rect;
+}
+
+DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
+ _field_7C = src->_field_7C;
+ _field_7E = 0;
+ _rect = new Common::Rect();
+
+ debug(0, "DynamicPhase::DynamicPhase(src, %d)", reverse);
+
+ if (reverse) {
+ if (!src->_bitmap)
+ src->init();
+
+ _bitmap = src->_bitmap->reverseImage();
+ _data = _bitmap->_pixels;
+ _dataSize = src->_dataSize;
+
+ if (g_fullpipe->_currArchive) {
+ _mfield_14 = 0;
+ _libHandle = g_fullpipe->_currArchive;
+ }
+
+ _mflags |= 1;
+
+ _someX = src->_someX;
+ _someY = src->_someY;
+ } else {
+ _mfield_14 = src->_mfield_14;
+ _mfield_8 = src->_mfield_8;
+ _mflags = src->_mflags;
+
+ _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1);
+ strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1);
+ _dataSize = src->_dataSize;
+ _mfield_10 = src->_mfield_10;
+ _libHandle = src->_libHandle;
+
+ _bitmap = src->_bitmap;
+ if (_bitmap)
+ _field_54 = 1;
+
+ _someX = src->_someX;
+ _someY = src->_someY;
+ }
+
+ *_rect = *src->_rect;
+
+ _width = src->_width;
+ _height = src->_height;
+ _field_7C = src->_field_7C;
+
+ if (src->getExCommand())
+ _exCommand = new ExCommand(src->getExCommand());
+ else
+ _exCommand = 0;
+
+ _initialCountdown = src->_initialCountdown;
+ _field_6A = src->_field_6A;
+ _dynFlags = src->_dynFlags;
+
+ setPaletteData(src->getPaletteData());
+
+ copyMemoryObject2(src);
+}
+
+bool DynamicPhase::load(MfcArchive &file) {
+ debug(5, "DynamicPhase::load()");
+
+ StaticPhase::load(file);
+
+ _field_7C = file.readUint16LE();
+ _rect = new Common::Rect();
+ _rect->left = file.readUint32LE();
+ _rect->top = file.readUint32LE();
+ _rect->right = file.readUint32LE();
+ _rect->bottom = file.readUint32LE();
+
+ assert (g_fullpipe->_gameProjectVersion >= 1);
+
+ _someX = file.readUint32LE();
+ _someY = file.readUint32LE();
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ _dynFlags = file.readUint32LE();
+
+ return true;
+}
+
+StaticPhase::StaticPhase() {
+ _field_6A = 1;
+ _initialCountdown = 0;
+ _countdown = 0;
+ _field_68 = 0;
+ _exCommand = 0;
+}
+
+StaticPhase::~StaticPhase() {
+ delete _exCommand;
+}
+
+bool StaticPhase::load(MfcArchive &file) {
+ debug(5, "StaticPhase::load()");
+
+ Picture::load(file);
+
+ _initialCountdown = file.readUint16LE();
+ _field_6A = file.readUint16LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 12) {
+ _exCommand = (ExCommand *)file.readClass();
+
+ return true;
+ }
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
new file mode 100644
index 0000000000..15de4ab3be
--- /dev/null
+++ b/engines/fullpipe/statics.h
@@ -0,0 +1,257 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_STATICS_H
+#define FULLPIPE_STATICS_H
+
+#include "fullpipe/gfx.h"
+
+namespace Fullpipe {
+
+class ExCommand;
+
+class StepArray : public CObject {
+ int _currPointIndex;
+ Common::Point **_points;
+ int _maxPointIndex;
+ int _pointsCount;
+ int _isEos;
+
+ public:
+ StepArray();
+ ~StepArray();
+ void clear();
+
+ int getCurrPointIndex() { return _currPointIndex; }
+ int getPointsCount() { return _maxPointIndex; }
+
+ Common::Point *getCurrPoint(Common::Point *point);
+ Common::Point *getPoint(Common::Point *point, int index, int offset);
+ bool gotoNextPoint();
+};
+
+class StaticPhase : public Picture {
+ public:
+ int16 _initialCountdown;
+ int16 _countdown;
+ int16 _field_68;
+ int16 _field_6A;
+ ExCommand *_exCommand;
+
+ public:
+ StaticPhase();
+ virtual ~StaticPhase();
+
+ virtual bool load(MfcArchive &file);
+
+ ExCommand *getExCommand() { return _exCommand; }
+};
+
+class DynamicPhase : public StaticPhase {
+ public:
+ int _someX;
+ int _someY;
+ Common::Rect *_rect;
+ int16 _field_7C;
+ int16 _field_7E;
+ int _dynFlags;
+
+ public:
+ DynamicPhase();
+ DynamicPhase(DynamicPhase *src, bool reverse);
+ virtual ~DynamicPhase();
+
+ virtual bool load(MfcArchive &file);
+
+ int getDynFlags() { return _dynFlags; }
+};
+
+class Statics : public DynamicPhase {
+ public:
+ int16 _staticsId;
+ char *_staticsName;
+ Picture *_picture;
+
+ public:
+ Statics();
+ Statics(Statics *src, bool reverse);
+ virtual ~Statics();
+
+ virtual bool load(MfcArchive &file);
+ Statics *getStaticsById(int itemId);
+
+ Common::Point *getSomeXY(Common::Point &p);
+ Common::Point *getCenter(Common::Point *p);
+};
+
+class StaticANIObject;
+
+class Movement : public GameObject {
+ public:
+ Common::Point _somePoint;
+ int _lastFrameSpecialFlag;
+ int _flipFlag;
+ int _updateFlag1;
+ Statics *_staticsObj1;
+ Statics *_staticsObj2;
+ int _mx;
+ int _my;
+ int _m2x;
+ int _m2y;
+ int _field_50;
+ int _counterMax;
+ int _counter;
+ PtrList _dynamicPhases;
+ int _field_78;
+ Common::Point **_framePosOffsets;
+ Movement *_currMovement;
+ int _field_84;
+ DynamicPhase *_currDynamicPhase;
+ int _field_8C;
+ int _currDynamicPhaseIndex;
+ int _field_94;
+
+ public:
+ Movement();
+ Movement(Movement *src, StaticANIObject *ani);
+ Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani);
+
+ virtual bool load(MfcArchive &file);
+ bool load(MfcArchive &file, StaticANIObject *ani);
+
+ Common::Point *getCurrDynamicPhaseXY(Common::Point &p);
+ Common::Point *getCenter(Common::Point *p);
+ Common::Point *getDimensionsOfPhase(Common::Point *p, int phaseIndex);
+
+ Common::Point *calcSomeXY(Common::Point &p, int idx);
+
+ void initStatics(StaticANIObject *ani);
+ void updateCurrDynamicPhase();
+
+ void setAlpha(int alpha);
+
+ void setDynamicPhaseIndex(int index);
+ DynamicPhase *getDynamicPhaseByIndex(int idx);
+
+ int calcDuration();
+
+ void removeFirstPhase();
+ bool gotoNextFrame(int callback1, void (*callback2)(int *));
+ bool gotoPrevFrame();
+ void gotoFirstFrame();
+ void gotoLastFrame();
+
+ void loadPixelData();
+
+ void draw(bool flipFlag, int angle);
+};
+
+class StaticANIObject : public GameObject {
+ public:
+ Movement *_movement;
+ Statics *_statics;
+ int _shadowsOn;
+ int16 _field_30;
+ int16 _field_32;
+ int _field_34;
+ int _initialCounter;
+ int _callback1;
+ void (*_callback2)(int *);
+ PtrList _movements;
+ PtrList _staticsList;
+ StepArray _stepArray;
+ int16 _field_96;
+ int _messageQueueId;
+ int _messageNum;
+ int _animExFlag;
+ int _counter;
+ int _someDynamicPhaseIndex;
+
+ public:
+ int16 _sceneId;
+
+ public:
+ StaticANIObject();
+ StaticANIObject(StaticANIObject *src);
+
+ virtual bool load(MfcArchive &file);
+
+ void setOXY(int x, int y);
+ Statics *getStaticsById(int id);
+ Statics *getStaticsByName(char *name);
+ Movement *getMovementById(int id);
+ int getMovementIdById(int itemId);
+ Movement *getMovementByName(char *name);
+ Common::Point *getCurrDimensions(Common::Point &p);
+
+ Common::Point *getSomeXY(Common::Point &p);
+
+ void clearFlags();
+ void setFlags40(bool state);
+ bool isIdle();
+ void setAlpha(int alpha);
+
+ void deleteFromGlobalMessageQueue();
+ void queueMessageQueue(MessageQueue *msg);
+ MessageQueue *getMessageQueue();
+ bool trySetMessageQueue(int msgNum, int qId);
+
+ void initMovements();
+ void loadMovementsPixelData();
+
+ void setSomeDynamicPhaseIndex(int val) { _someDynamicPhaseIndex = val; }
+ void adjustSomeXY();
+
+ bool startAnim(int movementId, int messageQueueId, int dynPhaseIdx);
+ bool startAnimEx(int movid, int parId, int flag1, int flag2);
+ void startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex);
+
+ void hide();
+ void show1(int x, int y, int movementId, int mqId);
+ void show2(int x, int y, int movementId, int mqId);
+ void playIdle();
+ void update(int counterdiff);
+
+ Statics *addReverseStatics(Statics *ani);
+ void draw();
+ void draw2();
+
+ MovTable *countMovements();
+ void setSpeed(int speed);
+
+ void updateStepPos();
+ void stopAnim_maybe();
+
+ MessageQueue *changeStatics1(int msgNum);
+ void changeStatics2(int objId);
+
+ bool getPixelAtPos(int x, int y, int *pixel);
+};
+
+struct MovTable {
+ int count;
+ int16 *movs;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_STATICS_H */
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
new file mode 100644
index 0000000000..3a65801951
--- /dev/null
+++ b/engines/fullpipe/utils.cpp
@@ -0,0 +1,501 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/memstream.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+bool CObject::loadFile(const char *fname) {
+ Common::File file;
+
+ if (!file.open(fname))
+ return false;
+
+ MfcArchive archive(&file);
+
+ return load(archive);
+}
+
+bool ObList::load(MfcArchive &file) {
+ debug(5, "ObList::load()");
+ int count = file.readCount();
+
+ debug(9, "ObList::count: %d:", count);
+
+ for (int i = 0; i < count; i++) {
+ debug(9, "ObList::[%d]", i);
+ CObject *t = file.readClass();
+
+ push_back(t);
+ }
+
+ return true;
+}
+
+bool ObArray::load(MfcArchive &file) {
+ debug(5, "ObArray::load()");
+ int count = file.readCount();
+
+ resize(count);
+
+ for (int i = 0; i < count; i++) {
+ CObject *t = file.readClass();
+
+ push_back(*t);
+ }
+
+ return true;
+}
+
+bool DWordArray::load(MfcArchive &file) {
+ debug(5, "DWordArray::load()");
+ int count = file.readCount();
+
+ debug(9, "DWordArray::count: %d", count);
+
+ resize(count);
+
+ for (int i = 0; i < count; i++) {
+ int32 t = file.readUint32LE();
+
+ push_back(t);
+ }
+
+ return true;
+}
+
+char *MfcArchive::readPascalString(bool twoByte) {
+ char *tmp;
+ int len;
+
+ if (twoByte)
+ len = readUint16LE();
+ else
+ len = readByte();
+
+ tmp = (char *)calloc(len + 1, 1);
+ read(tmp, len);
+
+ debug(9, "readPascalString: %d <%s>", len, transCyrillic((byte *)tmp));
+
+ return tmp;
+}
+
+MemoryObject::MemoryObject() {
+ _memfilename = 0;
+ _mfield_8 = 0;
+ _mfield_C = 0;
+ _mfield_10 = -1;
+ _mfield_14 = 1;
+ _dataSize = 0;
+ _mflags = 0;
+ _libHandle = 0;
+ _data = 0;
+}
+
+MemoryObject::~MemoryObject() {
+ freeData();
+ if (_memfilename)
+ free(_memfilename);
+}
+
+bool MemoryObject::load(MfcArchive &file) {
+ debug(5, "MemoryObject::load()");
+ _memfilename = file.readPascalString();
+
+ if (char *p = strchr(_memfilename, '\\')) {
+ for (char *d = _memfilename; *p;) {
+ p++;
+ *d++ = *p;
+ }
+ }
+
+ if (g_fullpipe->_currArchive) {
+ _mfield_14 = 0;
+ _libHandle = g_fullpipe->_currArchive;
+ }
+
+ return true;
+}
+
+void MemoryObject::loadFile(char *filename) {
+ debug(5, "MemoryObject::loadFile(<%s>)", filename);
+
+ if (!*filename)
+ return;
+
+ if (!_data) {
+ NGIArchive *arr = g_fullpipe->_currArchive;
+
+ if (g_fullpipe->_currArchive != _libHandle && _libHandle)
+ g_fullpipe->_currArchive = _libHandle;
+
+ Common::SeekableReadStream *s = g_fullpipe->_currArchive->createReadStreamForMember(filename);
+
+ if (s) {
+ assert(s->size() > 0);
+
+ _dataSize = s->size();
+
+ debug(5, "Loading %s (%d bytes)", filename, _dataSize);
+ _data = (byte *)calloc(_dataSize, 1);
+ s->read(_data, _dataSize);
+
+ delete s;
+ } else {
+ warning("MemoryObject::loadFile(): reading failure");
+ }
+
+ g_fullpipe->_currArchive = arr;
+ }
+}
+
+byte *MemoryObject::getData() {
+ load();
+
+ if (_mfield_14 || _mflags & 1) {
+ return _data;
+ } else {
+ error("Unhandled packed data");
+ }
+}
+
+byte *MemoryObject::loadData() {
+ load();
+ return _data;
+}
+
+void MemoryObject::freeData() {
+ debug(8, "MemoryObject::freeData(): file: %s", _memfilename);
+
+ if (_data)
+ free(_data);
+
+ _data = 0;
+}
+
+bool MemoryObject::testFlags() {
+ if (_mfield_8)
+ return false;
+
+ if (_mflags & 1)
+ return true;
+
+ return false;
+}
+
+MemoryObject2::MemoryObject2() {
+ _rows = 0;
+}
+
+MemoryObject2::~MemoryObject2() {
+ if (_rows)
+ free(_rows);
+}
+
+bool MemoryObject2::load(MfcArchive &file) {
+ debug(5, "MemoryObject2::load()");
+ MemoryObject::load(file);
+
+ _mflags |= 1;
+
+ debug(5, "MemoryObject2::load: <%s>", _memfilename);
+
+ if (_memfilename && *_memfilename) {
+ MemoryObject::loadFile(_memfilename);
+ }
+
+ return true;
+}
+
+void MemoryObject2::copyData(byte *src, int dataSize) {
+ if (_data)
+ freeData();
+
+ _dataSize = dataSize;
+ _data = (byte *)malloc(dataSize);
+
+ memcpy(_data, src, _dataSize);
+}
+
+int MfcArchive::readCount() {
+ int count = readUint16LE();
+
+ if (count == 0xffff)
+ count = readUint32LE();
+
+ return count;
+}
+
+double MfcArchive::readDouble() {
+ // FIXME: This is utterly cruel and unportable
+ // Some articles on the matter:
+ // http://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/
+ // http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
+
+ union {
+ struct {
+ int32 a;
+ int32 b;
+ } i;
+ double d;
+ } tmp;
+
+ tmp.i.a = readUint32LE();
+ tmp.i.b = readUint32LE();
+
+ return tmp.d;
+}
+
+enum {
+ kNullObject,
+ kInteraction,
+ kMessageQueue,
+ kExCommand,
+ kObjstateCommand,
+ kGameVar,
+ kMctlCompound,
+ kMovGraph,
+ kMovGraphLink,
+ kMovGraphNode,
+ kReactParallel,
+ kReactPolygonal
+};
+
+const struct {
+ const char *name;
+ int id;
+} classMap[] = {
+ { "CInteraction", kInteraction },
+ { "MessageQueue", kMessageQueue },
+ { "ExCommand", kExCommand },
+ { "CObjstateCommand", kObjstateCommand },
+ { "CGameVar", kGameVar },
+ { "CMctlCompound", kMctlCompound },
+ { "CMovGraph", kMovGraph },
+ { "CMovGraphLink", kMovGraphLink },
+ { "CMovGraphNode", kMovGraphNode },
+ { "CReactParallel", kReactParallel },
+ { "CReactPolygonal", kReactPolygonal },
+ { 0, 0 }
+};
+
+static const char *lookupObjectId(int id) {
+ for (int i = 0; classMap[i].name; i++) {
+ if (classMap[i].id == id)
+ return classMap[i].name;
+ }
+
+ return "";
+}
+
+static CObject *createObject(int objectId) {
+ switch (objectId) {
+ case kNullObject:
+ return 0;
+ case kInteraction:
+ return new Interaction();
+ case kMessageQueue:
+ return new MessageQueue();
+ case kExCommand:
+ return new ExCommand();
+ case kObjstateCommand:
+ return new ObjstateCommand();
+ case kGameVar:
+ return new GameVar();
+ case kMctlCompound:
+ return new MctlCompound();
+ case kMovGraph:
+ return new MovGraph();
+ case kMovGraphLink:
+ return new MovGraphLink();
+ case kMovGraphNode:
+ return new MovGraphNode();
+ case kReactParallel:
+ return new ReactParallel();
+ case kReactPolygonal:
+ return new ReactPolygonal();
+ default:
+ error("Unknown objectId: %d", objectId);
+ }
+
+ return 0;
+}
+
+MfcArchive::MfcArchive(Common::SeekableReadStream *stream) {
+ for (int i = 0; classMap[i].name; i++) {
+ _classMap[classMap[i].name] = classMap[i].id;
+ }
+
+ _lastIndex = 1;
+ _level = 0;
+
+ _stream = stream;
+
+ _objectMap.push_back(0);
+ _objectIdMap.push_back(kNullObject);
+}
+
+CObject *MfcArchive::readClass() {
+ bool isCopyReturned;
+ CObject *res = parseClass(&isCopyReturned);
+
+ if (res && !isCopyReturned)
+ res->load(*this);
+
+ return res;
+}
+
+CObject *MfcArchive::parseClass(bool *isCopyReturned) {
+ char *name;
+ int objectId = 0;
+ CObject *res = 0;
+
+ uint obTag = readUint16LE();
+
+ debug(7, "parseClass::obTag = %d (%04x) at 0x%08x", obTag, obTag, pos() - 2);
+
+ if (obTag == 0xffff) {
+ int schema = readUint16LE();
+
+ debug(7, "parseClass::schema = %d", schema);
+
+ name = readPascalString(true);
+ debug(7, "parseClass::class <%s>", name);
+
+ if (!_classMap.contains(name)) {
+ error("Unknown class in MfcArchive: <%s>", name);
+ }
+
+ objectId = _classMap[name];
+
+ debug(7, "tag: %d 0x%x (%x)", _objectMap.size() - 1, _objectMap.size() - 1, objectId);
+
+ res = createObject(objectId);
+ _objectMap.push_back(res);
+ _objectIdMap.push_back(objectId);
+
+ _objectMap.push_back(res); // Basically a hack, but behavior is all correct
+ _objectIdMap.push_back(objectId);
+
+ *isCopyReturned = false;
+ } else if ((obTag & 0x8000) == 0) {
+ if (_objectMap.size() < obTag) {
+ error("Object index too big: %d at 0x%08x", obTag, pos() - 2);
+ }
+ debug(7, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag]));
+
+ res = _objectMap[obTag];
+
+ *isCopyReturned = true;
+ } else {
+
+ obTag &= ~0x8000;
+
+ if (_objectMap.size() < obTag) {
+ error("Object index too big: %d at 0x%08x", obTag, pos() - 2);
+ }
+
+ debug(7, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag]));
+
+ objectId = _objectIdMap[obTag];
+
+ res = createObject(objectId);
+ _objectMap.push_back(res);
+ _objectIdMap.push_back(objectId);
+
+ *isCopyReturned = false;
+ }
+
+ return res;
+}
+
+char *genFileName(int superId, int sceneId, const char *ext) {
+ char *s = (char *)calloc(256, 1);
+
+ if (superId) {
+ snprintf(s, 255, "%04d%04d.%s", superId, sceneId, ext);
+ } else {
+ snprintf(s, 255, "%04d.%s", sceneId, ext);
+ }
+
+ debug(7, "genFileName: %s", s);
+
+ return s;
+}
+
+// Translates cp-1251..utf-8
+byte *transCyrillic(byte *s) {
+ static byte tmp[1024];
+
+ static int trans[] = { 0xa8, 0xd081, 0xb8, 0xd191, 0xc0, 0xd090,
+ 0xc1, 0xd091, 0xc2, 0xd092, 0xc3, 0xd093, 0xc4, 0xd094,
+ 0xc5, 0xd095, 0xc6, 0xd096, 0xc7, 0xd097, 0xc8, 0xd098,
+ 0xc9, 0xd099, 0xca, 0xd09a, 0xcb, 0xd09b, 0xcc, 0xd09c,
+ 0xcd, 0xd09d, 0xce, 0xd09e, 0xcf, 0xd09f, 0xd0, 0xd0a0,
+ 0xd1, 0xd0a1, 0xd2, 0xd0a2, 0xd3, 0xd0a3, 0xd4, 0xd0a4,
+ 0xd5, 0xd0a5, 0xd6, 0xd0a6, 0xd7, 0xd0a7, 0xd8, 0xd0a8,
+ 0xd9, 0xd0a9, 0xda, 0xd0aa, 0xdb, 0xd0ab, 0xdc, 0xd0ac,
+ 0xdd, 0xd0ad, 0xde, 0xd0ae, 0xdf, 0xd0af, 0xe0, 0xd0b0,
+ 0xe1, 0xd0b1, 0xe2, 0xd0b2, 0xe3, 0xd0b3, 0xe4, 0xd0b4,
+ 0xe5, 0xd0b5, 0xe6, 0xd0b6, 0xe7, 0xd0b7, 0xe8, 0xd0b8,
+ 0xe9, 0xd0b9, 0xea, 0xd0ba, 0xeb, 0xd0bb, 0xec, 0xd0bc,
+ 0xed, 0xd0bd, 0xee, 0xd0be, 0xef, 0xd0bf, 0xf0, 0xd180,
+ 0xf1, 0xd181, 0xf2, 0xd182, 0xf3, 0xd183, 0xf4, 0xd184,
+ 0xf5, 0xd185, 0xf6, 0xd186, 0xf7, 0xd187, 0xf8, 0xd188,
+ 0xf9, 0xd189, 0xfa, 0xd18a, 0xfb, 0xd18b, 0xfc, 0xd18c,
+ 0xfd, 0xd18d, 0xfe, 0xd18e, 0xff, 0xd18f };
+
+ int i = 0;
+
+ for (byte *p = s; *p; p++) {
+ if (*p < 128) {
+ tmp[i++] = *p;
+ } else {
+ int j;
+ for (j = 0; trans[j]; j += 2) {
+ if (trans[j] == *p) {
+ tmp[i++] = (trans[j + 1] >> 8) & 0xff;
+ tmp[i++] = trans[j + 1] & 0xff;
+ break;
+ }
+ }
+
+ assert(trans[j]);
+ }
+ }
+
+ tmp[i] = 0;
+
+ return tmp;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
new file mode 100644
index 0000000000..64f56ced0a
--- /dev/null
+++ b/engines/fullpipe/utils.h
@@ -0,0 +1,155 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_UTILS_H
+#define FULLPIPE_UTILS_H
+
+#include "common/hash-str.h"
+#include "common/array.h"
+#include "common/file.h"
+
+namespace Fullpipe {
+
+class CObject;
+class NGIArchive;
+
+typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ClassMap;
+
+class MfcArchive : public Common::SeekableReadStream {
+ ClassMap _classMap;
+ Common::Array<CObject *> _objectMap;
+ Common::Array<int> _objectIdMap;
+
+ int _lastIndex;
+ int _level;
+
+ Common::SeekableReadStream *_stream;
+
+ public:
+ MfcArchive(Common::SeekableReadStream *file);
+
+ char *readPascalString(bool twoByte = false);
+ int readCount();
+ double readDouble();
+ CObject *parseClass(bool *isCopyReturned);
+ CObject *readClass();
+
+ void incLevel() { _level++; }
+ void decLevel() { _level--; }
+ int getLevel() { return _level; }
+
+ virtual bool eos() const { return _stream->eos(); }
+ virtual uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
+ virtual int32 pos() const { return _stream->pos(); }
+ virtual int32 size() const { return _stream->size(); }
+ virtual bool seek(int32 offset, int whence = SEEK_SET) { return _stream->seek(offset, whence); }
+};
+
+enum ObjType {
+ kObjTypeDefault,
+ kObjTypeMovGraph,
+ kObjTypeMovGraphLink,
+ kObjTypeMovGraphNode,
+ kObjTypeMctlCompound,
+ kObjTypeObjstateCommand,
+ kObjTypePictureObject,
+ kObjTypeStaticANIObject
+};
+
+class CObject {
+public:
+ ObjType _objtype;
+
+ CObject() : _objtype(kObjTypeDefault) {}
+ virtual bool load(MfcArchive &in) { return true; }
+ virtual ~CObject() {}
+
+ bool loadFile(const char *fname);
+};
+
+class ObList : public Common::List<CObject *>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class MemoryObject : CObject {
+ friend class Picture;
+ friend class Scene;
+
+ protected:
+ char *_memfilename;
+ int _mfield_8;
+ int _mfield_C;
+ int _mfield_10;
+ char _mfield_14;
+ byte *_data;
+ int _dataSize;
+ int _mflags;
+ NGIArchive *_libHandle;
+
+ public:
+ MemoryObject();
+ virtual ~MemoryObject();
+
+ virtual bool load(MfcArchive &file);
+ void loadFile(char *filename);
+ void load() { loadFile(_memfilename); }
+ byte *getData();
+ byte *loadData();
+
+ bool testFlags();
+
+ void freeData();
+};
+
+class MemoryObject2 : public MemoryObject {
+ friend class Picture;
+
+ protected:
+ byte **_rows;
+
+ public:
+ MemoryObject2();
+ virtual ~MemoryObject2();
+ virtual bool load(MfcArchive &file);
+
+ void copyData(byte *src, int dataSize);
+};
+
+class ObArray : public Common::Array<CObject>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class DWordArray : public Common::Array<int32>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+typedef Common::Array<void *> PtrList;
+
+char *genFileName(int superId, int sceneId, const char *ext);
+byte *transCyrillic(byte *s);
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_UTILS_H */
diff --git a/engines/gob/POTFILES b/engines/gob/POTFILES
new file mode 100644
index 0000000000..9a512469dd
--- /dev/null
+++ b/engines/gob/POTFILES
@@ -0,0 +1,3 @@
+engines/gob/inter_playtoons.cpp
+engines/gob/inter_v2.cpp
+engines/gob/inter_v5.cpp
diff --git a/engines/gob/configure.engine b/engines/gob/configure.engine
new file mode 100644
index 0000000000..8e012f5815
--- /dev/null
+++ b/engines/gob/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine gob "Gobli*ns" yes
diff --git a/engines/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 6b65eb6ab9..870b0f15b3 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -45,7 +45,7 @@ static void plotPixel(int x, int y, int color, void *data) {
Pixel::Pixel(byte *vidMem, uint8 bpp, byte *min, byte *max) :
_vidMem(vidMem), _bpp(bpp), _min(min), _max(max) {
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
assert(_vidMem >= _min);
assert(_vidMem < _max);
}
@@ -91,6 +91,8 @@ uint32 Pixel::get() const {
return *((byte *) _vidMem);
if (_bpp == 2)
return *((uint16 *) _vidMem);
+ if (_bpp == 4)
+ return *((uint32 *) _vidMem);
return 0;
}
@@ -103,6 +105,8 @@ void Pixel::set(uint32 p) {
*((byte *) _vidMem) = (byte) p;
if (_bpp == 2)
*((uint16 *) _vidMem) = (uint16) p;
+ if (_bpp == 4)
+ *((uint32 *) _vidMem) = (uint32) p;
}
bool Pixel::isValid() const {
@@ -113,7 +117,7 @@ bool Pixel::isValid() const {
ConstPixel::ConstPixel(const byte *vidMem, uint8 bpp, const byte *min, const byte *max) :
_vidMem(vidMem), _bpp(bpp), _min(min), _max(max) {
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
assert(_vidMem >= _min);
assert(_vidMem < _max);
}
@@ -159,6 +163,8 @@ uint32 ConstPixel::get() const {
return *((const byte *) _vidMem);
if (_bpp == 2)
return *((const uint16 *) _vidMem);
+ if (_bpp == 4)
+ return *((const uint32 *) _vidMem);
return 0;
}
@@ -172,7 +178,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) :
_width(width), _height(height), _bpp(bpp), _vidMem(vidMem) {
assert((_width > 0) && (_height > 0));
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
if (!_vidMem) {
_vidMem = new byte[_bpp * _width * _height];
@@ -187,7 +193,7 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) :
_width(width), _height(height), _bpp(bpp), _vidMem(0) {
assert((_width > 0) && (_height > 0));
- assert((_bpp == 1) || (_bpp == 2));
+ assert((_bpp == 1) || (_bpp == 2) || (_bpp == 4));
_vidMem = new byte[_bpp * _width * _height];
_ownVidMem = true;
@@ -504,7 +510,7 @@ void Surface::fillRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uin
return;
}
- assert(_bpp == 2);
+ assert((_bpp == 2) || (_bpp == 4));
// Otherwise, we have to fill by pixel
@@ -815,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/POTFILES b/engines/groovie/POTFILES
new file mode 100644
index 0000000000..0bf4528a7d
--- /dev/null
+++ b/engines/groovie/POTFILES
@@ -0,0 +1,2 @@
+engines/groovie/detection.cpp
+engines/groovie/script.cpp
diff --git a/engines/groovie/configure.engine b/engines/groovie/configure.engine
new file mode 100644
index 0000000000..84e95a70df
--- /dev/null
+++ b/engines/groovie/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine groovie "Groovie" yes "groovie2" "7th Guest"
+add_engine groovie2 "Groovie 2 games" no "" "" "jpeg"
diff --git a/engines/groovie/font.cpp b/engines/groovie/font.cpp
index d29c22dd02..a55d8fad95 100644
--- a/engines/groovie/font.cpp
+++ b/engines/groovie/font.cpp
@@ -112,7 +112,7 @@ bool T7GFont::load(Common::SeekableReadStream &stream) {
return true;
}
-void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const {
+void T7GFont::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
// We ignore the color, as the font is already colored
const Glyph *glyph = getGlyph(chr);
const byte *src = glyph->pixels;
@@ -125,7 +125,7 @@ void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 co
}
}
-const T7GFont::Glyph *T7GFont::getGlyph(byte chr) const {
+const T7GFont::Glyph *T7GFont::getGlyph(uint32 chr) const {
assert (chr < 128);
byte numGlyph = _mapChar2Glyph[chr];
diff --git a/engines/groovie/font.h b/engines/groovie/font.h
index 20aaa4cf23..49cf4b7b06 100644
--- a/engines/groovie/font.h
+++ b/engines/groovie/font.h
@@ -37,8 +37,8 @@ public:
int getFontHeight() const { return _maxHeight; }
int getMaxCharWidth() const { return _maxWidth; }
- int getCharWidth(byte chr) const { return getGlyph(chr)->width; }
- void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const;
+ int getCharWidth(uint32 chr) const { return getGlyph(chr)->width; }
+ void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
int _maxHeight, _maxWidth;
@@ -55,7 +55,7 @@ private:
byte _mapChar2Glyph[128];
Glyph *_glyphs;
- const Glyph *getGlyph(byte chr) const;
+ const Glyph *getGlyph(uint32 chr) const;
};
} // End of Groovie namespace
diff --git a/engines/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..e1ca7fb945 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -28,6 +28,7 @@
#include "groovie/groovie.h"
#include "common/debug.h"
+#include "common/substream.h"
#include "common/textconsole.h"
#include "graphics/palette.h"
@@ -160,7 +161,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 +292,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;
@@ -435,19 +436,20 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
warning("Groovie::ROQ: JPEG frame (unfinished)");
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);
+ jpg->setOutputColorSpace(Graphics::JPEGDecoder::kColorSpaceYUV);
- byte *ptr = (byte *)_currBuf->getBasePtr(0, 0);
- for (int i = 0; i < _currBuf->w * _currBuf->h; i++) {
- *ptr++ = *y++;
- *ptr++ = *u++;
- *ptr++ = *v++;
- }
+ uint32 startPos = _file->pos();
+ Common::SeekableSubReadStream subStream(_file, startPos, startPos + blockHeader.size, DisposeAfterUse::NO);
+ jpg->loadStream(subStream);
+
+ const Graphics::Surface *srcSurf = jpg->getSurface();
+ const byte *src = (const byte *)srcSurf->getPixels();
+ byte *ptr = (byte *)_currBuf->getPixels();
+ memcpy(ptr, src, _currBuf->w * _currBuf->h * srcSurf->format.bytesPerPixel);
delete jpg;
+
+ _file->seek(startPos + blockHeader.size);
return true;
}
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..f9e3ecafcd 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;
}
/**
@@ -349,15 +349,21 @@ void ComputerManager::loadMenu() {
char *ptr;
if (_vm->_fileIO->fileExists("COMPUTAN.TXT")) {
ptr = (char *)_vm->_fileIO->loadFile("COMPUTAN.TXT");
- } else if (_vm->_globals->_language == LANG_FR) {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
- strcpy(ptr, _frenchText);
- } else if (_vm->_globals->_language == LANG_SP) {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
- strcpy(ptr, _spanishText);
} else {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
- strcpy(ptr, _englishText);
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
+ strcpy(ptr, _frenchText);
+ break;
+ case LANG_SP:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
+ strcpy(ptr, _spanishText);
+ break;
+ default:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
+ strcpy(ptr, _englishText);
+ break;
+ }
}
char *tmpPtr = ptr;
@@ -479,12 +485,17 @@ void ComputerManager::readText(int idx) {
_vm->_events->_escKeyFl = false;
Common::String filename;
- if (_vm->_globals->_language == LANG_EN)
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
filename = "THOPKAN.TXT";
- else if (_vm->_globals->_language == LANG_FR)
+ break;
+ case LANG_FR:
filename = "THOPK.TXT";
- else if (_vm->_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
filename = "THOPKES.TXT";
+ break;
+ }
byte *ptr = _vm->_fileIO->loadFile(filename);
uint16 fileSize = _vm->_fileIO->fileSize(filename);
@@ -579,26 +590,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 +796,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 +840,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 +881,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 +903,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 +920,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 +1002,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 +1023,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/configure.engine b/engines/hopkins/configure.engine
new file mode 100644
index 0000000000..c38ecd4cd2
--- /dev/null
+++ b/engines/hopkins/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine hopkins "Hopkins FBI" yes "" "" "16bit"
diff --git a/engines/hopkins/detection.cpp b/engines/hopkins/detection.cpp
index a42597415b..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[] = {
@@ -67,6 +71,7 @@ static const PlainGameDescriptor hopkinsGames[] = {
const static char *directoryGlobs[] = {
"voice",
+ "link",
0
};
diff --git a/engines/hopkins/detection_tables.h b/engines/hopkins/detection_tables.h
index 3e04375fe9..c3ff563f6f 100644
--- a/engines/hopkins/detection_tables.h
+++ b/engines/hopkins/detection_tables.h
@@ -24,12 +24,11 @@ namespace Hopkins {
static const HopkinsGameDescription gameDescriptions[] = {
{
- // Hopkins FBI Linux Demo 1.00
+ // Hopkins FBI Linux Demo UK 1.00 and 1.02
{
"hopkins",
- "Linux Demo v1.00",
+ "Linux Demo",
{
- {"Hopkins-PDemo.bin", 0, "88b4d6e14b9b1407083cb3d1213c0fa7", 272027},
{"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 16060544},
AD_LISTEND
},
@@ -39,32 +38,14 @@ static const HopkinsGameDescription gameDescriptions[] = {
GUIO1(GUIO_NONE)
},
},
-
- {
- // Hopkins FBI Linux Demo 1.02
- {
- "hopkins",
- "Linux Demo v1.02",
- {
- {"Hopkins-PDemo.bin", 0, "f82f4e698f3a189419351be0de2b2f8e", 273760},
- {"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 16060544},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
-
{
// Hopkins FBI OS/2, provided by Strangerke
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "63d45f882278e5a9fa1027066223e5d9", 292864},
{"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
+ {"CREAN.TXT", 0, "e13aa69d9e043f066776e1d0ef98fdf5", 1871},
AD_LISTEND
},
Common::EN_ANY,
@@ -74,93 +55,41 @@ static const HopkinsGameDescription gameDescriptions[] = {
},
},
{
- // Hopkins FBI Win95 Demo, provided by Strangerke
- // CHECKME: No voice! a second file is required though... Also, it has multi-language support
- {
- "hopkins",
- "Win95 Demo",
- {
- {"Hopkins.exe", 0, "0c9ebfe371f4dcf84a49f333f04839a0", 376897},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95 Polish Demo, provided by Strangerke
- {
- "hopkins",
- "Win95 Demo",
- {
- {"Hopkins.exe", 0, "7595c0b9374739b212ee9f8f412ac716", 307200},
- {"RES_VAN.RES", 0, "8262cfba261c200af4451902689dffe0", 12233202},
- AD_LISTEND
- },
- Common::PL_POL,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95 Spanish
- {
- "hopkins",
- 0,
- {
- {"Hopkins.exe", 0, "31c837378bb2e0b2573befea44956d3f", 421386},
- {"RES_VES.RES", 0, "77ee08896466ae88cc1af3bf1a0bf78c", 32882302},
- AD_LISTEND
- },
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95, provided by Strangerke
+ // Hopkins FBI BeOS, provided by Strangerke & Eriktorbjorn
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "277a5c144bf9ec7d8450ae37afb85090", 419281},
- {"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
+ {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformWindows,
+ Common::kPlatformBeOS,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
},
{
- // Hopkins FBI Win95, provided by alexbevi
- // Dec 15 1998 hopkins.exe
+ // Hopkins FBI Win95 Spanish
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "a587762dd50d5933e1c89f9975180764", 378694},
- {"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
+ {"RES_VES.RES", 0, "77ee08896466ae88cc1af3bf1a0bf78c", 32882302},
AD_LISTEND
},
- Common::EN_ANY,
+ Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
},
{
- // Hopkins FBI Win95 EN, provided by greencis in bug #3612406
+ // Hopkins FBI Win95 UK, provided by Strangerke, alexbevi, greencis
{
"hopkins",
0,
{
- {"hopkins.exe", 0, "020690049fa1dfcd63a18fdafb139a0e", 421386},
{"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
AD_LISTEND
},
@@ -176,7 +105,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"hopkins.exe", 0, "3043fef0bd3bfeba8252647cd090ce09", 419281},
{"res_van.res", 0, "bf17c710e184a25a6c8e9d1d9503c38e", 32197685},
AD_LISTEND
},
@@ -192,7 +120,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"Hopkins.bin", 0, "71611380cb31744bf909b8319a65e6e6", 275844},
{"RES_VFR.RES", 0, "0490d4d1aa71075ebf71cc79e5dc7894", 39817945},
AD_LISTEND
},
@@ -208,7 +135,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"Hopkins.bin", 0, "71611380cb31744bf909b8319a65e6e6", 275844},
{"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 38832455},
AD_LISTEND
},
@@ -218,61 +144,53 @@ static const HopkinsGameDescription gameDescriptions[] = {
GUIO1(GUIO_NONE)
},
},
-
{
- // Hopkins FBI BeOS, provided by Strangerke
+ // Hopkins FBI Win95, French, provided by SylvainTV
{
"hopkins",
0,
{
- {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
- {"Hopkins_ FBI", 0, "8940ce2e618c42691b66aad5d6c223b0", 757936},
+ {"RES_VFR.RES", 0, "b8a3849063c9eeefe80e82cfce1ad3cd", 39269361},
AD_LISTEND
},
- Common::EN_ANY,
- Common::kPlatformBeOS,
+ Common::FR_FRA,
+ Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
- },
+ },
{
- // Hopkins FBI BeOS, uninstalled, provided by eriktorbjorn
+ // Hopkins FBI Win95 Demo, provided by Strangerke
+ // CHECKME: No voice! a second file is required though... Also, it has multi-language support
{
"hopkins",
- 0,
+ "Win95 Demo",
{
- {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
- {"Hopkins.pkg", 0, "72f97806dd3d5fc0c0eb24196f180618", 285017},
+ {"Hopkins.exe", 0, "0c9ebfe371f4dcf84a49f333f04839a0", 376897},
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformBeOS,
- ADGF_NO_FLAGS,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
GUIO1(GUIO_NONE)
},
-
},
-
{
- // Hopkins FBI Win32, French uninstalled, provided by SylvainTV
+ // Hopkins FBI Win95 Polish Demo, provided by Strangerke
{
"hopkins",
- 0,
+ "Win95 Demo",
{
- {"Hopkins.exe", 0, "277a5c144bf9ec7d8450ae37afb85090", 419281},
- {"RES_VFR.RES", 0, "b8a3849063c9eeefe80e82cfce1ad3cd", 39269361},
+ {"RES_VAN.RES", 0, "8262cfba261c200af4451902689dffe0", 12233202},
AD_LISTEND
},
- Common::FR_FRA,
+ Common::PL_POL,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_DEMO,
GUIO1(GUIO_NONE)
},
-
},
-
-
{ AD_TABLE_END_MARKER }
};
diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp
index 6cdfbf47d1..8c944167ae 100644
--- a/engines/hopkins/dialogs.cpp
+++ b/engines/hopkins/dialogs.cpp
@@ -84,12 +84,17 @@ void DialogsManager::showOptionsDialog() {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "OPTION.SPR";
else {
- if (_vm->_globals->_language == LANG_FR)
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
filename = "OPTIFR.SPR";
- else if (_vm->_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
filename = "OPTIAN.SPR";
- else if (_vm->_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
filename = "OPTIES.SPR";
+ break;
+ }
}
_vm->_globals->_optionDialogSpr = _vm->_fileIO->loadFile(filename);
@@ -505,7 +510,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 +696,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/events.cpp b/engines/hopkins/events.cpp
index 51c66c4f92..d0c1dcea4d 100644
--- a/engines/hopkins/events.cpp
+++ b/engines/hopkins/events.cpp
@@ -271,7 +271,7 @@ void EventsManager::pollEvents() {
_mouseButton = 0;
return;
default:
- break;
+ break;
}
}
diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp
index 28f22ed99e..cd66a84b73 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:
@@ -148,7 +148,7 @@ void Globals::setConfig() {
_language = LANG_SP;
break;
default:
- warning("Unknown language in internal language mapping");
+ error("Hopkins - SetConfig(): Unknown language in internal language mapping");
break;
}
// End of CHECKME
diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp
index ebc5cfa8da..05b8296b86 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);
@@ -1361,7 +1359,7 @@ void GraphicsManager::drawCompressedSprite(byte *surface, const byte *srcData, i
_posYClipped = 0;
_clipX1 = 0;
_clipY1 = 0;
- if ((xp300 <= _minX) || (yp300 <= _minY) || (xp300 >= _maxX + 300) || (yp300 >= _maxY + 300))
+ if ((xp300 <= _minX) || (yp300 <= _minY) || (xp300 >= _maxX + 300) || (yp300 >= _maxY + 300))
return;
// Clipped values are greater or equal to zero, thanks to the previous test
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 2997320ba4..adf7580e6b 100644
--- a/engines/hopkins/hopkins.cpp
+++ b/engines/hopkins/hopkins.cpp
@@ -35,12 +35,9 @@
namespace Hopkins {
-HopkinsEngine *g_vm;
-
HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _randomSource("Hopkins") {
DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level");
- g_vm = this;
_animMan = new AnimationManager(this);
_computer = new ComputerManager(this);
_dialog = new DialogsManager(this);
@@ -95,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();
}
@@ -114,8 +111,6 @@ Common::Error HopkinsEngine::saveGameState(int slot, const Common::String &desc)
}
Common::Error HopkinsEngine::run() {
- _saveLoad->initSaves();
-
_globals->setConfig();
_fileIO->initCensorship();
initializeSystem();
@@ -156,36 +151,31 @@ bool HopkinsEngine::runWin95Demo() {
_events->_rateCounter = 0;
_globals->_eventMode = EVENTMODE_IGNORE;
_globals->_speed = 1;
-
- for (int i = 1; i < 50; i++) {
- _graphicsMan->copySurface(_graphicsMan->_backBuffer, 0, 0, 640, 440, _graphicsMan->_frontBuffer, 0, 0);
- _events->refreshScreenAndEvents();
- }
-
+ _events->delay(500);
_globals->_eventMode = EVENTMODE_DEFAULT;
if (_events->_rateCounter > 475)
_globals->_speed = 2;
if (_events->_rateCounter > 700)
_globals->_speed = 3;
- if (_startGameSlot == -1) {
- _graphicsMan->fadeOutLong();
- _globals->_eventMode = EVENTMODE_IGNORE;
- _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
- }
+ if (_startGameSlot == -1)
+ _graphicsMan->fadeOutShort();
+
+ _globals->_eventMode = EVENTMODE_IGNORE;
+ _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
- if (_startGameSlot != -1)
- _saveLoad->loadGame(_startGameSlot);
-
if (getLanguage() != Common::PL_POL)
if (!displayAdultDisclaimer())
return Common::kNoError;
+ if (_startGameSlot != -1)
+ _saveLoad->loadGame(_startGameSlot);
+
for (;;) {
if (_globals->_exitId == 300)
_globals->_exitId = 0;
@@ -206,23 +196,31 @@ bool HopkinsEngine::runWin95Demo() {
switch (_globals->_exitId) {
case 1:
+ // Handles room: Apartment
_linesMan->setMaxLineIdx(40);
_globals->_characterMaxPosY = 435;
_objectsMan->sceneControl2("IM01", "IM01", "ANIM01", "IM01", 2, true);
break;
case 3:
+ // - Displays bank attack when leaving the apartment
+ // - Handles room: bottom of the apartment
if (!_globals->_saveData->_data[svBankAttackAnimPlayedFl]) {
_soundMan->playSound(3);
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -240,7 +238,7 @@ bool HopkinsEngine::runWin95Demo() {
_soundMan->removeSample(2);
_soundMan->removeSample(3);
_soundMan->removeSample(4);
- _graphicsMan->fadeOutLong();
+ _graphicsMan->fadeOutShort();
_globals->_saveData->_data[svBankAttackAnimPlayedFl] = 1;
}
_linesMan->setMaxLineIdx(5);
@@ -249,12 +247,14 @@ bool HopkinsEngine::runWin95Demo() {
break;
case 4:
+ // Handle room: City map
_globals->_disableInventFl = true;
_objectsMan->handleCityMap();
_globals->_disableInventFl = false;
break;
case 5:
+ // Handle room: Outside the bank
_linesMan->setMaxLineIdx(5);
_globals->_characterMaxPosY = 455;
@@ -402,14 +402,27 @@ bool HopkinsEngine::runWin95Demo() {
break;
case 151:
- _soundMan->playSound(28);
- _globals->_eventMode = EVENTMODE_ALT; // CHECKME!
- _graphicsMan->clearScreen();
- _graphicsMan->clearPalette();
- _graphicsMan->loadImage("njour3a");
- _graphicsMan->fadeInLong();
- _events->delay(5000);
- _graphicsMan->fadeOutLong();
+ if (_fileIO->fileExists("JOUR3A.ANM")) {
+ // The Polish demo uses the animation file than the complete versions
+ _soundMan->playSound(16);
+ _globals->_eventMode = EVENTMODE_IGNORE;
+
+ _graphicsMan->clearScreen();
+ _graphicsMan->clearPalette();
+ _graphicsMan->_fadingFl = true;
+ _animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000);
+ } else {
+ // The other demos only display a nag screen
+ _soundMan->playSound(28);
+ _globals->_eventMode = EVENTMODE_ALT; // CHECKME!
+ _graphicsMan->clearScreen();
+ _graphicsMan->clearPalette();
+ _graphicsMan->loadImage("njour3a");
+ _graphicsMan->fadeInLong();
+ _events->delay(5000);
+ _graphicsMan->fadeOutLong();
+ }
+
_globals->_exitId = 300;
_globals->_eventMode = EVENTMODE_DEFAULT;
break;
@@ -457,7 +470,7 @@ bool HopkinsEngine::runLinuxDemo() {
_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
if (_startGameSlot != -1)
@@ -513,12 +526,17 @@ bool HopkinsEngine::runLinuxDemo() {
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -785,14 +803,14 @@ bool HopkinsEngine::runFull() {
if (_startGameSlot == -1) {
if (getPlatform() == Common::kPlatformLinux) {
- _graphicsMan->loadImage("H2");
- _graphicsMan->fadeInLong();
- _events->delay(500);
- _graphicsMan->fadeOutLong();
- _globals->_speed = 2;
- _globals->_eventMode = EVENTMODE_IGNORE;
- _graphicsMan->_fadingFl = true;
- _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200);
+ _graphicsMan->loadImage("H2");
+ _graphicsMan->fadeInLong();
+ _events->delay(500);
+ _graphicsMan->fadeOutLong();
+ _globals->_speed = 2;
+ _globals->_eventMode = EVENTMODE_IGNORE;
+ _graphicsMan->_fadingFl = true;
+ _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200);
} else {
_animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200);
_graphicsMan->fadeOutLong();
@@ -818,7 +836,7 @@ bool HopkinsEngine::runFull() {
_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
@@ -859,12 +877,17 @@ bool HopkinsEngine::runFull() {
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -1125,12 +1148,14 @@ bool HopkinsEngine::runFull() {
break;
case 30:
+ // Shooting
_linesMan->setMaxLineIdx(15);
_globals->_characterMaxPosY = 440;
_objectsMan->sceneControl2("IM30", "IM30", "ANIM30", "IM30", 24, false);
break;
case 31:
+ // Shooting target
_objectsMan->sceneControl("IM31", "IM31", "ANIM31", "IM31", 10, true);
break;
@@ -1145,6 +1170,7 @@ bool HopkinsEngine::runFull() {
break;
case 34:
+ // In the airport, before the flight cut-scene
_objectsMan->sceneControl("IM34", "IM34", "ANIM34", "IM34", 2, false);
break;
@@ -1175,6 +1201,7 @@ bool HopkinsEngine::runFull() {
}
case 50:
+ // Flight cut scene
playPlaneCutscene();
_globals->_exitId = 51;
break;
@@ -1634,8 +1661,8 @@ void HopkinsEngine::playIntro() {
_graphicsMan->setColorPercentage(253, 100, 100, 100);
_graphicsMan->setColorPercentage(251, 100, 100, 100);
_graphicsMan->setColorPercentage(254, 0, 0, 0);
- for (int i = 0; i <= 4; i++)
- _events->refreshScreenAndEvents();
+
+ _events->delay(500);
_globals->_eventMode = EVENTMODE_IGNORE;
_graphicsMan->fadeInLong();
@@ -1896,10 +1923,7 @@ void HopkinsEngine::bombExplosion() {
}
void HopkinsEngine::restoreSystem() {
- // If the game isn't alerady trying to quit, flag that quitting is needed
- if (!shouldQuit())
- quitGame();
-
+ quitGame();
_events->refreshEvents();
}
@@ -2224,6 +2248,8 @@ void HopkinsEngine::playPlaneCutscene() {
if (!_events->_escKeyFl) {
_graphicsMan->_fadingFl = true;
_animMan->playAnim("PARA00A.ANM", "PARA00.ANM", 9, 9, 9);
+ } else {
+ _graphicsMan->fadeOutShort();
}
_events->_escKeyFl = false;
diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h
index 777fd1c335..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);
@@ -183,9 +184,6 @@ public:
virtual void syncSoundSettings();
};
-// Global reference to the HopkinsEngine object
-extern HopkinsEngine *g_vm;
-
} // End of namespace Hopkins
#endif /* HOPKINS_HOPKINS_H */
diff --git a/engines/hopkins/lines.cpp b/engines/hopkins/lines.cpp
index 767b599d68..aa708fdfb2 100644
--- a/engines/hopkins/lines.cpp
+++ b/engines/hopkins/lines.cpp
@@ -975,7 +975,6 @@ int LinesManager::computeRouteIdx(int lineIdx, int dataIdx, int fromX, int fromY
curX = destX;
int lineIdxLeft = -1;
- loopCond = false;
do {
--curX;
if (checkCollisionLine(curX, destY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx)) {
diff --git a/engines/hopkins/menu.cpp b/engines/hopkins/menu.cpp
index 455f4ad8d4..048d1b2cef 100644
--- a/engines/hopkins/menu.cpp
+++ b/engines/hopkins/menu.cpp
@@ -69,23 +69,37 @@ int MenuManager::menu() {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
_vm->_graphicsMan->loadImage("MENU");
- else if (_vm->_globals->_language == LANG_EN)
- _vm->_graphicsMan->loadImage("MENUAN");
- else if (_vm->_globals->_language == LANG_FR)
- _vm->_graphicsMan->loadImage("MENUFR");
- else if (_vm->_globals->_language == LANG_SP)
- _vm->_graphicsMan->loadImage("MENUES");
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
+ _vm->_graphicsMan->loadImage("MENUAN");
+ break;
+ case LANG_FR:
+ _vm->_graphicsMan->loadImage("MENUFR");
+ break;
+ case LANG_SP:
+ _vm->_graphicsMan->loadImage("MENUES");
+ break;
+ }
+ }
_vm->_graphicsMan->fadeInLong();
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
spriteData = _vm->_objectsMan->loadSprite("MENU.SPR");
- else if (_vm->_globals->_language == LANG_EN)
- spriteData = _vm->_objectsMan->loadSprite("MENUAN.SPR");
- else if (_vm->_globals->_language == LANG_FR)
- spriteData = _vm->_objectsMan->loadSprite("MENUFR.SPR");
- else if (_vm->_globals->_language == LANG_SP)
- spriteData = _vm->_objectsMan->loadSprite("MENUES.SPR");
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
+ spriteData = _vm->_objectsMan->loadSprite("MENUAN.SPR");
+ break;
+ case LANG_FR:
+ spriteData = _vm->_objectsMan->loadSprite("MENUFR.SPR");
+ break;
+ case LANG_SP:
+ spriteData = _vm->_objectsMan->loadSprite("MENUES.SPR");
+ break;
+ }
+ }
_vm->_events->mouseOn();
_vm->_events->changeMouseCursor(0);
diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp
index 45b4885c90..b0dea7e6d1 100644
--- a/engines/hopkins/saveload.cpp
+++ b/engines/hopkins/saveload.cpp
@@ -43,39 +43,38 @@ SaveLoadManager::SaveLoadManager(HopkinsEngine *vm) {
}
bool SaveLoadManager::save(const Common::String &file, const void *buf, size_t n) {
- Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(file);
+ Common::OutSaveFile *savefile = g_system->getSavefileManager()->openForSaving(file);
- if (f) {
- size_t bytesWritten = f->write(buf, n);
- f->finalize();
- delete f;
+ if (savefile) {
+ size_t bytesWritten = savefile->write(buf, n);
+ savefile->finalize();
+ delete savefile;
return bytesWritten == n;
} else
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 *f = g_system->getSavefileManager()->openForLoading(file);
- if (f == NULL)
- error("Error openinig file - %s", file.c_str());
+ Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(file);
+ if (savefile == NULL)
+ error("Error opening file - %s", file.c_str());
- int32 filesize = f->size();
- f->read(buf, filesize);
- delete f;
+ int32 filesize = savefile->size();
+ savefile->read(buf, filesize);
+ delete savefile;
}
bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) {
@@ -215,13 +214,13 @@ Common::Error SaveLoadManager::loadGame(int slot) {
bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) {
// Try and open the save file for reading
- Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
- g_vm->generateSaveName(slot));
- if (!saveFile)
+ Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(
+ _vm->generateSaveName(slot));
+ if (!savefile)
return false;
- bool result = readSavegameHeader(saveFile, header);
- delete saveFile;
+ bool result = readSavegameHeader(savefile, header);
+ delete savefile;
return result;
}
@@ -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 221a445fd2..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,14 +56,14 @@ 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);
static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header);
void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header);
- static bool readSavegameHeader(int slot, hopkinsSavegameHeader &header);
+ bool readSavegameHeader(int slot, hopkinsSavegameHeader &header);
Common::Error saveGame(int slot, const Common::String &saveName);
Common::Error loadGame(int slot);
diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp
index c39273203d..09b0641a12 100644
--- a/engines/hopkins/script.cpp
+++ b/engines/hopkins/script.cpp
@@ -148,12 +148,18 @@ int ScriptManager::handleOpcode(const byte *dataP) {
_vm->_soundMan->mixVoice(635, 4, displayedTxtFl);
} else {
int textPosX = READ_LE_INT16(dataP + 9);
- if (_vm->_globals->_language == LANG_FR && !_vm->_soundMan->_textOffFl)
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJET1.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
- else if (_vm->_globals->_language == LANG_EN && !_vm->_soundMan->_textOffFl)
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETAN.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
- else if (_vm->_globals->_language == LANG_SP && !_vm->_soundMan->_textOffFl) {
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETES.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ if (!_vm->_soundMan->_textOffFl) {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJET1.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ case LANG_EN:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETAN.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ case LANG_SP:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETES.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ }
}
bool displayedTxtFl = false;
@@ -536,6 +542,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
break;
case 12:
+ // Bank - negotiations between Hopkins and one of the killers
_vm->_fontMan->hideText(9);
_vm->_events->refreshScreenAndEvents();
_vm->_events->refreshScreenAndEvents();
@@ -543,6 +550,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
break;
case 13:
+ // Bank - after negotiations, Hopkins enters the bank
_vm->_events->_mouseButton = _vm->_events->_curMouseButton;
_vm->_globals->_disableInventFl = true;
_vm->_graphicsMan->fadeOutLong();
@@ -553,9 +561,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
_vm->_graphicsMan->endDisplayBob();
_vm->_objectsMan->clearScreen();
- if ((_vm->getPlatform() == Common::kPlatformWindows) && _vm->getIsDemo()) {
- _vm->_graphicsMan->fadeOutLong();
- } else {
+ if ((_vm->getPlatform() != Common::kPlatformWindows) || !_vm->getIsDemo()) {
_vm->_soundMan->playSoundFile("SOUND17.WAV");
_vm->_graphicsMan->_fadingFl = true;
_vm->_animMan->playSequence2("HELICO.SEQ", 10, 4, 10);
@@ -615,10 +621,6 @@ int ScriptManager::handleOpcode(const byte *dataP) {
_vm->_graphicsMan->_fadingFl = true;
_vm->_animMan->playSequence2("ASSOM.SEQ", 10, 4, 500);
_vm->_soundMan->_specialSoundNum = 0;
-
- if ((_vm->getPlatform() == Common::kPlatformWindows) && _vm->getIsDemo())
- _vm->_graphicsMan->fadeOutLong();
-
_vm->_globals->_disableInventFl = false;
_vm->_objectsMan->_helicopterFl = true;
break;
@@ -1221,6 +1223,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
break;
case 88:
+ // Shooting target - Shooting at target
if (_vm->_globals->_saveData->_data[svField183] == 1) {
_vm->_objectsMan->setBobAnimDataIdx(1, 0);
_vm->_objectsMan->setBobAnimDataIdx(2, 0);
@@ -1298,6 +1301,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
break;
case 90:
+ // Shooting target - Using the level
_vm->_soundMan->playSoundFile("SOUND52.WAV");
if (!_vm->_globals->_saveData->_data[svField186]) {
_vm->_animMan->playSequence("CIB5A.SEQ", 1, 12, 1, false, false);
@@ -1984,6 +1988,7 @@ int ScriptManager::handleOpcode(const byte *dataP) {
break;
case 216:
+ // Discuss with pilot just before Flight cutscene
_vm->_globals->_introSpeechOffFl = true;
_vm->_talkMan->startAnimatedCharacterDialogue("aviat1.pe2");
_vm->_globals->_introSpeechOffFl = false;
diff --git a/engines/hopkins/sound.cpp b/engines/hopkins/sound.cpp
index bf816c08a4..92c5f51462 100644
--- a/engines/hopkins/sound.cpp
+++ b/engines/hopkins/sound.cpp
@@ -520,12 +520,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
@@ -535,12 +542,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
@@ -550,12 +564,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
diff --git a/engines/hopkins/talk.cpp b/engines/hopkins/talk.cpp
index 736ec9865c..d218dd27b5 100644
--- a/engines/hopkins/talk.cpp
+++ b/engines/hopkins/talk.cpp
@@ -68,12 +68,17 @@ void TalkManager::startAnimatedCharacterDialogue(const Common::String &filename)
getStringFromBuffer(40, spriteFilename, (const char *)_characterBuffer);
getStringFromBuffer(0, _questionsFilename, (const char *)_characterBuffer);
getStringFromBuffer(20, _answersFilename, (const char *)_characterBuffer);
- if (_vm->_globals->_language == LANG_FR) {
+
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
_answersFilename = _questionsFilename = "RUE.TXT";
- } else if (_vm->_globals->_language == LANG_EN) {
+ break;
+ case LANG_EN:
_answersFilename = _questionsFilename = "RUEAN.TXT";
- } else if (_vm->_globals->_language == LANG_SP) {
+ break;
+ case LANG_SP:
_answersFilename = _questionsFilename = "RUEES.TXT";
+ break;
}
_dialogueMesgId1 = READ_LE_INT16((uint16 *)_characterBuffer + 40);
_paletteBufferIdx = 20 * READ_LE_INT16((uint16 *)_characterBuffer + 42) + 110;
@@ -261,7 +266,7 @@ int TalkManager::dialogQuestion(bool animatedFl) {
int retVal = -1;
bool loopCond = false;
- do {
+ do {
int mousePosY = _vm->_events->getMouseY();
if (sentence1PosY < mousePosY && mousePosY < (sentence2PosY - 1)) {
_vm->_fontMan->setOptimalColor(6, 7, 8, 5);
diff --git a/engines/hugo/configure.engine b/engines/hugo/configure.engine
new file mode 100644
index 0000000000..9ab5c54e1e
--- /dev/null
+++ b/engines/hugo/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine hugo "Hugo Trilogy" yes
diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp
index 0f07d52aee..23e04dc479 100644
--- a/engines/hugo/dialogs.cpp
+++ b/engines/hugo/dialogs.cpp
@@ -34,8 +34,10 @@
namespace Hugo {
-TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _arrayBmp(0), _arraySize(0),
- _vm(vm) {
+TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _vm(vm) {
+ _arrayBmp = nullptr;
+ _arraySize = 0;
+
init();
}
@@ -140,12 +142,10 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
_arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat());
_arrayBmp[i * 2 + 1] = new Graphics::Surface();
_arrayBmp[i * 2 + 1]->create(_arrayBmp[i * 2]->w * 2, _arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat());
- byte *src = (byte *)_arrayBmp[i * 2]->pixels;
- byte *dst = (byte *)_arrayBmp[i * 2 + 1]->pixels;
for (int j = 0; j < _arrayBmp[i * 2]->h; j++) {
- src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j);
- dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
+ byte *src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j);
+ byte *dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
for (int k = _arrayBmp[i * 2]->w; k > 0; k--) {
for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
*dst++ = *src++;
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index fbe39b3a0c..3dc9c9a1c3 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -75,13 +75,13 @@ static const byte stdMouseCursor[] = {
Screen::Screen(HugoEngine *vm) : _vm(vm) {
- _mainPalette = 0;
- _curPalette = 0;
+ _mainPalette = nullptr;
+ _curPalette = nullptr;
_dlAddIndex = 0;
_dlRestoreIndex = 0;
for (int i = 0; i < kNumFonts; i++) {
- _arrayFont[i] = 0;
+ _arrayFont[i] = nullptr;
fontLoadedFl[i] = false;
}
for (int i = 0; i < kBlitListSize; i++) {
@@ -100,6 +100,8 @@ Screen::Screen(HugoEngine *vm) : _vm(vm) {
_dlRestoreList[i]._dx = 0;
_dlRestoreList[i]._dy = 0;
}
+ _fnt = 0;
+ _paletteSize = 0;
}
Screen::~Screen() {
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index e58c2e57d6..aa128048af 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -246,13 +246,13 @@ SoundPtr FileManager::getSound(const int16 sound, uint16 *size) {
// No more to do if SILENCE (called for cleanup purposes)
if (sound == _vm->_soundSilence)
- return 0;
+ return nullptr;
// Open sounds file
Common::File fp; // Handle to SOUND_FILE
if (!fp.open(getSoundFilename())) {
warning("Hugo Error: File not found %s", getSoundFilename());
- return 0;
+ return nullptr;
}
if (!_hasReadHeader) {
@@ -519,6 +519,7 @@ void FileManager::readBootFile() {
ofp.read(_vm->_boot._pbswitch, sizeof(_vm->_boot._pbswitch));
ofp.read(_vm->_boot._distrib, sizeof(_vm->_boot._distrib));
_vm->_boot._exitLen = ofp.readUint16LE();
+ ofp.close();
byte *p = (byte *)&_vm->_boot;
@@ -527,7 +528,6 @@ void FileManager::readBootFile() {
checksum ^= p[i];
p[i] ^= s_bootCypher[i % s_bootCypherLen];
}
- ofp.close();
if (checksum) {
Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename()));
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index bcf06055f8..88e2e4372b 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -46,11 +46,11 @@
namespace Hugo {
-HugoEngine *HugoEngine::s_Engine = 0;
+HugoEngine *HugoEngine::s_Engine = nullptr;
HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd),
- _hero(0), _heroImage(0), _defltTunes(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
- _screenStates(0), _numStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(0), _episode(0)
+ _hero(nullptr), _heroImage(0), _defltTunes(nullptr), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
+ _screenStates(nullptr), _numStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(0), _episode(nullptr)
{
_system = syst;
DebugMan.addDebugChannel(kDebugSchedule, "Schedule", "Script Schedule debug level");
@@ -66,17 +66,17 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
_console = new HugoConsole(this);
_rnd = 0;
-
- _screen = NULL;
- _mouse = NULL;
- _inventory = NULL;
- _parser = NULL;
- _route = NULL;
- _sound = NULL;
- _intro = NULL;
- _object = NULL;
- _text = NULL;
- _topMenu = NULL;
+
+ _screen = nullptr;
+ _mouse = nullptr;
+ _inventory = nullptr;
+ _parser = nullptr;
+ _route = nullptr;
+ _sound = nullptr;
+ _intro = nullptr;
+ _object = nullptr;
+ _text = nullptr;
+ _topMenu = nullptr;
_status._storyModeFl = false;
_status._gameOverFl = false;
_status._lookFl = false;
@@ -93,6 +93,26 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
_gameType = kGameTypeNone;
_platform = Common::kPlatformUnknown;
_packedFl = false;
+
+ _numVariant = 0;
+ _gameVariant = kGameVariantNone;
+ _normalTPS = 0;
+ _screenPtr = nullptr;
+ _config._musicFl = true;
+ _config._soundFl = true;
+ _config._turboFl = false;
+ _look = 0;
+ _take = 0;
+ _drop = 0;
+ _maze._enabledFl = false;
+ _maze._size = 0;
+ _maze._x1 = _maze._y1 = _maze._x2 = _maze._y2 = _maze._x3 = _maze._x4 = 0;
+ _maze._firstScreenIndex = 0;
+ _boot._checksum = 0;
+ _boot._registered = kRegShareware;
+ _boot._exitLen = 0;
+ _file = nullptr;
+ _scheduler = nullptr;
}
HugoEngine::~HugoEngine() {
diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h
index 9f495a9037..6adb5f95d0 100644
--- a/engines/hugo/hugo.h
+++ b/engines/hugo/hugo.h
@@ -106,7 +106,8 @@ enum GameVariant {
kGameVariantH3Win,
kGameVariantH1Dos,
kGameVariantH2Dos,
- kGameVariantH3Dos
+ kGameVariantH3Dos,
+ kGameVariantNone
};
enum HugoDebugChannels {
@@ -259,7 +260,7 @@ public:
// Used by the qsort function
static HugoEngine &get() {
- assert(s_Engine != 0);
+ assert(s_Engine != nullptr);
return *s_Engine;
}
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 505e356049..5db6c39078 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -39,9 +39,10 @@
namespace Hugo {
-IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm), _introX(0), _introY(0) {
+IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm) {
_introXSize = 0;
_introTicks = 0;
+ _introX = _introY = nullptr;
}
IntroHandler::~IntroHandler() {
@@ -74,6 +75,7 @@ void IntroHandler::loadIntroData(Common::SeekableReadStream &in) {
void IntroHandler::freeIntroData() {
free(_introX);
free(_introY);
+ _introX = _introY = nullptr;
}
intro_v1d::intro_v1d(HugoEngine *vm) : IntroHandler(vm) {
@@ -89,11 +91,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 +241,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 +283,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/hugo/inventory.cpp b/engines/hugo/inventory.cpp
index c2495beadb..03df997866 100644
--- a/engines/hugo/inventory.cpp
+++ b/engines/hugo/inventory.cpp
@@ -44,7 +44,8 @@ namespace Hugo {
static const int kMaxDisp = (kXPix / kInvDx); // Max icons displayable
-InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm), _invent(0) {
+InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
+ _invent = nullptr;
_firstIconId = 0;
_inventoryState = kInventoryOff; // Inventory icon bar state
_inventoryHeight = 0; // Inventory icon bar pos
@@ -62,6 +63,7 @@ void InventoryHandler::setInventoryState(Istate state) {
void InventoryHandler::freeInvent() {
free(_invent);
+ _invent = nullptr;
}
int16 InventoryHandler::getInventoryObjId() const {
diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp
index ae286c8afb..4ef3db3e2b 100644
--- a/engines/hugo/mouse.cpp
+++ b/engines/hugo/mouse.cpp
@@ -45,7 +45,8 @@
namespace Hugo {
-MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm), _hotspots(0) {
+MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm) {
+ _hotspots = nullptr;
_leftButtonFl = false;
_rightButtonFl = false;
_jumpExitFl = false; // Can't jump to a screen exit
@@ -83,6 +84,7 @@ void MouseHandler::setMouseY(int y) {
void MouseHandler::freeHotspots() {
free(_hotspots);
+ _hotspots = nullptr;
}
bool MouseHandler::getJumpExitFl() const {
@@ -169,7 +171,7 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in
_vm->_object->useObject(objId); // Use status.objid on object
} else { // Clicked over viewport object
Object *obj = &_vm->_object->_objects[objId];
- int16 x = 0, y = 0;
+ int16 x, y;
switch (obj->_viewx) { // Where to walk to
case -1: // Walk to object position
if (_vm->_object->findObjectSpace(obj, &x, &y))
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index 7b4783e4d8..44f46d2d79 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -44,7 +44,9 @@
namespace Hugo {
-ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) {
+ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm) {
+ _uses = nullptr;
+ _objects = nullptr;
_numObj = 0;
_objCount = 0;
_usesSize = 0;
@@ -249,47 +251,49 @@ void ObjectHandler::lookObject(Object *obj) {
void ObjectHandler::freeObjects() {
debugC(1, kDebugObject, "freeObjects");
- if (_vm->_hero != 0 && _vm->_hero->_seqList[0]._seqPtr != 0) {
+ if (_vm->_hero != nullptr && _vm->_hero->_seqList[0]._seqPtr != nullptr) {
// Free all sequence lists and image data
for (int16 i = 0; i < _numObj; i++) {
Object *obj = &_objects[i];
for (int16 j = 0; j < obj->_seqNumb; j++) {
Seq *seq = obj->_seqList[j]._seqPtr;
Seq *next;
- if (seq == 0) // Failure during database load
+ if (seq == nullptr) // Failure during database load
break;
- if (seq->_imagePtr != 0) {
+ if (seq->_imagePtr != nullptr) {
free(seq->_imagePtr);
- seq->_imagePtr = 0;
+ seq->_imagePtr = nullptr;
}
seq = seq->_nextSeqPtr;
while (seq != obj->_seqList[j]._seqPtr) {
- if (seq->_imagePtr != 0) {
+ if (seq->_imagePtr != nullptr) {
free(seq->_imagePtr);
- seq->_imagePtr = 0;
+ seq->_imagePtr = nullptr;
}
next = seq->_nextSeqPtr;
free(seq);
seq = next;
}
free(seq);
+ seq = nullptr;
}
}
}
- if (_uses) {
+ if (_uses != nullptr) {
for (int16 i = 0; i < _usesSize; i++)
free(_uses[i]._targets);
free(_uses);
+ _uses = nullptr;
}
for (int16 i = 0; i < _objCount; i++) {
free(_objects[i]._stateDataIndex);
- _objects[i]._stateDataIndex = 0;
+ _objects[i]._stateDataIndex = nullptr;
}
free(_objects);
- _objects = 0;
+ _objects = nullptr;
}
/**
@@ -358,7 +362,7 @@ void ObjectHandler::showTakeables() {
* Find a clear space around supplied object that hero can walk to
*/
bool ObjectHandler::findObjectSpace(Object *obj, int16 *destx, int16 *desty) {
- debugC(1, kDebugObject, "findObjectSpace(obj, %d, %d)", *destx, *desty);
+ debugC(1, kDebugObject, "findObjectSpace(...)");
Seq *curImage = obj->_currImagePtr;
int16 y = obj->_y + curImage->_y2 - 1;
@@ -414,7 +418,7 @@ void ObjectHandler::readUse(Common::ReadStream &in, Uses &curUse) {
*/
void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
Uses tmpUse;
- tmpUse._targets = 0;
+ tmpUse._targets = nullptr;
//Read _uses
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
@@ -430,7 +434,7 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
else {
readUse(in, tmpUse);
free(tmpUse._targets);
- tmpUse._targets = 0;
+ tmpUse._targets = nullptr;
}
}
}
@@ -442,7 +446,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
uint16 numSubElem = in.readUint16BE();
if (numSubElem == 0)
- curObject._stateDataIndex = 0;
+ curObject._stateDataIndex = nullptr;
else
curObject._stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
for (int j = 0; j < numSubElem; j++)
@@ -453,16 +457,16 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
curObject._vyPath = in.readSint16BE();
curObject._actIndex = in.readUint16BE();
curObject._seqNumb = in.readByte();
- curObject._currImagePtr = 0;
+ curObject._currImagePtr = nullptr;
if (curObject._seqNumb == 0) {
curObject._seqList[0]._imageNbr = 0;
- curObject._seqList[0]._seqPtr = 0;
+ curObject._seqList[0]._seqPtr = nullptr;
}
for (int j = 0; j < curObject._seqNumb; j++) {
curObject._seqList[j]._imageNbr = in.readUint16BE();
- curObject._seqList[j]._seqPtr = 0;
+ curObject._seqList[j]._seqPtr = nullptr;
}
curObject._cycling = (Cycle)in.readByte();
@@ -498,7 +502,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
debugC(6, kDebugObject, "loadObject(&in)");
Object tmpObject;
- tmpObject._stateDataIndex = 0;
+ tmpObject._stateDataIndex = nullptr;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
uint16 numElem = in.readUint16BE();
@@ -515,7 +519,7 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
// Skip over uneeded objects.
readObject(in, tmpObject);
free(tmpObject._stateDataIndex);
- tmpObject._stateDataIndex = 0;
+ tmpObject._stateDataIndex = nullptr;
}
}
}
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 2585c64fd8..57938ec371 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -44,14 +44,20 @@
namespace Hugo {
-Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0), _arrayReqs(0), _catchallList(0), _backgroundObjects(0), _cmdList(0) {
+Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0) {
+ _catchallList = nullptr;
+ _arrayReqs = nullptr;
+
+ _backgroundObjects = nullptr;
+ _backgroundObjectsSize = 0;
+ _cmdList = nullptr;
+ _cmdListSize = 0;
+
_cmdLineIndex = 0;
_cmdLineTick = 0;
_cmdLineCursor = '_';
_cmdLine[0] = '\0';
- _cmdListSize = 0;
_checkDoubleF1Fl = false;
- _backgroundObjectsSize = 0;
}
Parser::~Parser() {
@@ -172,7 +178,7 @@ const char *Parser::useBG(const char *name) {
return _vm->_text->getVerb(p[i]._verbIndex, 0);
}
- return 0;
+ return nullptr;
}
void Parser::freeParser() {
@@ -180,20 +186,24 @@ void Parser::freeParser() {
for (int i = 0; _arrayReqs[i] != 0; i++)
free(_arrayReqs[i]);
free(_arrayReqs);
+ _arrayReqs = nullptr;
}
free(_catchallList);
+ _catchallList = nullptr;
if (_backgroundObjects) {
for (int i = 0; i < _backgroundObjectsSize; i++)
free(_backgroundObjects[i]);
free(_backgroundObjects);
+ _backgroundObjects = nullptr;
}
if (_cmdList) {
for (int i = 0; i < _cmdListSize; i++)
free(_cmdList[i]);
free(_cmdList);
+ _cmdList = nullptr;
}
}
@@ -398,9 +408,9 @@ void Parser::command(const char *format, ...) {
* Locate any member of object name list appearing in command line
*/
bool Parser::isWordPresent(char **wordArr) const {
- debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
-
if (wordArr != 0) {
+ debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
+
for (int i = 0; strlen(wordArr[i]); i++) {
if (strstr(_vm->_line, wordArr[i]))
return true;
@@ -421,7 +431,7 @@ const char *Parser::findNoun() const {
return _vm->_text->getNoun(i, 0);
}
}
- return 0;
+ return nullptr;
}
/**
@@ -436,7 +446,7 @@ const char *Parser::findVerb() const {
return _vm->_text->getVerb(i, 0);
}
}
- return 0;
+ return nullptr;
}
/**
diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp
index 54dae88c28..dc3c41de9c 100644
--- a/engines/hugo/route.cpp
+++ b/engines/hugo/route.cpp
@@ -45,6 +45,17 @@ Route::Route(HugoEngine *vm) : _vm(vm) {
_routeIndex = -1; // Hero not following a route
_routeType = kRouteSpace; // Hero walking to space
_routeObjId = -1; // Hero not walking to anything
+
+ for (int i = 0; i < kMaxSeg; i++)
+ _segment[i]._y = _segment[i]._x1 = _segment[i]._x2 = 0;
+
+ _segmentNumb = 0;
+ _routeListIndex = 0;
+ _destX = _destY = 0;
+ _heroWidth = 0;
+ _routeFoundFl = false;
+ _fullStackFl = false;
+ _fullSegmentFl = false;
}
void Route::resetRoute() {
@@ -303,7 +314,7 @@ Common::Point *Route::newNode() {
_routeListIndex++;
if (_routeListIndex >= kMaxNodes) // Too many nodes
- return 0; // Incomplete route - failure
+ return nullptr; // Incomplete route - failure
_route[_routeListIndex] = _route[_routeListIndex - 1]; // Initialize with previous node
return &_route[_routeListIndex];
diff --git a/engines/hugo/route.h b/engines/hugo/route.h
index 716829a201..71db1e2583 100644
--- a/engines/hugo/route.h
+++ b/engines/hugo/route.h
@@ -79,9 +79,11 @@ private:
int16 _destY;
int16 _heroWidth; // Hero width
bool _routeFoundFl; // TRUE when path found
- bool _fullStackFl; // TRUE if stack exhausted
bool _fullSegmentFl; // Segments exhausted
+ // CHECKME: Never set to true, could be removed
+ bool _fullStackFl; // TRUE if stack exhausted
+
void segment(int16 x, int16 y);
bool findRoute(const int16 cx, const int16 cy);
Common::Point *newNode();
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 32b8a47df7..17ffa9d391 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -47,10 +47,23 @@
namespace Hugo {
-Scheduler::Scheduler(HugoEngine *vm) : _vm(vm), _actListArr(0), _curTick(0), _oldTime(0), _refreshTimeout(0), _points(0), _screenActs(0) {
+Scheduler::Scheduler(HugoEngine *vm) : _vm(vm) {
+ _actListArr = nullptr;
+ _curTick = 0;
+ _oldTime = 0;
+ _refreshTimeout = 0;
+ _points = nullptr;
+ _screenActs = nullptr;
+
memset(_events, 0, sizeof(_events));
_numBonuses = 0;
_screenActsSize = 0;
+
+ _actListArrSize = 0;
+ _alNewscrIndex = 0;
+ _freeEvent = nullptr;
+ _headEvent = nullptr;
+ _tailEvent = nullptr;
}
Scheduler::~Scheduler() {
@@ -69,14 +82,14 @@ void Scheduler::initEventQueue() {
// Chain nextEvent from first to last
for (int i = kMaxEvents; --i;)
_events[i - 1]._nextEvent = &_events[i];
- _events[kMaxEvents - 1]._nextEvent = 0;
+ _events[kMaxEvents - 1]._nextEvent = nullptr;
// Chain prevEvent from last to first
for (int i = 1; i < kMaxEvents; i++)
_events[i]._prevEvent = &_events[i - 1];
- _events[0]._prevEvent = 0;
+ _events[0]._prevEvent = nullptr;
- _headEvent = _tailEvent = 0; // Event list is empty
+ _headEvent = _tailEvent = nullptr; // Event list is empty
_freeEvent = _events; // Free list is full
}
@@ -90,7 +103,7 @@ Event *Scheduler::getQueue() {
error("An error has occurred: %s", "getQueue");
Event *resEvent = _freeEvent;
_freeEvent = _freeEvent->_nextEvent;
- resEvent->_nextEvent = 0;
+ resEvent->_nextEvent = nullptr;
return resEvent;
}
@@ -597,7 +610,7 @@ void Scheduler::loadScreenAct(Common::SeekableReadStream &in) {
for (int i = 0; i < numElem; i++) {
uint16 numSubElem = in.readUint16BE();
if (numSubElem == 0) {
- _screenActs[i] = 0;
+ _screenActs[i] = nullptr;
} else {
_screenActs[i] = (uint16 *)malloc(sizeof(uint16) * numSubElem);
for (int j = 0; j < numSubElem; j++)
@@ -617,11 +630,14 @@ void Scheduler::freeScheduler() {
debugC(6, kDebugSchedule, "freeActListArr()");
free(_points);
+ _points = nullptr;
if (_screenActs) {
for (int i = 0; i < _screenActsSize; i++)
free(_screenActs[i]);
free(_screenActs);
+ _screenActs = nullptr;
+ _screenActsSize = 0;
}
if (_actListArr) {
@@ -633,6 +649,8 @@ void Scheduler::freeScheduler() {
free(_actListArr[i]);
}
free(_actListArr);
+ _actListArr = nullptr;
+ _actListArrSize = 0;
}
}
@@ -698,9 +716,9 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
f->writeUint32BE(getTicks());
- int16 freeIndex = (_freeEvent == 0) ? -1 : _freeEvent - _events;
- int16 headIndex = (_headEvent == 0) ? -1 : _headEvent - _events;
- int16 tailIndex = (_tailEvent == 0) ? -1 : _tailEvent - _events;
+ int16 freeIndex = (_freeEvent == nullptr) ? -1 : _freeEvent - _events;
+ int16 headIndex = (_headEvent == nullptr) ? -1 : _headEvent - _events;
+ int16 tailIndex = (_tailEvent == nullptr) ? -1 : _tailEvent - _events;
f->writeSint16BE(freeIndex);
f->writeSint16BE(headIndex);
@@ -717,8 +735,8 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
f->writeSint16BE(subElem);
f->writeByte((wrkEvent->_localActionFl) ? 1 : 0);
f->writeUint32BE(wrkEvent->_time);
- f->writeSint16BE((wrkEvent->_prevEvent == 0) ? -1 : (wrkEvent->_prevEvent - _events));
- f->writeSint16BE((wrkEvent->_nextEvent == 0) ? -1 : (wrkEvent->_nextEvent - _events));
+ f->writeSint16BE((wrkEvent->_prevEvent == nullptr) ? -1 : (wrkEvent->_prevEvent - _events));
+ f->writeSint16BE((wrkEvent->_nextEvent == nullptr) ? -1 : (wrkEvent->_nextEvent - _events));
}
}
@@ -1102,7 +1120,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
// fix up action pointer (to do better)
if ((index == -1) && (subElem == -1))
- _events[i]._action = 0;
+ _events[i]._action = nullptr;
else
_events[i]._action = (Act *)&_actListArr[index][subElem];
@@ -1112,12 +1130,12 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
int16 prevIndex = f->readSint16BE();
int16 nextIndex = f->readSint16BE();
- _events[i]._prevEvent = (prevIndex == -1) ? (Event *)0 : &_events[prevIndex];
- _events[i]._nextEvent = (nextIndex == -1) ? (Event *)0 : &_events[nextIndex];
+ _events[i]._prevEvent = (prevIndex == -1) ? nullptr : &_events[prevIndex];
+ _events[i]._nextEvent = (nextIndex == -1) ? nullptr : &_events[nextIndex];
}
- _freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex];
- _headEvent = (headIndex == -1) ? 0 : &_events[headIndex];
- _tailEvent = (tailIndex == -1) ? 0 : &_events[tailIndex];
+ _freeEvent = (freeIndex == -1) ? nullptr : &_events[freeIndex];
+ _headEvent = (headIndex == -1) ? nullptr : &_events[headIndex];
+ _tailEvent = (tailIndex == -1) ? nullptr : &_events[tailIndex];
// Adjust times to fit our time
uint32 curTime = getTicks();
@@ -1156,7 +1174,7 @@ void Scheduler::insertAction(Act *action) {
// Now find the place to insert the event
if (!_tailEvent) { // Empty queue
_tailEvent = _headEvent = curEvent;
- curEvent->_nextEvent = curEvent->_prevEvent = 0;
+ curEvent->_nextEvent = curEvent->_prevEvent = nullptr;
} else {
Event *wrkEvent = _tailEvent; // Search from latest time back
bool found = false;
@@ -1178,7 +1196,7 @@ void Scheduler::insertAction(Act *action) {
if (!found) { // Must be earliest in list
_headEvent->_prevEvent = curEvent; // So insert as new head
curEvent->_nextEvent = _headEvent;
- curEvent->_prevEvent = 0;
+ curEvent->_prevEvent = nullptr;
_headEvent = curEvent;
}
}
@@ -1424,7 +1442,7 @@ Event *Scheduler::doAction(Event *curEvent) {
}
if (action->_a0._actType == NEW_SCREEN) { // New_screen() deletes entire list
- return 0; // nextEvent = 0 since list now empty
+ return nullptr; // nextEvent = nullptr since list now empty
} else {
wrkEvent = curEvent->_nextEvent;
delQueue(curEvent); // Return event to free list
@@ -1455,9 +1473,9 @@ void Scheduler::delQueue(Event *curEvent) {
}
if (_headEvent)
- _headEvent->_prevEvent = 0; // Mark end of list
+ _headEvent->_prevEvent = nullptr; // Mark end of list
else
- _tailEvent = 0; // Empty queue
+ _tailEvent = nullptr; // Empty queue
curEvent->_nextEvent = _freeEvent; // Return p to free list
if (_freeEvent) // Special case, if free list was empty
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index aefa03cd5e..28dcdc83d6 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -123,11 +123,12 @@ SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
_speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
- _DOSSongPtr = 0;
+ _DOSSongPtr = nullptr;
_curPriority = 0;
_pcspkrTimer = 0;
_pcspkrOctave = 3;
_pcspkrNoteDuration = 2;
+ _DOSIntroSong = nullptr;
}
SoundHandler::~SoundHandler() {
@@ -210,7 +211,7 @@ void SoundHandler::playSound(int16 sound, const byte priority) {
_curPriority = priority;
// Get sound data
- if ((soundPtr = _vm->_file->getSound(sound, &size)) == 0)
+ if ((soundPtr = _vm->_file->getSound(sound, &size)) == nullptr)
return;
Audio::AudioStream *stream = Audio::makeRawStream(soundPtr, size, 11025, Audio::FLAG_UNSIGNED);
diff --git a/engines/hugo/text.cpp b/engines/hugo/text.cpp
index f8b02bdf68..538a0341e2 100644
--- a/engines/hugo/text.cpp
+++ b/engines/hugo/text.cpp
@@ -26,9 +26,17 @@
namespace Hugo {
-TextHandler::TextHandler(HugoEngine *vm) : _vm(vm), _textData(0), _stringtData(0),
- _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textUtil(0),
- _screenNames(0), _arrayNouns(0), _arrayVerbs(0) {
+TextHandler::TextHandler(HugoEngine *vm) : _vm(vm) {
+ _textData = nullptr;
+ _stringtData = nullptr;
+ _textEngine = nullptr;
+ _textIntro = nullptr;
+ _textMouse = nullptr;
+ _textParser = nullptr;
+ _textUtil = nullptr;
+ _screenNames = nullptr;
+ _arrayNouns = nullptr;
+ _arrayVerbs = nullptr;
}
TextHandler::~TextHandler() {
@@ -86,9 +94,9 @@ char **TextHandler::loadTextsVariante(Common::ReadStream &in, uint16 *arraySize)
int numTexts;
int entryLen;
int len;
- char **res = 0;
- char *pos = 0;
- char *posBck = 0;
+ char **res = nullptr;
+ char *pos = nullptr;
+ char *posBck = nullptr;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
numTexts = in.readUint16BE();
@@ -126,21 +134,21 @@ char **TextHandler::loadTextsVariante(Common::ReadStream &in, uint16 *arraySize)
}
char ***TextHandler::loadTextsArray(Common::ReadStream &in) {
- char ***resArray = 0;
+ char ***resArray = nullptr;
uint16 arraySize;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
arraySize = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
resArray = (char ***)malloc(sizeof(char **) * (arraySize + 1));
- resArray[arraySize] = 0;
+ resArray[arraySize] = nullptr;
}
for (int i = 0; i < arraySize; i++) {
int numTexts = in.readUint16BE();
int entryLen = in.readUint16BE();
char *pos = (char *)malloc(entryLen);
- char *posBck = 0;
- char **res = 0;
+ char *posBck = nullptr;
+ char **res = nullptr;
if (varnt == _vm->_gameVariant) {
res = (char **)malloc(sizeof(char *) * numTexts);
res[0] = pos;
@@ -232,6 +240,7 @@ void TextHandler::freeTexts(char **ptr) {
free(*ptr - DATAALIGNMENT);
free(ptr);
+ ptr = nullptr;
}
void TextHandler::freeAllTexts() {
@@ -242,12 +251,14 @@ void TextHandler::freeAllTexts() {
for (int i = 0; _arrayNouns[i]; i++)
freeTexts(_arrayNouns[i]);
free(_arrayNouns);
+ _arrayNouns = nullptr;
}
if (_arrayVerbs) {
for (int i = 0; _arrayVerbs[i]; i++)
freeTexts(_arrayVerbs[i]);
free(_arrayVerbs);
+ _arrayVerbs = nullptr;
}
freeTexts(_screenNames);
diff --git a/engines/kyra/POTFILES b/engines/kyra/POTFILES
new file mode 100644
index 0000000000..16888e2c5a
--- /dev/null
+++ b/engines/kyra/POTFILES
@@ -0,0 +1,3 @@
+engines/kyra/detection.cpp
+engines/kyra/lol.cpp
+engines/kyra/sound_midi.cpp
diff --git a/engines/kyra/animator_lok.cpp b/engines/kyra/animator_lok.cpp
index c246eebd46..945a51a4ec 100644
--- a/engines/kyra/animator_lok.cpp
+++ b/engines/kyra/animator_lok.cpp
@@ -491,7 +491,7 @@ Animator_LoK::AnimObject *Animator_LoK::objectAddHead(AnimObject *queue, AnimObj
}
Animator_LoK::AnimObject *Animator_LoK::objectQueue(AnimObject *queue, AnimObject *add) {
- if (add->drawY <= queue->drawY || !queue) {
+ if (!queue || add->drawY <= queue->drawY) {
add->nextAnimObject = queue;
return add;
}
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 80a95da047..80ff42e2c5 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -155,8 +155,10 @@ CharacterGenerator::~CharacterGenerator() {
}
bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
- if (!characters && !faceShapes)
+ if (!characters || !faceShapes) {
+ warning("CharacterGenerator::start: Called without character data");
return true;
+ }
_characters = characters;
_faceShapes = *faceShapes;
diff --git a/engines/kyra/configure.engine b/engines/kyra/configure.engine
new file mode 100644
index 0000000000..b7d6334fcc
--- /dev/null
+++ b/engines/kyra/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
+add_engine lol "Lands of Lore" yes
+add_engine eob "Eye of the Beholder" yes
diff --git a/engines/kyra/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/kyra_rpg.cpp b/engines/kyra/kyra_rpg.cpp
index f8eb7d00cd..4f7adcc6e5 100644
--- a/engines/kyra/kyra_rpg.cpp
+++ b/engines/kyra/kyra_rpg.cpp
@@ -213,7 +213,7 @@ void KyraRpgEngine::drawDialogueButtons() {
screen()->printText(_dialogueButtonString[i], (x + 37 - (screen()->getTextWidth(_dialogueButtonString[i])) / 2) & ~3,
((_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2) & ~7, _dialogueHighlightedButton == i ? 0xC1 : 0xE1, 0);
} else {
- int sjisYOffset = (_flags.lang == Common::JA_JPN && _dialogueButtonString[i][0] < 0) ? 2 : 0;
+ int sjisYOffset = (_flags.lang == Common::JA_JPN && (_dialogueButtonString[i][0] & 0x80)) ? 2 : 0;
gui_drawBox(x, (_dialogueButtonYoffs + _dialogueButtonPosY[i]), _dialogueButtonWidth, guiSettings()->buttons.height, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
screen()->printText(_dialogueButtonString[i], x + (_dialogueButtonWidth >> 1) - (screen()->getTextWidth(_dialogueButtonString[i])) / 2,
(_dialogueButtonYoffs + _dialogueButtonPosY[i]) + 2 - sjisYOffset, _dialogueHighlightedButton == i ? _dialogueButtonLabelColor1 : _dialogueButtonLabelColor2, 0);
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index c350c81742..7a1abe8dd9 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -74,10 +74,14 @@ bool Resource::reset() {
loadProtectedFiles(list);
} else {
+ // We only search in the game path to avoid any invalid PAK or
+ // APK files from being picked up. This might happen, for example,
+ // when the user has an Android package file in the CWD.
+ Common::FSDirectory gameDir(dir);
Common::ArchiveMemberList files;
- _files.listMatchingMembers(files, "*.PAK");
- _files.listMatchingMembers(files, "*.APK");
+ gameDir.listMatchingMembers(files, "*.PAK");
+ gameDir.listMatchingMembers(files, "*.APK");
for (Common::ArchiveMemberList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name = (*i)->getName();
diff --git a/engines/kyra/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 419b630714..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) {
@@ -1256,7 +1263,7 @@ int Screen::getTextWidth(const char *str) {
while (1) {
if (_sjisMixedFontMode)
- setFont(*str < 0 ? FID_SJIS_FNT : curFont);
+ setFont((*str & 0x80) ? FID_SJIS_FNT : curFont);
uint c = fetchChar(str);
@@ -1296,7 +1303,7 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
while (1) {
if (_sjisMixedFontMode)
- setFont(*str < 0 ? FID_SJIS_FNT : curFont);
+ setFont((*str & 0x80) ? FID_SJIS_FNT : curFont);
uint8 charHeightFnt = getFontHeight();
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index cc7d526ffe..23eb94cb53 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -280,7 +280,7 @@ void Screen_v2::setTextColorMap(const uint8 *cmap) {
void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) {
- if (!(w1 || h1 || w2 || h2))
+ if (!w1 || !h1 || !w2 || !h2)
return;
ScreenDim cdm = *getScreenDim(dim);
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 2a2f9a5493..51f1ea51cf 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -1722,9 +1722,10 @@ int KyraEngine_LoK::handleBeadState() {
_screen->addBitBlitRect(_beadState1.x, _beadState1.y, _beadState1.width2, _beadState1.height);
++_beadState1.tableIndex;
- if (_beadState1.tableIndex > 24)
+ if (_beadState1.tableIndex > 24) {
_beadState1.tableIndex = 0;
_unkEndSeqVar4 = 1;
+ }
if (_system->getMillis() > _beadStateTimer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) {
snd_playSoundEffect(0x0B);
if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 &&
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index af741a1ebe..e4752f33de 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -225,6 +225,7 @@ void SoundTowns::playSoundEffect(uint8 track, uint8) {
_driver->chanPanPos(_sfxChannel, 0x40);
_driver->chanPitch(_sfxChannel, 0);
_driver->playSoundEffect(_sfxChannel, note, 127, sfxPlaybackBuffer);
+ delete[] sfxPlaybackBuffer;
}
void SoundTowns::updateVolumeSettings() {
diff --git a/engines/kyra/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/configure.engine b/engines/lastexpress/configure.engine
new file mode 100644
index 0000000000..807b1a088b
--- /dev/null
+++ b/engines/lastexpress/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine lastexpress "The Last Express" no "" "" "16bit"
diff --git a/engines/lastexpress/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/entities/entity.h b/engines/lastexpress/entities/entity.h
index c67d13db9e..f3b57e7464 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -330,7 +330,7 @@ public:
};
struct EntityParametersSIII : EntityParameters {
- char seq[12];
+ char seq[13];
uint param4;
uint param5;
uint param6;
@@ -338,7 +338,7 @@ public:
uint param8;
EntityParametersSIII() {
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param4 = 0;
param5 = 0;
param6 = 0;
@@ -374,16 +374,16 @@ public:
};
struct EntityParametersSIIS : EntityParameters {
- char seq1[12];
+ char seq1[13];
uint param4;
uint param5;
- char seq2[12];
+ char seq2[13];
EntityParametersSIIS() {
- memset(&seq1, 0, 12);
+ memset(&seq1, 0, 13);
param4 = 0;
param5 = 0;
- memset(&seq2, 0, 12);
+ memset(&seq2, 0, 13);
}
Common::String toString() {
@@ -410,14 +410,14 @@ public:
struct EntityParametersISSI : EntityParameters {
uint param1;
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
uint param8;
EntityParametersISSI() {
param1 = 0;
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
param8 = 0;
}
@@ -445,7 +445,7 @@ public:
struct EntityParametersISII : EntityParameters {
uint param1;
- char seq[12];
+ char seq[13];
uint param5;
uint param6;
uint param7;
@@ -453,7 +453,7 @@ public:
EntityParametersISII() {
param1 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param5 = 0;
param6 = 0;
param7 = 0;
@@ -488,14 +488,14 @@ public:
};
struct EntityParametersSSII : EntityParameters {
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
uint param7;
uint param8;
EntityParametersSSII() {
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
param7 = 0;
param8 = 0;
}
@@ -523,14 +523,14 @@ public:
};
struct EntityParametersSSS : EntityParameters {
- char seq1[12];
- char seq2[12];
- char seq3[8];
+ char seq1[13];
+ char seq2[13];
+ char seq3[9];
EntityParametersSSS() {
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
- memset(&seq3, 0, 8);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
+ memset(&seq3, 0, 9);
}
Common::String toString() {
@@ -551,14 +551,14 @@ public:
struct EntityParametersIISS : EntityParameters {
uint param1;
uint param2;
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
EntityParametersIISS() {
param1 = 0;
param2 = 0;
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
}
Common::String toString() {
@@ -586,7 +586,7 @@ public:
struct EntityParametersIISI : EntityParameters {
uint param1;
uint param2;
- char seq[12];
+ char seq[13];
uint param6;
uint param7;
uint param8;
@@ -594,7 +594,7 @@ public:
EntityParametersIISI() {
param1 = 0;
param2 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param6 = 0;
param7 = 0;
param8 = 0;
@@ -631,7 +631,7 @@ public:
uint param1;
uint param2;
uint param3;
- char seq[12];
+ char seq[13];
uint param7;
uint param8;
@@ -639,7 +639,7 @@ public:
param1 = 0;
param2 = 0;
param3 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param7 = 0;
param8 = 0;
}
@@ -677,7 +677,7 @@ public:
uint param3;
uint param4;
uint param5;
- char seq[12];
+ char seq[13];
EntityParametersI5S() {
param1 = 0;
@@ -685,7 +685,7 @@ public:
param3 = 0;
param4 = 0;
param5 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
}
void saveLoadWithSerializer(Common::Serializer &s) {
@@ -818,9 +818,9 @@ public:
/**
* Synchronizes a string.
*
- * @param s The Common::Serializer to use.
- * @param string The string.
- * @param length Length of the string.
+ * @param s The Common::Serializer to use.
+ * @param string The string.
+ * @param length Length of the string.
*/
void syncString(Common::Serializer &s, Common::String &string, uint length) const;
@@ -921,7 +921,7 @@ protected:
/**
* Play sound
*
- * @param savepoint The savepoint
+ * @param savepoint The savepoint
* - Sound filename
* @param resetItem true to reset item.
* @param flag sound flag
@@ -931,9 +931,9 @@ protected:
/**
* Draws the entity
*
- * @param savepoint The savepoint
- * - Sequence
- * - ExcuseMe flag
+ * @param savepoint The savepoint
+ * - Sequence
+ * - ExcuseMe flag
* @param handleExcuseMe true to handle excuseMeCath action
*/
void draw(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -941,7 +941,7 @@ protected:
/**
* Draws the entity along with another one
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
* - Sequence 1
* - Sequence 2
* - EntityIndex
@@ -976,23 +976,23 @@ protected:
/**
* Process callback action when the entity direction is not kDirectionRight
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
*/
void callbackActionOnDirection(const SavePoint &savepoint);
/**
* Process callback action when somebody is standing in the restaurant or salon.
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
*/
void callbackActionRestaurantOrSalon(const SavePoint &savepoint);
/**
* Updates the entity
*
- * @param savepoint The savepoint.
- * - CarIndex
- * - EntityPosition
+ * @param savepoint The savepoint.
+ * - CarIndex
+ * - EntityPosition
* @param handleExcuseMe true to handle the kActionExcuseMe/kActionExcuseMeCath actions.
*/
void updateEntity(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -1000,11 +1000,11 @@ protected:
/**
* Call a specific savepoint (or draw sequence in default case)
*
- * @param savepoint The savepoint.
- * - Sequence to draw in default case
- * - EntityIndex
- * - ActionIndex
- * - Sequence for the savepoint
+ * @param savepoint The savepoint.
+ * - Sequence to draw in default case
+ * - EntityIndex
+ * - ActionIndex
+ * - Sequence for the savepoint
* @param handleExcuseMe true to handle excuse me.
*/
void callSavepoint(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -1012,36 +1012,36 @@ protected:
/**
* Handles entering/exiting a compartment.
*
- * @param savepoint The savepoint.
- * @param position1 The first position.
- * @param position2 The second position.
- * @param car The car.
- * @param compartment The compartment.
- * @param alternate true to use the alternate version of SceneManager::loadSceneFromObject()
+ * @param savepoint The savepoint.
+ * @param position1 The first position.
+ * @param position2 The second position.
+ * @param car The car.
+ * @param compartment The compartment.
+ * @param alternate true to use the alternate version of SceneManager::loadSceneFromObject()
*/
void enterExitCompartment(const SavePoint &savepoint, EntityPosition position1 = kPositionNone, EntityPosition position2 = kPositionNone, CarIndex car = kCarNone, ObjectIndex compartment = kObjectNone, bool alternate = false, bool updateLocation = false);
/**
* Go to compartment.
*
- * @param savepoint The savepoint.
- * @param compartmentFrom The compartment from.
- * @param positionFrom The position from.
- * @param sequenceFrom The sequence from.
- * @param sequenceTo The sequence to.
+ * @param savepoint The savepoint.
+ * @param compartmentFrom The compartment from.
+ * @param positionFrom The position from.
+ * @param sequenceFrom The sequence from.
+ * @param sequenceTo The sequence to.
*/
void goToCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, Common::String sequenceTo);
/**
* Go to compartment from compartment.
*
- * @param savepoint The savepoint.
- * @param compartmentFrom The compartment from.
- * @param positionFrom The position from.
- * @param sequenceFrom The sequence from.
- * @param compartmentTo The compartment to.
- * @param positionTo The position to.
- * @param sequenceTo The sequence to.
+ * @param savepoint The savepoint.
+ * @param compartmentFrom The compartment from.
+ * @param positionFrom The position from.
+ * @param sequenceFrom The sequence from.
+ * @param compartmentTo The compartment to.
+ * @param positionTo The position to.
+ * @param sequenceTo The sequence to.
*/
void goToCompartmentFromCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, ObjectIndex compartmentTo, EntityPosition positionTo, Common::String sequenceTo);
diff --git a/engines/lastexpress/entities/servers0.cpp b/engines/lastexpress/entities/servers0.cpp
index 73e0d34722..6323ef0ca8 100644
--- a/engines/lastexpress/entities/servers0.cpp
+++ b/engines/lastexpress/entities/servers0.cpp
@@ -115,7 +115,7 @@ IMPLEMENT_FUNCTION_NOSETUP(5, Servers0, callbackActionOnDirection)
case kActionExitCompartment:
callbackAction();
- break;
+ break;
case kActionExcuseMeCath:
if (!params->param1) {
@@ -445,7 +445,7 @@ IMPLEMENT_FUNCTION(24, Servers0, chapter2Handler)
HANDLE_TABLE(1, 3, 1, setup_function25);
HANDLE_TABLE(1, 4, 2, setup_function26);
- break;
+ break;
case kActionCallback:
if (getCallback() == 1)
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index d9ddb0a4d1..68c0813013 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -105,7 +105,7 @@ IMPLEMENT_FUNCTION(3, Verges, callbackActionOnDirection)
case kActionExitCompartment:
callbackAction();
- break;
+ break;
case kActionExcuseMeCath:
if (!params->param1) {
diff --git a/engines/lastexpress/game/entities.h b/engines/lastexpress/game/entities.h
index 81aed627aa..cacbc408c9 100644
--- a/engines/lastexpress/game/entities.h
+++ b/engines/lastexpress/game/entities.h
@@ -110,7 +110,7 @@ public:
* Query if 'entity' is inside a compartment
*
* @param entity The entity.
- * @param car The car.
+ * @param car The car.
* @param position The position.
*
* @return true if inside the compartment, false if not.
@@ -247,7 +247,7 @@ public:
/**
* Query if nobody is in a compartment at that position.
*
- * @param car The car.
+ * @param car The car.
* @param position The position.
*
* @return true if nobody is in a compartment, false if not.
@@ -334,8 +334,8 @@ private:
static const int _compartmentsCount = 16;
static const int _positionsCount = 100 * 10; // 100 positions per train car
- LastExpressEngine *_engine;
- EntityData *_header;
+ LastExpressEngine *_engine;
+ EntityData *_header;
Common::Array<Entity *> _entities;
// Compartments & positions
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index 11e7369ee1..2f1b0a8e76 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -52,6 +52,8 @@ Inventory::Inventory(LastExpressEngine *engine) : _engine(engine), _selectedItem
_selectedItemRect = Common::Rect(44, 0, 76, 32);
init();
+
+ debug(9, "_showingHourGlass: %d", _showingHourGlass);
}
Inventory::~Inventory() {
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index 09104d1bf9..d24fb9b598 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -413,8 +413,8 @@ void Logic::resetState() {
/**
* Handle game over
*
- * @param type The savegame type.
- * @param value The value (event, time, index, ...)
+ * @param type The savegame type.
+ * @param value The value (event, time, index, ...)
* @param sceneIndex Index of the scene to show.
* @param showScene true to show a scene, false to return to menu directly
*/
diff --git a/engines/lastexpress/game/logic.h b/engines/lastexpress/game/logic.h
index efb8f1e1a3..b2d08cb06f 100644
--- a/engines/lastexpress/game/logic.h
+++ b/engines/lastexpress/game/logic.h
@@ -54,7 +54,7 @@ public:
void playFinalSequence() const;
void updateCursor(bool redraw = true) const;
- Action *getGameAction() { return _action; }
+ Action *getGameAction() { return _action; }
Beetle *getGameBeetle() { return _beetle; }
Entities *getGameEntities() { return _entities; }
Fight *getGameFight() { return _fight; }
diff --git a/engines/lastexpress/game/object.cpp b/engines/lastexpress/game/object.cpp
index 48df91ea6d..2fcdde12b9 100644
--- a/engines/lastexpress/game/object.cpp
+++ b/engines/lastexpress/game/object.cpp
@@ -69,11 +69,12 @@ void Objects::update(ObjectIndex index, EntityIndex entity, ObjectLocation locat
getFlags()->flag_3 = true;
// Compartments
- if (original_location != location && (original_location == kObjectLocation2 || location == kObjectLocation2))
+ if (original_location != location && (original_location == kObjectLocation2 || location == kObjectLocation2)) {
if ((index >= kObjectCompartment1 && index <= kObjectCompartment8)
- || (index >= kObjectCompartmentA && index <= kObjectCompartmentF)) {
- getScenes()->updateDoorsAndClock();
+ || (index >= kObjectCompartmentA && index <= kObjectCompartmentF)) {
+ getScenes()->updateDoorsAndClock();
}
+ }
}
void Objects::updateLocation2(ObjectIndex index, ObjectLocation location2) {
diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h
index 361957227e..257c005e4a 100644
--- a/engines/lastexpress/game/savegame.h
+++ b/engines/lastexpress/game/savegame.h
@@ -167,7 +167,7 @@ public:
bool isGameFinished(uint32 menuIndex, uint32 savegameIndex);
// Accessors
- uint32 getTime(uint32 index) { return getEntry(index)->time; }
+ uint32 getTime(uint32 index) { return getEntry(index)->time; }
ChapterIndex getChapter(uint32 index) { return getEntry(index)->chapter; }
uint32 getValue(uint32 index) { return getEntry(index)->value; }
uint32 getLastSavegameTicks() const { return _gameTicksLastSavegame; }
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index 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..83d528d346 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;
@@ -656,12 +657,12 @@ private:
// Timer
int _timer;
- Flags *_flags; ///< Flags
- Inventory *_inventory; ///< Inventory
- Objects *_objects; ///< Objects
- SavePoints *_savepoints; ///< SavePoints
- GameState *_state; ///< State
- Common::Point _coords; ///< Current coordinates
+ Flags *_flags; ///< Flags
+ Inventory *_inventory; ///< Inventory
+ Objects *_objects; ///< Objects
+ SavePoints *_savepoints; ///< SavePoints
+ GameState *_state; ///< State
+ Common::Point _coords; ///< Current coordinates
};
} // End of namespace LastExpress
diff --git a/engines/lastexpress/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/configure.engine b/engines/lure/configure.engine
new file mode 100644
index 0000000000..e9f92893e3
--- /dev/null
+++ b/engines/lure/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine lure "Lure of the Temptress" yes
diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp
index 3fbbf84469..92f07a566e 100644
--- a/engines/lure/debugger.cpp
+++ b/engines/lure/debugger.cpp
@@ -337,11 +337,11 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {
} else if (strcmp(argv[2], "activate") == 0) {
// Activate the hotspot
res.activateHotspot(hs->hotspotId);
- hs->flags &= !HOTSPOTFLAG_MENU_EXCLUSION;
+ hs->flags &= ~HOTSPOTFLAG_MENU_EXCLUSION;
DebugPrintf("Activated\n");
} else if (strcmp(argv[2], "deactivate") == 0) {
- // Activate the hotspot
+ // Deactivate the hotspot
res.deactivateHotspot(hs->hotspotId);
hs->flags |= HOTSPOTFLAG_MENU_EXCLUSION;
DebugPrintf("Deactivated\n");
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/lure/menu.cpp b/engines/lure/menu.cpp
index 93deecdcd6..7564ce91a0 100644
--- a/engines/lure/menu.cpp
+++ b/engines/lure/menu.cpp
@@ -47,6 +47,7 @@ MenuRecord::MenuRecord(const MenuRecordBounds *bounds, int numParams, ...) {
va_start(params, numParams);
for (int index = 0; index < _numEntries; ++index)
_entries[index] = va_arg(params, const char *);
+ va_end(params);
// Store position data
_hsxstart = bounds->left; _hsxend = bounds->right;
@@ -458,7 +459,7 @@ Action PopupMenu::Show(int numEntries, Action *actions) {
strList[index] = stringList.getString(*actionPtr++);
uint16 result = Show(numEntries, strList);
- delete strList;
+ Memory::dealloc(strList);
if (result == 0xffff) return NONE;
else return actions[result];
}
diff --git a/engines/made/configure.engine b/engines/made/configure.engine
new file mode 100644
index 0000000000..2266712338
--- /dev/null
+++ b/engines/made/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine made "MADE" yes
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index e8b755cb40..c2c866ff34 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -211,77 +211,77 @@ static const MadeGameDescription gameDescriptions[] = {
3,
},
- {
- // Return to Zork - Italian CD version 1.2 3/31/95 (installed)
+ {
+ // Return to Zork - Italian CD version 1.2 3/31/95 (installed)
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, installed, CD",
- AD_ENTRY1s("rtzcd.dat", "5b86035aed0277f96e3d173542b5364a", 523776),
- Common::IT_ITA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, installed, CD",
+ AD_ENTRY1s("rtzcd.dat", "5b86035aed0277f96e3d173542b5364a", 523776),
+ Common::IT_ITA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD,
- 3,
- },
+ },
+ GID_RTZ,
+ 0,
+ GF_CD,
+ 3,
+ },
{
- // Return to Zork - Italian CD version 1.2 3/31/95
+ // Return to Zork - Italian CD version 1.2 3/31/95
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, CD",
- AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354971),
- Common::IT_ITA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, CD",
+ AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354971),
+ Common::IT_ITA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD_COMPRESSED,
- 3,
- },
-
- {
- // Return to Zork - French CD version 1.2 5/13/95 (installed)
+ },
+ GID_RTZ,
+ 0,
+ GF_CD_COMPRESSED,
+ 3,
+ },
+
+ {
+ // Return to Zork - French CD version 1.2 5/13/95 (installed)
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 5/13/95, installed, CD",
- AD_ENTRY1s("rtzcd.dat", "bde8251a8e34e87c54e3f93147d56c9e", 523776),
- Common::FR_FRA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 5/13/95, installed, CD",
+ AD_ENTRY1s("rtzcd.dat", "bde8251a8e34e87c54e3f93147d56c9e", 523776),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD,
- 3,
- },
-
- {
- // Return to Zork - French CD version 1.2 5/13/95
+ },
+ GID_RTZ,
+ 0,
+ GF_CD,
+ 3,
+ },
+
+ {
+ // Return to Zork - French CD version 1.2 5/13/95
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, CD",
- AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354614),
- Common::FR_FRA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, CD",
+ AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354614),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD_COMPRESSED,
- 3,
- },
+ },
+ GID_RTZ,
+ 0,
+ GF_CD_COMPRESSED,
+ 3,
+ },
{
// Return to Zork - English floppy version
diff --git a/engines/made/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/made.cpp b/engines/made/made.cpp
index 3843040961..3e192cb04c 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -85,7 +85,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_script = new ScriptInterpreter(this);
- _music = new MusicPlayer();
+ _music = nullptr;
// Set default sound frequency
switch (getGameID()) {
@@ -102,8 +102,6 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
// Return to Zork sets it itself via a script funtion
break;
}
-
- syncSoundSettings();
}
MadeEngine::~MadeEngine() {
@@ -277,6 +275,8 @@ void MadeEngine::handleEvents() {
}
Common::Error MadeEngine::run() {
+ _music = new MusicPlayer();
+ syncSoundSettings();
// Initialize backend
initGraphics(320, 200, false);
diff --git a/engines/made/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..b89b3af802 100644
--- a/engines/made/screenfx.cpp
+++ b/engines/made/screenfx.cpp
@@ -165,7 +165,7 @@ void ScreenEffects::flash(int flashCount, byte *palette, int colorCount) {
_screen->setRGBPalette(_fxPalette, 0, colorCount);
_screen->updateScreenAndWait(20);
_screen->setRGBPalette(palette, 0, colorCount);
- _screen->updateScreenAndWait(20);
+ _screen->updateScreenAndWait(20);
}
}
@@ -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/made/sound.cpp b/engines/made/sound.cpp
index f73c580560..176f8688bd 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -228,7 +228,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
break;
default:
- return;
+ return;
}
diff --git a/engines/mohawk/POTFILES b/engines/mohawk/POTFILES
new file mode 100644
index 0000000000..54d9dcaa3a
--- /dev/null
+++ b/engines/mohawk/POTFILES
@@ -0,0 +1,3 @@
+engines/mohawk/dialogs.cpp
+engines/mohawk/myst.cpp
+engines/mohawk/riven.cpp
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/configure.engine b/engines/mohawk/configure.engine
new file mode 100644
index 0000000000..fa9d15cffc
--- /dev/null
+++ b/engines/mohawk/configure.engine
@@ -0,0 +1,6 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
+add_engine cstime "Where in Time is Carmen Sandiego?" no
+add_engine riven "Riven: The Sequel to Myst" no "" "" "16bit"
+add_engine myst "Myst" no "" "" "16bit"
diff --git a/engines/mohawk/cstime.cpp b/engines/mohawk/cstime.cpp
index 3f9827581b..0f69d50a22 100644
--- a/engines/mohawk/cstime.cpp
+++ b/engines/mohawk/cstime.cpp
@@ -51,6 +51,15 @@ MohawkEngine_CSTime::MohawkEngine_CSTime(OSystem *syst, const MohawkGameDescript
_state = kCSTStateStartup;
reset();
+
+ _console = 0;
+ _gfx = 0;
+ _cursor = 0;
+ _interface = 0;
+ _view = 0;
+ _needsUpdate = false;
+ _case = 0;
+ _nextSceneId = 1;
}
MohawkEngine_CSTime::~MohawkEngine_CSTime() {
diff --git a/engines/mohawk/cstime_game.cpp b/engines/mohawk/cstime_game.cpp
index 2e21111025..91d2f895c0 100644
--- a/engines/mohawk/cstime_game.cpp
+++ b/engines/mohawk/cstime_game.cpp
@@ -1094,7 +1094,7 @@ void CSTimeScene::idleAmbientAnims() {
bool CSTimeScene::eventIsActive() {
return _vm->NISIsRunning() /* TODO || _vm->soundIsPlaying()*/ || _vm->getCurrentEventType() == kCSTimeEventWaitForClick
- || _activeChar->_flappingState != 0xffff || _vm->getInterface()->getState() == 4;
+ || _activeChar->_flappingState != 0xffff || _vm->getInterface()->getState() == kCSTimeInterfaceDroppedInventory;
}
void CSTimeScene::cursorOverHotspot(uint id) {
diff --git a/engines/mohawk/cstime_ui.cpp b/engines/mohawk/cstime_ui.cpp
index de7d5bde80..6d5e5dd3ef 100644
--- a/engines/mohawk/cstime_ui.cpp
+++ b/engines/mohawk/cstime_ui.cpp
@@ -854,7 +854,7 @@ void CSTimeInterface::dropItemInInventory(uint16 id) {
clearDialogArea();
_inventoryDisplay->show();
_inventoryDisplay->draw();
- _inventoryDisplay->setState(4);
+ _inventoryDisplay->setState(kCSTimeInterfaceDroppedInventory);
}
CSTimeHelp::CSTimeHelp(MohawkEngine_CSTime *vm) : _vm(vm) {
diff --git a/engines/mohawk/cstime_ui.h b/engines/mohawk/cstime_ui.h
index 27df7cac3e..3154d4b2ef 100644
--- a/engines/mohawk/cstime_ui.h
+++ b/engines/mohawk/cstime_ui.h
@@ -167,7 +167,8 @@ protected:
enum CSTimeInterfaceState {
kCSTimeInterfaceStateNormal = 1,
kCSTimeInterfaceStateDragStart = 2,
- kCSTimeInterfaceStateDragging = 3
+ kCSTimeInterfaceStateDragging = 3,
+ kCSTimeInterfaceDroppedInventory = 4
};
class CSTimeInterface {
diff --git a/engines/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 f80dbfacbd..634ff441b6 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -148,16 +148,10 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa
const Common::FSNode gameDataDir(ConfMan.get("path"));
// Rugrats
- const Common::FSNode ProgPath = gameDataDir.getChild("program");
- if (ProgPath.exists())
- SearchMan.addDirectory(ProgPath.getPath(), ProgPath, 0, 2);
- const Common::FSNode RugPath = gameDataDir.getChild("Rugrats Adventure Game");
- if (RugPath.exists())
- SearchMan.addDirectory(RugPath.getPath(), RugPath, 0, 2);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "program", 0, 2);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "Rugrats Adventure Game", 0, 2);
// CarmenTQ
- const Common::FSNode CTQPath = gameDataDir.getChild("95instal");
- if (CTQPath.exists())
- SearchMan.addDirectory(CTQPath.getPath(), CTQPath, 0, 4);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "95instal", 0, 4);
}
MohawkEngine_LivingBooks::~MohawkEngine_LivingBooks() {
@@ -317,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/configure.engine b/engines/mortevielle/configure.engine
new file mode 100644
index 0000000000..14d6479e7a
--- /dev/null
+++ b/engines/mortevielle/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mortevielle "Mortevielle" no
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..480b4381ef
--- /dev/null
+++ b/engines/mortevielle/mouse.cpp
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * 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() {
+ _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..90d1ef310e
--- /dev/null
+++ b/engines/mortevielle/mouse.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This 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;
+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..c4f2d5714b
--- /dev/null
+++ b/engines/mortevielle/utils.cpp
@@ -0,0 +1,3405 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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];
+ Common::strlcpy(tmp, s.c_str() + idx - 1, size + 1);
+
+ 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);
+ quest = keyPressed();
+ if (quest && shouldQuit())
+ return;
+ } 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/POTFILES b/engines/neverhood/POTFILES
new file mode 100644
index 0000000000..36628cf4dd
--- /dev/null
+++ b/engines/neverhood/POTFILES
@@ -0,0 +1,2 @@
+engines/neverhood/detection.cpp
+engines/neverhood/menumodule.cpp
diff --git a/engines/neverhood/background.cpp b/engines/neverhood/background.cpp
index 0a80bd8390..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() {
@@ -45,7 +45,7 @@ Background::~Background() {
}
void Background::createSurface(int surfacePriority, int16 width, int16 height) {
- _surface = new BaseSurface(_vm, surfacePriority, width, height);
+ _surface = new BaseSurface(_vm, surfacePriority, width, height, "background");
_surface->setTransparent(false);
_spriteResource.getPosition().x = width;
_spriteResource.getPosition().y = height;
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index 9f5f46487c..c743037e63 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)
@@ -131,7 +131,8 @@ void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) {
break;
case 3: // DCL-compressed
if (!Common::decompressDCL(&_fd, buffer, entry->diskSize, entry->size))
- error("BlbArchive::load() Error during decompression of %08X", entry->fileHash);
+ error("BlbArchive::load() Error during decompression of %08X (offset: %d, disk size: %d, size: %d)",
+ entry->fileHash, entry->offset, entry->diskSize, entry->size);
break;
default:
error("BlbArchive::load() Unknown compression type %d", entry->comprType);
diff --git a/engines/neverhood/configure.engine b/engines/neverhood/configure.engine
new file mode 100644
index 0000000000..0767a631f9
--- /dev/null
+++ b/engines/neverhood/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine neverhood "Neverhood" no
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
new file mode 100644
index 0000000000..34438d821f
--- /dev/null
+++ b/engines/neverhood/console.cpp
@@ -0,0 +1,269 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/console.h"
+#include "gui/debugger.h"
+#include "neverhood/neverhood.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/navigationscene.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerscene.h"
+#include "neverhood/sound.h"
+#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module3000_sprites.h"
+
+namespace Neverhood {
+
+Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("cheat", WRAP_METHOD(Console, Cmd_Cheat));
+ DCmd_Register("checkresource", WRAP_METHOD(Console, Cmd_CheckResource));
+ DCmd_Register("dumpresource", WRAP_METHOD(Console, Cmd_DumpResource));
+ DCmd_Register("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars));
+ DCmd_Register("playsound", WRAP_METHOD(Console, Cmd_PlaySound));
+ DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene));
+ DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
+}
+
+Console::~Console() {
+}
+
+bool Console::Cmd_Scene(int argc, const char **argv) {
+ if (argc != 3) {
+ int currentModule = _vm->_gameModule->getCurrentModuleNum();
+ int previousModule = _vm->_gameModule->getPreviousModuleNum();
+ int scenenNum = _vm->gameState().sceneNum;
+ SceneType sceneType = ((GameModule *)_vm->_gameModule->_childObject)->getSceneType();
+
+ const char *sceneTypes[] = { "normal", "smacker", "navigation" };
+
+ DebugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
+
+ if (sceneType == kSceneTypeNormal) {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Normal scenes have a background and a cursor file hash
+ DebugPrintf("Background hash: 0x%x, cursor hash: 0x%x\n", scene->getBackgroundFileHash(), scene->getCursorFileHash());
+ } else if (sceneType == kSceneTypeSmacker) {
+ SmackerScene *scene = (SmackerScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Smacker scenes have a file hash, or a list of hashes
+ // TODO: Only the first file hash is shown - any additional hashes, found in
+ // scenes with a list of hashes (two scenes in module 1100 and the making of
+ // video) aren't shown yet
+ DebugPrintf("File hash: 0x%x\n", scene->getSmackerFileHash());
+ } else if (sceneType == kSceneTypeNavigation) {
+ NavigationScene *scene = (NavigationScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Navigation scenes have a navigation list and its index
+ NavigationList *navigationList = _vm->_staticData->getNavigationList(scene->getNavigationListId());
+ int navigationIndex = scene->getGlobalVar(V_NAVIGATION_INDEX);
+ NavigationItem curNavigation = (*navigationList)[navigationIndex];
+ DebugPrintf("Navigation list ID: 0x%x, index: %d\n", scene->getNavigationListId(), navigationIndex);
+ DebugPrintf("File hash: 0x%x, cursor hash: 0x%x, Smacker hashes: [left: 0x%x, middle: 0x%x, right: 0x%x\n",
+ curNavigation.fileHash, curNavigation.mouseCursorFileHash,
+ curNavigation.leftSmackerFileHash, curNavigation.middleSmackerFileHash, curNavigation.rightSmackerFileHash);
+ }
+
+ DebugPrintf("Use %s <module> <scene> to change scenes\n", argv[0]);
+ DebugPrintf("Modules are incremental by 100, from 1000 to 3000\n");
+ } else {
+ int newModule = atoi(argv[1]);
+ int newScene = atoi(argv[2]);
+
+ _vm->gameState().sceneNum = newScene;
+ _vm->_gameModule->createModule(newModule, -1);
+ }
+
+ return true;
+}
+
+bool Console::Cmd_Surfaces(int argc, const char **argv) {
+ if (_vm->_gameModule->_childObject) {
+ ((Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject)->printSurfaces(this);
+ }
+ return true;
+}
+
+bool Console::Cmd_Cheat(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Cheats for various puzzles in the game\n");
+ DebugPrintf("Use %s <cheatname> to use a cheat.\n", argv[0]);
+ DebugPrintf("Cheats:\n-------\n");
+ DebugPrintf(" buttons - enables all 3 buttons on the door in the purple building, module 3000, scene 9\n");
+ DebugPrintf(" cannon - sets the correct cannon combination in module 3000, scene 8\n");
+ DebugPrintf(" dice - shows the correct dice combination in the teddy bear puzzle, module 1100, scene 6\n");
+ DebugPrintf(" memory - solves the memory puzzle, module 1400, scene 4\n");
+ 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");
+ return true;
+ }
+
+ Common::String cheatName = argv[1];
+ int moduleNum = _vm->_gameModule->getCurrentModuleNum();
+ int sceneNum = _vm->gameState().sceneNum;
+
+ if (cheatName == "buttons") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+
+ scene->setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 1); // kScene3010ButtonNameHashes[0]
+ scene->setSubVar(VA_LOCKS_DISABLED, 0x40119852, 1); // kScene3010ButtonNameHashes[1]
+ scene->setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1); // kScene3010ButtonNameHashes[2]
+
+ DebugPrintf("All 3 door buttons have been enabled\n");
+ } else if (cheatName == "cannon") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+
+ for (int i = 0; i < 3; i++)
+ scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_1, i));
+
+ for (int i = 3; i < 6; i++)
+ scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_2, i - 3));
+
+ DebugPrintf("Puzzle solved\n");
+ } else if (cheatName == "dice") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ DebugPrintf("Good: (%d %d %d), current: (%d %d %d)\n",
+ scene->getSubVar(VA_GOOD_DICE_NUMBERS, 0), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 1), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 2),
+ scene->getSubVar(VA_CURR_DICE_NUMBERS, 0), scene->getSubVar(VA_CURR_DICE_NUMBERS, 1), scene->getSubVar(VA_CURR_DICE_NUMBERS, 2)
+ );
+ } else if (cheatName == "memory") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+
+ // Autosolve all tiles and leave only two matching tiles closed
+ for (int i = 0; i < 48; i++)
+ scene->setSubVar(VA_IS_TILE_MATCH, i, 1);
+
+ // Close the top left tile
+ scene->setSubVar(VA_IS_TILE_MATCH, 0, 0);
+
+ // Find and close the pair of the top left tile
+ for (int i = 0; i < 48; i++) {
+ if (i != 0 && scene->getSubVar(VA_TILE_SYMBOLS, i) == scene->getSubVar(VA_TILE_SYMBOLS, 0)) {
+ scene->setSubVar(VA_IS_TILE_MATCH, i, 0);
+ break;
+ }
+ }
+
+ DebugPrintf("Puzzle solved\n");
+ } else if (cheatName == "music") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ DebugPrintf("Good music index: %d, current radio music index: %d\n", scene->getGlobalVar(V_CURR_RADIO_MUSIC_INDEX), scene->getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX));
+ } else if (cheatName == "radio") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ scene->setGlobalVar(V_RADIO_ENABLED, 1);
+
+ DebugPrintf("The radio has been enabled\n");
+ } else if (cheatName == "symbols") {
+ if (moduleNum == 1600 && sceneNum == 8) {
+ Scene1609 *scene = ((Scene1609 *)((Module1600 *)_vm->_gameModule->_childObject)->_childObject);
+
+ for (int index = 0; index < 12; index++) {
+ scene->_asSymbols[index]->change((int)scene->getSubVar(VA_CODE_SYMBOLS, index) + 12, index == (int)scene->getSubVar(VA_CODE_SYMBOLS, scene->_noisySymbolIndex));
+ }
+
+ scene->_changeCurrentSymbol = false;
+ scene->_symbolPosition = 11;
+ scene->_countdown1 = 36;
+
+ DebugPrintf("Puzzle solved\n");
+ } else {
+ DebugPrintf("Only available in module 1600, scene 8\n");
+ }
+ } else if (cheatName == "tubes") {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ DebugPrintf("Tube set 1: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2));
+ DebugPrintf("Tube set 2: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2));
+ }
+
+ return true;
+}
+
+bool Console::Cmd_Dumpvars(int argc, const char **argv) {
+ _vm->_gameVars->dumpVars(this);
+
+ return true;
+}
+
+bool Console::Cmd_PlaySound(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Usage: %s <sound hash>\n", argv[0]);
+ } else {
+ uint32 soundHash = strtol(argv[1], NULL, 0);
+ AudioResourceManSoundItem *soundItem = new AudioResourceManSoundItem(_vm, soundHash);
+ soundItem->setVolume(100);
+ soundItem->playSound(false);
+ while (soundItem->isPlaying()) {
+ _vm->_system->delayMillis(10);
+ }
+ delete soundItem;
+ }
+
+ return true;
+}
+
+bool Console::Cmd_CheckResource(int argc, const char **argv) {
+ const char *resourceNames[] = { "unknown", "unknown", "bitmap", "palette", "animation", "data", "text", "sound", "music", "unknown", "video" };
+
+ if (argc < 2) {
+ DebugPrintf("Gets information about a resource\n");
+ DebugPrintf("Usage: %s <resource hash>\n", argv[0]);
+ } else {
+ uint32 resourceHash = strtol(argv[1], NULL, 0);
+ ResourceHandle handle;
+
+ _vm->_res->queryResource(resourceHash, handle);
+ if (!handle.isValid()) {
+ DebugPrintf("Invalid resource hash\n");
+ } else {
+ DebugPrintf("Resource type: %d (%s). Size: %d bytes\n", handle.type(), resourceNames[handle.type()], handle.size());
+ }
+ }
+
+ return true;
+}
+
+bool Console::Cmd_DumpResource(int argc, const char **argv) {
+ if (argc < 3) {
+ DebugPrintf("Dumps a resource to disk\n");
+ DebugPrintf("Usage: %s <resource hash> <output file>\n", argv[0]);
+ } else {
+ uint32 resourceHash = strtol(argv[1], NULL, 0);
+ const char *outFileName = argv[2];
+ ResourceHandle handle;
+
+ _vm->_res->queryResource(resourceHash, handle);
+ if (!handle.isValid()) {
+ DebugPrintf("Invalid resource hash\n");
+ } else {
+ _vm->_res->loadResource(handle, _vm->applyResourceFixes());
+ Common::DumpFile outFile;
+ outFile.open(outFileName);
+ outFile.write(handle.data(), handle.size());
+ outFile.finalize();
+ outFile.close();
+ _vm->_res->unloadResource(handle);
+ }
+ }
+
+ return true;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/console.h b/engines/neverhood/console.h
new file mode 100644
index 0000000000..70260a96af
--- /dev/null
+++ b/engines/neverhood/console.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_CONSOLE_H
+#define NEVERHOOD_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Neverhood {
+
+class NeverhoodEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(NeverhoodEngine *vm);
+ virtual ~Console(void);
+
+private:
+ NeverhoodEngine *_vm;
+
+ bool Cmd_Scene(int argc, const char **argv);
+ bool Cmd_Surfaces(int argc, const char **argv);
+ bool Cmd_Cheat(int argc, const char **argv);
+ bool Cmd_Dumpvars(int argc, const char **argv);
+ bool Cmd_PlaySound(int argc, const char **argv);
+ bool Cmd_CheckResource(int argc, const char **argv);
+ bool Cmd_DumpResource(int argc, const char **argv);
+
+};
+
+} // End of namespace Neverhood
+#endif
diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp
index 5f860f8519..e5486bbcf5 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -24,6 +24,7 @@
#include "engines/advancedDetector.h"
#include "common/file.h"
+#include "common/translation.h"
#include "neverhood/neverhood.h"
@@ -51,6 +52,10 @@ Common::Platform NeverhoodEngine::getPlatform() const {
return _gameDescription->desc.platform;
}
+Common::Language NeverhoodEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
uint16 NeverhoodEngine::getVersion() const {
return _gameDescription->version;
}
@@ -59,6 +64,10 @@ bool NeverhoodEngine::isDemo() const {
return _gameDescription->desc.flags & ADGF_DEMO;
}
+bool NeverhoodEngine::applyResourceFixes() const {
+ return getLanguage() == Common::RU_RUS;
+}
+
}
static const PlainGameDescriptor neverhoodGames[] = {
@@ -143,6 +152,20 @@ static const NeverhoodGameDescription gameDescriptions[] = {
} // End of namespace Neverhood
+static const ExtraGuiOption neverhoodExtraGuiOption1 = {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+};
+
+static const ExtraGuiOption neverhoodExtraGuiOption2 = {
+ _s("Skip the Hall of Records storyboard scenes"),
+ _s("Allows the player to skip past the Hall of Records storyboard scenes"),
+ "skiphallofrecordsscenes",
+ false
+};
+
class NeverhoodMetaEngine : public AdvancedMetaEngine {
public:
NeverhoodMetaEngine() : AdvancedMetaEngine(Neverhood::gameDescriptions, sizeof(Neverhood::NeverhoodGameDescription), neverhoodGames) {
@@ -160,7 +183,7 @@ public:
virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-
+ virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -173,7 +196,7 @@ bool NeverhoodMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsListSaves) ||
(f == kSupportsLoadingDuringStartup) ||
(f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail) ||
(f == kSavesSupportCreationDate) ||
(f == kSavesSupportPlayTime);
@@ -194,6 +217,13 @@ bool NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const A
return gd != 0;
}
+const ExtraGuiOptions NeverhoodMetaEngine::getExtraGuiOptions(const Common::String &target) const {
+ ExtraGuiOptions options;
+ options.push_back(neverhoodExtraGuiOption1);
+ options.push_back(neverhoodExtraGuiOption2);
+ return options;
+}
+
SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Neverhood::NeverhoodEngine::SaveHeader header;
diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp
index d972943759..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;
@@ -354,16 +354,14 @@ DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int
insertPuzzleMouse(0x000408A8, 20, 620);
showMouse(false);
- _diskSmackerPlayer = new SmackerPlayer(_vm, this, 0x08288103, false, true);
- addEntity(_diskSmackerPlayer);
- addSurface(_diskSmackerPlayer->getSurface());
+ _diskSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08288103, false, true));
_diskSmackerPlayer->setDrawPos(154, 86);
_vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
_palette->usePalette();
- SetMessageHandler(&DiskplayerScene::handleMessage);
- SetUpdateHandler(&DiskplayerScene::update);
+ SetMessageHandler(&DiskplayerScene::handleMessage);
+ SetUpdateHandler(&DiskplayerScene::update);
_appearCountdown = 6;
}
@@ -419,7 +417,7 @@ void DiskplayerScene::update() {
}
_diskIndex++;
while (!_diskAvailable[_diskIndex] && _diskIndex < 19)
- _diskIndex++;
+ _diskIndex++;
if (_diskIndex < 20) {
_appearCountdown = 1;
} else {
@@ -450,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();
@@ -464,45 +462,43 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
break;
case 0x2000:
tuneIn();
- break;
+ break;
case 0x2001:
stop();
- break;
+ break;
}
}
return 0;
}
-void DiskplayerScene::stop() {
- _diskSmackerPlayer->open(0x08288103, true);
+void DiskplayerScene::openSmacker(uint32 fileHash, bool keepLastFrame) {
+ _diskSmackerPlayer->open(fileHash, keepLastFrame);
_vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
_palette->usePalette();
+}
+
+void DiskplayerScene::stop() {
+ openSmacker(0x08288103, true);
_ssPlayButton->release();
_updateStatus = kUSStopped;
_diskSlots[_diskIndex]->activate();
}
void DiskplayerScene::tuneIn() {
- _diskSmackerPlayer->open(0x900001C1, false);
- _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
- _palette->usePalette();
+ openSmacker(0x900001C1, false);
_ssPlayButton->release();
_updateStatus = kUSTuningIn;
_diskSlots[_diskIndex]->activate();
}
void DiskplayerScene::playDisk() {
- _diskSmackerPlayer->open(kDiskplayerSmackerFileHashes[_diskIndex], false);
- _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
- _palette->usePalette();
+ openSmacker(kDiskplayerSmackerFileHashes[_diskIndex], false);
_updateStatus = kUSPlaying;
_diskSlots[_diskIndex]->play();
}
void DiskplayerScene::playStatic() {
- _diskSmackerPlayer->open(0x90000101, false);
- _vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
- _palette->usePalette();
+ openSmacker(0x90000101, false);
_ssPlayButton->release();
_updateStatus = kUSPlaying;
_diskSlots[_diskIndex]->activate();
diff --git a/engines/neverhood/diskplayerscene.h b/engines/neverhood/diskplayerscene.h
index f3fd9ea874..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 {
@@ -99,6 +99,7 @@ protected:
bool _dropKey;
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void openSmacker(uint32 fileHash, bool keepLastFrame);
void stop();
void tuneIn();
void playDisk();
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 fb8941ae43..5c29bf8a4f 100644
--- a/engines/neverhood/entity.h
+++ b/engines/neverhood/entity.h
@@ -60,14 +60,18 @@ protected:
// TODO: Disable heavy debug stuff in release mode
#define SetUpdateHandler(handler) \
- _updateHandlerCb = static_cast <void (Entity::*)(void)> (handler); \
- debug(5, "SetUpdateHandler(" #handler ")"); \
- _updateHandlerCbName = #handler
+ do { \
+ _updateHandlerCb = static_cast <void (Entity::*)(void)> (handler); \
+ debug(5, "SetUpdateHandler(" #handler ")"); \
+ _updateHandlerCbName = #handler; \
+ } while (0)
#define SetMessageHandler(handler) \
- _messageHandlerCb = static_cast <uint32 (Entity::*)(int messageNum, const MessageParam &param, Entity *sender)> (handler); \
- debug(5, "SetMessageHandler(" #handler ")"); \
- _messageHandlerCbName = #handler
+ do { \
+ _messageHandlerCb = static_cast <uint32 (Entity::*)(int messageNum, const MessageParam &param, Entity *sender)> (handler); \
+ debug(5, "SetMessageHandler(" #handler ")"); \
+ _messageHandlerCbName = #handler; \
+ } while (0)
const uint kMaxSoundResources = 16;
@@ -94,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 49682b0d29..699df2ae7d 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++)
@@ -194,21 +194,6 @@ void GameModule::initMemoryPuzzle() {
tileSymbolIndex = 0;
}
setSubVar(VA_IS_PUZZLE_INIT, 0xC8606803, 1);
-
- // DEBUG Enable to autosolve all tiles and leave only two matching tiles open
-#if 0
- for (int i = 0; i < 48; i++)
- setSubVar(VA_IS_TILE_MATCH, i, 1);
- int debugIndex = 0;
- setSubVar(VA_IS_TILE_MATCH, debugIndex, 0);
- for (int i = 0; i < 48; i++) {
- if (i != debugIndex && getSubVar(VA_TILE_SYMBOLS, i) == getSubVar(VA_TILE_SYMBOLS, debugIndex)) {
- setSubVar(VA_IS_TILE_MATCH, i, 0);
- break;
- }
- }
-#endif
-
}
}
@@ -231,7 +216,7 @@ void GameModule::initRadioPuzzle() {
setGlobalVar(V_RADIO_ROOM_LEFT_DOOR, 1);
setGlobalVar(V_RADIO_ROOM_RIGHT_DOOR, 0);
setSubVar(VA_IS_PUZZLE_INIT, 0x08C80800, 1);
- }
+ }
}
void GameModule::initTestTubes1Puzzle() {
@@ -335,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;
}
@@ -426,6 +411,10 @@ void GameModule::checkRequests() {
}
if (_restoreGameRequested) {
_restoreGameRequested = false;
+ _vm->_audioResourceMan->stopAllMusic();
+ _vm->_audioResourceMan->stopAllSounds();
+ _vm->_soundMan->stopAllMusic();
+ _vm->_soundMan->stopAllSounds();
delete _childObject;
delete _prevChildObject;
_childObject = NULL;
@@ -438,8 +427,11 @@ void GameModule::checkRequests() {
}
void GameModule::createModule(int moduleNum, int which) {
- debug("GameModule::createModule(%d, %d)", moduleNum, which);
+ debug(1, "GameModule::createModule(%d, %d)", moduleNum, which);
_moduleNum = moduleNum;
+
+ delete _childObject;
+
switch (_moduleNum) {
case 1000:
setGlobalVar(V_MODULE_NAME, 0x03294419);
@@ -539,7 +531,7 @@ void GameModule::createModule(int moduleNum, int which) {
}
void GameModule::createModuleByHash(uint32 nameHash) {
- debug("GameModule::createModuleByHash(%08X)", nameHash);
+ debug(1, "GameModule::createModuleByHash(%08X)", nameHash);
switch (nameHash) {
case 0x03294419:
createModule(1000, -1);
@@ -684,7 +676,7 @@ void GameModule::updateModule() {
createModule(2300, 1);
break;
case 2300:
- debug("module 23000 _moduleResult : %d", _moduleResult);
+ debug(1, "module 23000 _moduleResult : %d", _moduleResult);
if (_moduleResult == 2)
createModule(1200, 0);
else if (_moduleResult == 0)
@@ -796,6 +788,7 @@ void GameModule::openMainMenu() {
createModule(1000, 0);
}
_vm->_screen->saveParams();
+ _vm->_screen->update();
_mainMenuRequested = false;
createMenuModule();
}
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index 8101d38009..2f2fecf463 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -49,12 +49,16 @@ public:
void initWaterPipesPuzzle();
void initRadioPuzzle();
void initTestTubes1Puzzle();
- void initTestTubes2Puzzle();
+ void initTestTubes2Puzzle();
void initCannonSymbolsPuzzle();
void initCodeSymbolsPuzzle();
void initCubeSymbolsPuzzle();
void initCrystalColorsPuzzle();
uint32 getCurrRadioMusicFileHash();
+ int getCurrentModuleNum() { return _moduleNum; }
+ int getPreviousModuleNum() { return _moduleNum; }
+
+ void createModule(int moduleNum, int which);
protected:
int _moduleNum;
Entity *_prevChildObject;
@@ -64,7 +68,6 @@ protected:
bool _canRequestMainMenu;
bool _mainMenuRequested;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void createModule(int moduleNum, int which);
void createModuleByHash(uint32 nameHash);
void updateModule();
void openMainMenu();
diff --git a/engines/neverhood/gamevars.cpp b/engines/neverhood/gamevars.cpp
index 87f5fe6dd9..9c080fea24 100644
--- a/engines/neverhood/gamevars.cpp
+++ b/engines/neverhood/gamevars.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "neverhood/console.h"
#include "neverhood/gamevars.h"
namespace Neverhood {
@@ -74,7 +75,7 @@ uint32 GameVars::getSubVar(uint32 nameHash, uint32 subNameHash) {
int16 subVarIndex = findSubVarIndex(varIndex, subNameHash);
if (subVarIndex != -1)
value = _vars[subVarIndex].value;
- }
+ }
return value;
}
@@ -123,10 +124,10 @@ int16 GameVars::getSubVarIndex(int16 varIndex, uint32 subNameHash) {
return subVarIndex;
}
-void GameVars::dumpVars() {
+void GameVars::dumpVars(Console *con) {
for (Common::Array<GameVar>::iterator it = _vars.begin(); it != _vars.end(); ++it) {
GameVar gameVar = *it;
- debug("%08X %08X %3d %3d", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex);
+ con->DebugPrintf("hash: %08X, var: %08X, first index: %3d, next index: %3d\n", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex);
}
}
diff --git a/engines/neverhood/gamevars.h b/engines/neverhood/gamevars.h
index 5337c13394..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 {
@@ -169,6 +169,8 @@ struct GameVar {
int16 firstIndex, nextIndex;
};
+class Console;
+
class GameVars {
public:
GameVars();
@@ -179,7 +181,7 @@ public:
void setGlobalVar(uint32 nameHash, uint32 value);
uint32 getSubVar(uint32 nameHash, uint32 subNameHash);
void setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value);
- void dumpVars();
+ void dumpVars(Console *con);
protected:
Common::Array<GameVar> _vars;
int16 addVar(uint32 nameHash, uint32 value);
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 5099c7a00e..490959020f 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -26,10 +26,10 @@
namespace Neverhood {
-BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height)
+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) {
-
+ _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;
@@ -130,7 +130,7 @@ void BaseSurface::copyFrom(Graphics::Surface *sourceSurface, int16 x, int16 y, N
// ShadowSurface
ShadowSurface::ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, BaseSurface *shadowSurface)
- : BaseSurface(vm, priority, width, height), _shadowSurface(shadowSurface) {
+ : BaseSurface(vm, priority, width, height, "shadow"), _shadowSurface(shadowSurface) {
// Empty
}
@@ -143,18 +143,18 @@ void ShadowSurface::draw() {
// FontSurface
FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
- : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows), _charsPerRow(charsPerRow), _numRows(numRows),
+ : 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;
}
FontSurface::FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
- : BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows), _charsPerRow(charsPerRow), _numRows(numRows),
+ : 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;
@@ -343,7 +343,7 @@ void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, i
int calcDistance(int16 x1, int16 y1, int16 x2, int16 y2) {
const int16 deltaX = ABS(x1 - x2);
const int16 deltaY = ABS(y1 - y2);
- return sqrt((double)(deltaX * deltaX + deltaY * deltaY));
+ return (int)sqrt((double)(deltaX * deltaX + deltaY * deltaY));
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h
index a0ac1f09d5..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;
@@ -83,7 +85,7 @@ class MouseCursorResource;
class BaseSurface {
public:
- BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height);
+ BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name);
virtual ~BaseSurface();
virtual void draw();
void clear();
@@ -104,10 +106,12 @@ public:
void setVisible(bool value) { _visible = value; }
void setTransparent(bool value) { _transparent = value; }
Graphics::Surface *getSurface() { return _surface; }
+ const Common::String getName() const { return _name; }
protected:
NeverhoodEngine *_vm;
int _priority;
bool _visible;
+ Common::String _name;
Graphics::Surface *_surface;
NDrawRect _drawRect;
NDrawRect _sysRect;
diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp
index 06d606e18d..e1a0d72d50 100644
--- a/engines/neverhood/klaymen.cpp
+++ b/engines/neverhood/klaymen.cpp
@@ -33,31 +33,20 @@ 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},
- {1, kIdleChest},
- {1, kIdleHeadOff},
};
-static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
- {1, kIdlePickEar},
- {2, kIdleWonderAbout}
-};
-
// Klaymen
Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRectArray *clipRects)
@@ -65,8 +54,8 @@ Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRec
_isWalkingOpenDoorNotified(false), _spitOutCountdown(0), _tapesToInsert(0), _keysToInsert(0), _busyStatus(0), _acceptInput(true),
_attachedSprite(NULL), _isWalking(false), _actionStatus(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false),
_doYHitIncr(false), _isLeverDown(false), _isSittingInTeleporter(false), _actionStatusChanged(false), _ladderStatus(0), _pathPoints(NULL), _soundFlag(false),
- _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _readyToSpit(false), _walkResumeFrameIncr(0) {
-
+ _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _walkResumeFrameIncr(0) {
+
createSurface(1000, 320, 200);
_x = x;
_y = y;
@@ -311,7 +300,7 @@ void Klaymen::stSitIdleTeleporterBlink() {
void Klaymen::stSitIdleTeleporterBlinkSecond() {
_busyStatus = 0;
_acceptInput = true;
- startAnimation(0x5C24C018, 0, -1);
+ startAnimation(0x582EC138, 0, -1);
SetUpdateHandler(&Klaymen::upSitIdleTeleporter);
SetMessageHandler(&Klaymen::hmLowLevel);
SetSpriteUpdate(NULL);
@@ -434,7 +423,7 @@ void Klaymen::stopWalking() {
}
void Klaymen::startIdleAnimation(uint32 fileHash, AnimationCb callback) {
- debug("startIdleAnimation(%08X)", fileHash);
+ debug(1, "startIdleAnimation(%08X)", fileHash);
NextState(callback);
SetUpdateHandler(&Klaymen::upIdleAnimation);
}
@@ -447,7 +436,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);
@@ -628,36 +617,6 @@ void Klaymen::startWalkToX(int16 x, bool walkExt) {
}
}
-void Klaymen::stWakeUp() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x527AC970, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stSleeping() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x5A38C110, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSleeping);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x03060012) {
- playSound(0, 0xC0238244);
- }
- break;
- }
- return messageResult;
-}
-
bool Klaymen::stStartAction(AnimationCb callback3) {
if (_busyStatus == 1) {
_busyStatus = 2;
@@ -684,35 +643,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 +679,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 +708,7 @@ void Klaymen::suSneaking() {
}
updateBounds();
}
-
+
}
void Klaymen::stSneak() {
@@ -761,7 +720,7 @@ void Klaymen::stSneak() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmSneaking);
SetSpriteUpdate(&Klaymen::suSneaking);
- FinalizeState(&Klaymen::evSneakingDone);
+ FinalizeState(&Klaymen::evSneakingDone);
}
void Klaymen::evSneakingDone() {
@@ -801,7 +760,7 @@ void Klaymen::stStartWalking() {
SetMessageHandler(&Klaymen::hmStartWalking);
SetSpriteUpdate(&Klaymen::suWalkingTestExit);
NextState(&Klaymen::stWalkingFirst);
- FinalizeState(&Klaymen::evStartWalkingDone);
+ FinalizeState(&Klaymen::evStartWalkingDone);
}
}
@@ -832,7 +791,7 @@ void Klaymen::stWalkingFirst() {
SetMessageHandler(&Klaymen::hmWalking);
SetSpriteUpdate(&Klaymen::suWalkingFirst);
NextState(&Klaymen::stUpdateWalkingFirst);
- FinalizeState(&Klaymen::evStartWalkingDone);
+ FinalizeState(&Klaymen::evStartWalkingDone);
}
void Klaymen::suWalkingFirst() {
@@ -882,20 +841,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 +887,7 @@ void Klaymen::suWalkingTestExit() {
}
updateBounds();
}
-
+
}
uint32 Klaymen::hmLever(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1363,7 +1322,7 @@ void Klaymen::stLargeStep() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLargeStep);
SetSpriteUpdate(&Klaymen::suLargeStep);
- FinalizeState(&Klaymen::evLargeStepDone);
+ FinalizeState(&Klaymen::evLargeStepDone);
}
void Klaymen::evLargeStepDone() {
@@ -1372,11 +1331,11 @@ void Klaymen::evLargeStepDone() {
void Klaymen::suLargeStep() {
int16 xdiff = _destX - _x;
-
+
if (_doDeltaX) {
_deltaX = -_deltaX;
}
-
+
if (_currFrameIndex == 7) {
_deltaX = xdiff;
}
@@ -1385,7 +1344,7 @@ void Klaymen::suLargeStep() {
xdiff = _deltaX;
_deltaX = 0;
-
+
if (_x != _destX) {
HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y);
_x += xdiff;
@@ -1420,7 +1379,7 @@ uint32 Klaymen::hmLargeStep(int messageNum, const MessageParam &param, Entity *s
case 0x3002:
_x = _destX;
gotoNextStateExt();
- break;
+ break;
}
return messageResult;
}
@@ -1512,112 +1471,11 @@ uint32 Klaymen::hmPeekWall(int messageNum, const MessageParam &param, Entity *se
return hmLowLevelAnimation(messageNum, param, sender);
}
-void Klaymen::stJumpToRing1() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing1))) {
- _busyStatus = 0;
- startAnimation(0xD82890BA, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::setupJumpToRing() {
- _acceptInput = false;
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRing);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- NextState(&Klaymen::stHangOnRing);
- sendMessage(_attachedSprite, 0x482B, 0);
-}
-
-uint32 Klaymen::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- _acceptInput = true;
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suUpdateDestX() {
AnimatedSprite::updateDeltaXY();
_destX = _x;
}
-void Klaymen::stHangOnRing() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4829E0B8, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stJumpToRing2() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing2))) {
- _busyStatus = 0;
- startAnimation(0x900980B2, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::stJumpToRing3() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing3))) {
- _busyStatus = 0;
- _acceptInput = false;
- startAnimation(0xBA1910B2, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- SetMessageHandler(&Klaymen::hmJumpToRing3);
- NextState(&Klaymen::stHoldRing3);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
-uint32 Klaymen::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHoldRing3() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4A293FB0, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHoldRing3);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
- if (messageNum == 0x1008) {
- stReleaseRing();
- return 0;
- }
- return hmLowLevel(messageNum, param, sender);
-}
-
void Klaymen::stReleaseRing() {
_busyStatus = 1;
_acceptInput = false;
@@ -1629,14 +1487,6 @@ void Klaymen::stReleaseRing() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stJumpToRing4() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing4))) {
- _busyStatus = 0;
- startAnimation(0xB8699832, 0, -1);
- setupJumpToRing();
- }
-}
-
void Klaymen::startWalkToAttachedSpriteXDistance(int16 distance) {
startWalkToXDistance(_attachedSprite->getX(), distance);
}
@@ -1681,7 +1531,7 @@ void Klaymen::stStartClimbLadderDown() {
_ladderStatus = 2;
_acceptInput = true;
startAnimation(0x122D1505, 29 - _currFrameIndex, -1);
- }
+ }
}
}
@@ -1885,29 +1735,6 @@ uint32 Klaymen::hmTurnToBackToUse(int messageNum, const MessageParam &param, Ent
return messageResult;
}
-void Klaymen::stClayDoorOpen() {
- if (!stStartAction(AnimationCallback(&Klaymen::stClayDoorOpen))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x5CCCB330, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmClayDoorOpen);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- }
-}
-
-uint32 Klaymen::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x040D4186) {
- sendMessage(_attachedSprite, 0x4808, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stTurnToUse() {
if (!stStartAction(AnimationCallback(&Klaymen::stTurnToUse))) {
_busyStatus = 2;
@@ -1979,7 +1806,7 @@ uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Enti
break;
case 0x480A:
_isMoveObjectRequested = true;
- return 0;
+ return 0;
}
return hmLowLevelAnimation(messageNum, param, sender);
}
@@ -2336,29 +2163,6 @@ uint32 Klaymen::hmTeleporterAppearDisappear(int messageNum, const MessageParam &
return messageResult;
}
-uint32 Klaymen::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x80C110B5)
- sendMessage(_parentScene, 0x482A, 0);
- else if (param.asInteger() == 0x33288344)
- playSound(2, 0x10688664);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stShrink() {
- _busyStatus = 0;
- _acceptInput = false;
- playSound(0, 0x4C69EA53);
- startAnimation(0x1AE88904, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmShrink);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
void Klaymen::stStandWonderAbout() {
if (_x > 260)
setDoDeltaX(1);
@@ -2521,7 +2325,7 @@ void Klaymen::stInsertKey() {
more = true;
} while (more);
_keysToInsert++;
- }
+ }
}
if (_keysToInsert == 0) {
GotoState(NULL);
@@ -2537,61 +2341,6 @@ void Klaymen::stInsertKey() {
}
}
-uint32 Klaymen::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x04684052) {
- _acceptInput = true;
- sendMessage(_parentScene, 0x2002, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stReadNote() {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x123E9C9F, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmReadNote);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 Klaymen::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- int16 speedUpFrameIndex;
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 438;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHitByDoor() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByDoor);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- playSound(0, 0x402E82D4);
-}
-
uint32 Klaymen::hmPeekWallReturn(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
@@ -2657,65 +2406,6 @@ void Klaymen::stPeekWallReturn() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stPullHammerLever() {
- if (!stStartAction(AnimationCallback(&Klaymen::stPullHammerLever))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x00648953, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPullHammerLever);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- }
-}
-
-uint32 Klaymen::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209)
- sendMessage(_attachedSprite, 0x480F, 0);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::suRidePlatformDown() {
- _platformDeltaY++;
- _y += _platformDeltaY;
- if (_y > 600)
- sendMessage(this, 0x1019, 0);
-}
-
-void Klaymen::stRidePlatformDown() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stRidePlatformDown))) {
- _busyStatus = 1;
- sendMessage(_parentScene, 0x4803, 0);
- _acceptInput = false;
- _platformDeltaY = 0;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suRidePlatformDown);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-}
-
-void Klaymen::stCrashDown() {
- playSound(0, 0x41648271);
- _busyStatus = 1;
- _acceptInput = false;
- startAnimationByHash(0x000BAB02, 0x88003000, 0);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(NULL);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- NextState(&Klaymen::stCrashDownFinished);
-}
-
-void Klaymen::stCrashDownFinished() {
- setDoDeltaX(2);
- stTryStandIdle();
-}
-
void Klaymen::upSpitOutFall() {
Klaymen::update();
if (_spitOutCountdown != 0 && (--_spitOutCountdown == 0)) {
@@ -2724,24 +2414,6 @@ void Klaymen::upSpitOutFall() {
}
}
-uint32 Klaymen::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x480F, 0);
- } else if (param.asInteger() == 0x586B0300) {
- sendMessage(_otherSprite, 0x480E, 1);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x4811:
@@ -2766,106 +2438,6 @@ uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, En
return 0;
}
-uint32 Klaymen::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x942D2081) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x2003, 0);
- } else if (param.asInteger() == 0xDA600012) {
- stHitByBoxingGlove();
- } else if (param.asInteger() == 0x0D01B294) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x480B, 0);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x01084280) {
- sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
- } else if (param.asInteger() == 0x02421405) {
- if (_isMoveObjectRequested) {
- if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
- stContinueMovingVenusFlyTrap();
- } else {
- SetMessageHandler(&Klaymen::hmFirstMoveVenusFlyTrap);
- }
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- case 0x480A:
- _isMoveObjectRequested = true;
- return 0;
- }
- return hmLowLevelAnimation(messageNum, param, sender);
-}
-
-uint32 Klaymen::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
- int16 speedUpFrameIndex;
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 435;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x1307050A) {
- playSound(0, 0x40428A09);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suFallDown() {
AnimatedSprite::updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
@@ -2877,19 +2449,6 @@ void Klaymen::suFallDown() {
_parentScene->checkCollision(this, 0xFFFF, 0x4810, 0);
}
-void Klaymen::stJumpToRingVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRingVenusFlyTrap))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x584984B4, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRingVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stLandOnFeet);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
void Klaymen::stStandIdleSpecial() {
playSound(0, 0x56548280);
_busyStatus = 0;
@@ -2946,86 +2505,6 @@ void Klaymen::stFallTouchdown() {
stTryStandIdle();
}
-void Klaymen::stJumpAndFall() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpAndFall))) {
- sendMessage(_parentScene, 0x1024, 3);
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0xB93AB151, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpAndFall);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
- }
-}
-
-void Klaymen::stDropFromRing() {
- if (_attachedSprite) {
- _x = _attachedSprite->getX();
- sendMessage(_attachedSprite, 0x4807, 0);
- _attachedSprite = NULL;
- }
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x586984B1, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
-}
-
-void Klaymen::stPressDoorButton() {
- _busyStatus = 2;
- _acceptInput = true;
- setDoDeltaX(0);
- startAnimation(0x1CD89029, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPressDoorButton);
- SetSpriteUpdate(&Klaymen::suAction);
-}
-
-void Klaymen::stHitByBoxingGlove() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByBoxingGlove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evHitByBoxingGloveDone);
-}
-
-void Klaymen::evHitByBoxingGloveDone() {
- sendMessage(_parentScene, 0x1024, 1);
-}
-
-void Klaymen::stMoveVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stMoveVenusFlyTrap))) {
- _busyStatus = 2;
- _isMoveObjectRequested = false;
- _acceptInput = true;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x5C01A870, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
- }
-}
-
-void Klaymen::stContinueMovingVenusFlyTrap() {
- _isMoveObjectRequested = false;
- _acceptInput = true;
- startAnimationByHash(0x5C01A870, 0x01084280, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
-}
-
-void Klaymen::evMoveVenusFlyTrapDone() {
- sendMessage(_attachedSprite, 0x482A, 0);
-}
-
void Klaymen::suFallSkipJump() {
updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
@@ -3049,50 +2528,7 @@ void Klaymen::stFallSkipJump() {
void Klaymen::upMoveObject() {
if (_x >= 380)
gotoNextStateExt();
- Klaymen::update();
-}
-
-uint32 Klaymen::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x51281850) {
- setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
- } else if (param.asInteger() == 0x43000538) {
- playSound(0, 0x21043059);
- } else if (param.asInteger() == 0x02B20220) {
- playSound(0, 0xC5408620);
- } else if (param.asInteger() == 0x0A720138) {
- playSound(0, 0xD4C08010);
- } else if (param.asInteger() == 0xB613A180) {
- playSound(0, 0x44051000);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stFetchMatch() {
- if (!stStartAction(AnimationCallback(&Klaymen::stFetchMatch))) {
- _busyStatus = 0;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x9CAA0218, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stLightMatch);
- }
-}
-
-void Klaymen::stLightMatch() {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x1222A513, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
+ Klaymen::update();
}
uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *sender) {
@@ -3114,18 +2550,6 @@ uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *
return Klaymen::hmLowLevelAnimation(messageNum, param, sender);
}
-uint32 Klaymen::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000F0082) {
- playSound(0, 0x74E2810F);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stMoveObject() {
if (!stStartAction(AnimationCallback(&Klaymen::stMoveObject))) {
_busyStatus = 2;
@@ -3147,93 +2571,6 @@ void Klaymen::stContinueMoveObject() {
SetMessageHandler(&Klaymen::hmMoveObject);
}
-void Klaymen::stTumbleHeadless() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stTumbleHeadless))) {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(0);
- startAnimation(0x2821C590, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmTumbleHeadless);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stTryStandIdle);
- sendMessage(_parentScene, 0x8000, 0);
- playSound(0, 0x62E0A356);
- }
-}
-
-void Klaymen::stCloseEyes() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stCloseEyes))) {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
- }
-}
-
-uint32 Klaymen::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x16401CA6) {
- _canSpitPipe = true;
- if (_contSpitPipe)
- spitIntoPipe();
- } else if (param.asInteger() == 0xC11C0008) {
- _canSpitPipe = false;
- _acceptInput = false;
- _readyToSpit = false;
- } else if (param.asInteger() == 0x018A0001) {
- sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stTrySpitIntoPipe() {
- if (_readyToSpit) {
- _contSpitPipe = true;
- _spitContDestPipeIndex = _spitPipeIndex;
- if (_canSpitPipe)
- spitIntoPipe();
- } else if (!stStartAction(AnimationCallback(&Klaymen::stTrySpitIntoPipe))) {
- _busyStatus = 2;
- _acceptInput = true;
- _spitDestPipeIndex = _spitPipeIndex;
- _readyToSpit = true;
- _canSpitPipe = false;
- _contSpitPipe = false;
- startAnimation(0x1808B150, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- }
-}
-
-void Klaymen::spitIntoPipe() {
- _contSpitPipe = false;
- _spitDestPipeIndex = _spitContDestPipeIndex;
- _canSpitPipe = false;
- _acceptInput = false;
- startAnimation(0x1B08B553, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stContSpitIntoPipe);
-}
-
-void Klaymen::stContSpitIntoPipe() {
- _canSpitPipe = true;
- _acceptInput = true;
- startAnimationByHash(0x1808B150, 0x16401CA6, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
-}
-
void Klaymen::suRidePlatform() {
_x = _attachedSprite->getX() - 20;
_y = _attachedSprite->getY() + 46;
@@ -3344,2798 +2681,4 @@ void Klaymen::stPeekInsideBlink() {
_blinkCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
}
-// KmScene1001
-
-KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-}
-
-uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stSleeping);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullHammerLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4836:
- if (param.asInteger() == 1) {
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stWakeUp);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1002
-
-KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable1();
-}
-
-void KmScene1002::xUpdate() {
- if (_x >= 250 && _x <= 435 && _y >= 420) {
- if (_idleTableNum == 0) {
- setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
- _idleTableNum = 1;
- }
- } else if (_idleTableNum == 1) {
- setKlaymenIdleTable1();
- _idleTableNum = 0;
- }
-}
-
-uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stStandIdleSpecial);
- break;
- case 0x2007:
- _otherSprite = (Sprite*)param.asEntity();
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stJumpAndFall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stDropFromRing);
- break;
- case 0x4804:
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4805:
- switch (param.asInteger()) {
- case 1:
- GotoState(&Klaymen::stJumpToRing1);
- break;
- case 2:
- GotoState(&Klaymen::stJumpToRing2);
- break;
- case 3:
- GotoState(&Klaymen::stJumpToRing3);
- break;
- case 4:
- GotoState(&Klaymen::stJumpToRing4);
- break;
- }
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveVenusFlyTrap);
- break;
- case 0x480D:
- GotoState(&Klaymen::stJumpToRingVenusFlyTrap);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressDoorButton);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- startWalkToAttachedSpriteXDistance(param.asInteger());
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2005, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2006, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1004
-
-KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x01900A04);
-}
-
-uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReadNote);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4828:
- GotoState(&Klaymen::stTurnToBackToUse);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x2C2A4A1C);
- break;
- case 0x483E:
- teleporterDisappear(0x3C2E4245);
- break;
- }
- return messageResult;
-}
-
-// KmScene1201
-
-KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
- _doYHitIncr = true;
-}
-
-uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveObject);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4813:
- GotoState(&Klaymen::stFetchMatch);
- break;
- case 0x4814:
- GotoState(&Klaymen::stTumbleHeadless);
- break;
- case 0x4815:
- GotoState(&Klaymen::stCloseEyes);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekWall1);
- break;
- case 0x483B:
- GotoState(&Klaymen::stPeekWallReturn);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekWall2);
- break;
- }
- return 0;
-}
-
-KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- GotoState(&Klaymen::stCrashDown);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- }
- return 0;
-}
-
-KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- else
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- else
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xEE084A04);
- break;
- case 0x483E:
- teleporterDisappear(0xB86A4274);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stInsertKey);
- else
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1401
-
-KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- }
- return 0;
-}
-
-// KmScene1402
-
-KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- SetFilterY(&Sprite::defFilterY);
-}
-
-uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- }
- return 0;
-}
-
-// KmScene1403
-
-KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
-}
-
-uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1404
-
-KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2032:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2032, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2032, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-// KmScene1705
-
-KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stFallSkipJump);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter) {
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- }
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x5E0A4905);
- break;
- case 0x483E:
- teleporterDisappear(0xD86E4477);
- break;
- }
- return messageResult;
-}
-
-KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xBE68CC54);
- break;
- case 0x483E:
- teleporterDisappear(0x18AB4ED4);
- break;
- }
- return messageResult;
-}
-
-KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4811:
- GotoState(&Klaymen::stHitByDoor);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xFF290E30);
- break;
- case 0x483E:
- teleporterDisappear(0x9A28CA1C);
- break;
- }
- return messageResult;
-}
-
-KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x04104242);
-}
-
-uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4819:
- GotoState(&Klaymen::stClayDoorOpen);
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2205::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _walkResumeFrameIncr = 1;
- _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
-}
-
-KmScene2206::~KmScene2206() {
- _vm->_soundMan->deleteSoundGroup(0x80101800);
-}
-
-void KmScene2206::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stRidePlatformDown);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stRidePlatform);
- break;
- case 0x2005:
- suRidePlatform();
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stInteractLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2242::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
- // Empty
-}
-
-void KmHallOfRecords::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2247::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4832:
- GotoState(&Klaymen::stUseTube);
- break;
- case 0x4833:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAbout);
- else {
- _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stTrySpitIntoPipe);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (!getGlobalVar(V_TV_JOKE_TOLD))
- GotoState(&Klaymen::stStandWonderAbout);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- }
- return messageResult;
-}
-
-KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekInside);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekInsideReturn);
- break;
- }
- return 0;
-}
-
-KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x00900849);
-}
-
-uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else
- GotoState(&Klaymen::stWonderAboutHalf);
- break;
- case 0x482E:
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4838:
- GotoState(&Klaymen::stJumpToGrabRelease);
- break;
- }
- return 0;
-}
-
-KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x81120132);
-}
-
-uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stWalkToFront2Small);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stTurnToBackWalkSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4830:
- GotoState(&Klaymen::stShrink);
- break;
- }
- return 0;
-}
-
-KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xDE284B74);
- break;
- case 0x483E:
- teleporterDisappear(0xD82A4094);
- break;
- }
- return messageResult;
-}
-
-KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x98182003);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(440, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x1830009A);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(226, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 5)
- GotoState(&Klaymen::stTurnToUseExt);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4805:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrabFall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
} // End of namespace Neverhood
diff --git a/engines/neverhood/klaymen.h b/engines/neverhood/klaymen.h
index 25443b5a35..a614560fc0 100644
--- a/engines/neverhood/klaymen.h
+++ b/engines/neverhood/klaymen.h
@@ -33,7 +33,6 @@ namespace Neverhood {
// TODO This code is horrible and weird and a lot of stuff needs renaming once a better name is found
// TODO Also the methods should probably rearranged and be grouped together more consistently
-class Klaymen;
class Scene;
const uint32 kKlaymenSpeedUpHash = 0x004A2148;
@@ -67,34 +66,30 @@ public:
void startIdleAnimation(uint32 fileHash, AnimationCb callback);
void upIdleAnimation();
+ // Idle animations - start
void stIdlePickEar();
void evIdlePickEarDone();
- uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleSpinHead();
- uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleArms();
void evIdleArmsDone();
- uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleChest();
- uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleHeadOff();
- uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleWonderAbout();
-
void stIdleTeleporterHands();
-
void stIdleTeleporterHands2();
+ uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
+ // Idle animations - end
+
void stTryStandIdle();
void stStandAround();
void upStandIdle();
void stIdleBlink();
-
+
bool stStartAction(AnimationCb callback3);
bool stStartActionFromIdle(AnimationCb callback);
uint32 hmStartAction(int messageNum, const MessageParam &param, Entity *sender);
@@ -134,7 +129,7 @@ public:
void stPickUpTube();
uint32 hmPickUpTube(int messageNum, const MessageParam &param, Entity *sender);
-
+
void stTurnToUse();
void stTurnToUseHalf();
void stTurnAwayFromUse();
@@ -150,12 +145,6 @@ public:
void stInsertKey();
uint32 hmInsertKey(int messageNum, const MessageParam &param, Entity *sender);
- void stReadNote();
- uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHitByDoor();
- uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
-
void stPeekWall();
uint32 hmPeekWall(int messageNum, const MessageParam &param, Entity *sender);
@@ -166,21 +155,8 @@ public:
void upPeekWallBlink();
void stPeekWall1();
-
void stPeekWall2();
- void stPullHammerLever();
- uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
-
- void stRidePlatformDown();
- void suRidePlatformDown();
-
- void stCrashDown();
- void stCrashDownFinished();
-
- void stShrink();
- uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
-
void stGrow();
uint32 hmGrow(int messageNum, const MessageParam &param, Entity *sender);
@@ -203,11 +179,6 @@ public:
void stLetGoOfLever();
void evLeverReleasedEvent();
- void stWakeUp();
-
- void stSleeping();
- uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
-
void stPressButton();
void stPressFloorButton();
void stPressButtonSide();
@@ -228,20 +199,6 @@ public:
void stClimbLadderHalf();
uint32 hmClimbLadderHalf(int messageNum, const MessageParam &param, Entity *sender);
- void setupJumpToRing();
- void stJumpToRing1();
- void stJumpToRing2();
- void stJumpToRing4();
- uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHangOnRing();
-
- void stJumpToRing3();
- uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHoldRing3();
- uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
-
void stReleaseRing();
void stLandOnFeet();
@@ -263,33 +220,26 @@ 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);
void stSitIdleTeleporter();
void upSitIdleTeleporter();
-
void stSitIdleTeleporterBlink();
-
void stSitIdleTeleporterBlinkSecond();
void stTurnToUseInTeleporter();
-
void stReturnFromUseInTeleporter();
-
void stGetUpFromTeleporter();
void teleporterAppear(uint32 fileHash);
void teleporterDisappear(uint32 fileHash);
uint32 hmTeleporterAppearDisappear(int messageNum, const MessageParam &param, Entity *sender);
- void stClayDoorOpen();
- uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
-
void stFallSkipJump();
void suFallSkipJump();
@@ -298,19 +248,6 @@ public:
uint32 hmMoveObject(int messageNum, const MessageParam &param, Entity *sender);
void upMoveObject();
- void stCloseEyes();
-
- void stTumbleHeadless();
- uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
-
- void stFetchMatch();
- void stLightMatch();
- uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHitByBoxingGlove();
- uint32 hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender);
- void evHitByBoxingGloveDone();
-
void stStandIdleSmall();
void stWonderAboutSmall();
void stWonderAboutHalfSmall();
@@ -326,35 +263,18 @@ public:
void stFinishGrow();
uint32 hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender);
-
- void stJumpToRingVenusFlyTrap();
- uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
-
- void stDropFromRing();
void stStandIdleSpecial();
uint32 hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender);
- void stPressDoorButton();
- uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
-
void stSpitOutFall0();
void stSpitOutFall2();
void suFallDown();
void upSpitOutFall();
- void stJumpAndFall();
- uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
-
void stFalling();
void stFallTouchdown();
- void stMoveVenusFlyTrap();
- void stContinueMovingVenusFlyTrap();
- uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- void evMoveVenusFlyTrapDone();
-
void stPeekInside();
void stPeekInsideReturn();
void stPeekInsideBlink();
@@ -363,7 +283,7 @@ public:
////////////////////////////////////////////////////////////////////////////
void stopWalking();
-
+
void suAction();
void suUpdateDestX();
void suWalkingTestExit();
@@ -375,13 +295,8 @@ public:
void setKlaymenIdleTable1();
void setKlaymenIdleTable2();
void setKlaymenIdleTable3();
-
- void setSoundFlag(bool value) { _soundFlag = value; }
- void spitIntoPipe();
- void stTrySpitIntoPipe();
- void stContSpitIntoPipe();
- uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
+ void setSoundFlag(bool value) { _soundFlag = value; }
void stRidePlatform();
void suRidePlatform();
@@ -416,7 +331,7 @@ protected:
NPointArray *_pathPoints;
bool _soundFlag;
-
+
int16 _spitOutCountdown;
bool _isSittingInTeleporter;
@@ -432,13 +347,6 @@ protected:
int _moveObjectCountdown;
- bool _canSpitPipe;
- bool _contSpitPipe;
- bool _readyToSpit;
- uint32 _spitPipeIndex;
- uint32 _spitDestPipeIndex;
- uint32 _spitContDestPipeIndex;
-
virtual void xUpdate();
virtual uint32 xHandleMessage(int messageNum, const MessageParam &param);
@@ -456,314 +364,9 @@ 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:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1002 : public Klaymen {
-public:
- KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1004 : public Klaymen {
-public:
- KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1109 : public Klaymen {
-public:
- KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1201 : public Klaymen {
-public:
- KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1303 : public Klaymen {
-public:
- KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1304 : public Klaymen {
-public:
- KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1305 : public Klaymen {
-public:
- KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1306 : public Klaymen {
-public:
- KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1308 : public Klaymen {
-public:
- KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1401 : public Klaymen {
-public:
- KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1402 : public Klaymen {
-public:
- KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1403 : public Klaymen {
-public:
- KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1404 : public Klaymen {
-public:
- KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1608 : public Klaymen {
-public:
- KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1705 : public Klaymen {
-public:
- KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1901 : public Klaymen {
-public:
- KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2001 : public Klaymen {
-public:
- KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2101 : public Klaymen {
-public:
- KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2201 : public Klaymen {
-public:
- KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2203 : public Klaymen {
-public:
- KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2205 : public Klaymen {
-public:
- KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2206 : public Klaymen {
-public:
- KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~KmScene2206();
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2207 : public Klaymen {
-public:
- KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2242 : public Klaymen {
-public:
- KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmHallOfRecords : public Klaymen {
-public:
- KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2247 : public Klaymen {
-public:
- KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2401 : public Klaymen {
-public:
- KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2402 : public Klaymen {
-public:
- KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2403 : public Klaymen {
-public:
- KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2406 : public Klaymen {
-public:
- KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2501 : public Klaymen {
-public:
- KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2732 : public Klaymen {
-public:
- KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2801 : public Klaymen {
-public:
- KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803 : public Klaymen {
-public:
- KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803Small : public Klaymen {
-public:
- KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2805 : public Klaymen {
-public:
- KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2806 : public Klaymen {
-public:
- KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2809 : public Klaymen {
-public:
- KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810Small : public Klaymen {
-public:
- KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810 : public Klaymen {
-public:
- KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2812 : public Klaymen {
-public:
- KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index a8631cb0d6..6b0635598f 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -20,6 +20,11 @@
*
*/
+#include "common/config-manager.h"
+#include "common/translation.h"
+
+#include "gui/saveload.h"
+
#include "neverhood/menumodule.h"
#include "neverhood/gamemodule.h"
@@ -68,17 +73,19 @@ 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);
createScene(MAIN_MENU, -1);
}
MenuModule::~MenuModule() {
_vm->_mixer->pauseAll(false);
+ _vm->toggleSoundUpdate(true);
_vm->_screen->setPaletteData(_savedPaletteData);
}
@@ -153,7 +160,8 @@ void MenuModule::updateScene() {
createScene(MAKING_OF, -1);
break;
case kMainMenuToggleMusic:
- // TODO Toggle music 0048A367
+ _vm->toggleMusic(!_vm->musicIsEnabled());
+ _vm->_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, !_vm->musicIsEnabled());
createScene(MAIN_MENU, -1);
break;
case kMainMenuDeleteGame:
@@ -191,24 +199,26 @@ uint32 MenuModule::handleMessage(int messageNum, const MessageParam &param, Enti
}
void MenuModule::createLoadGameMenu() {
- _savegameSlot = -1;
- _savegameList = new SavegameList();
- loadSavegameList();
+ refreshSaveGameList();
_childObject = new LoadGameMenu(_vm, this, _savegameList);
}
void MenuModule::createSaveGameMenu() {
- _savegameSlot = -1;
- _savegameList = new SavegameList();
- loadSavegameList();
+ refreshSaveGameList();
_childObject = new SaveGameMenu(_vm, this, _savegameList);
}
void MenuModule::createDeleteGameMenu() {
+ refreshSaveGameList();
+ _childObject = new DeleteGameMenu(_vm, this, _savegameList);
+}
+
+void MenuModule::refreshSaveGameList() {
_savegameSlot = -1;
+ delete _savegameList;
+ _savegameList = NULL;
_savegameList = new SavegameList();
loadSavegameList();
- _childObject = new DeleteGameMenu(_vm, this, _savegameList);
}
void MenuModule::handleLoadGameMenuAction(bool doLoad) {
@@ -257,7 +267,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());
@@ -315,7 +325,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,
@@ -327,37 +337,37 @@ 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);
+
+ insertStaticSprite(0x41137051, 100); // "Options" header text
+ insertStaticSprite(0xC10B2015, 100); // Button texts
+
+ if (!_vm->musicIsEnabled())
+ insertStaticSprite(0x0C24C0EE, 100); // "Music is off" button
for (uint buttonIndex = 0; buttonIndex < 9; ++buttonIndex) {
Sprite *menuButton = insertSprite<MenuButton>(this, buttonIndex,
kMenuButtonFileHashes[buttonIndex], kMenuButtonCollisionBounds[buttonIndex]);
addCollisionSprite(menuButton);
}
-
- SetUpdateHandler(&Scene::update);
- SetMessageHandler(&MainMenu::handleMessage);
+
+ SetUpdateHandler(&Scene::update);
+ SetMessageHandler(&MainMenu::handleMessage);
}
@@ -387,23 +397,25 @@ 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;
-
+
+ _vm->toggleSoundUpdate(true);
_musicResource = new MusicResource(_vm);
_musicResource->load(0x30812225);
_musicResource->play(0);
-
+
}
CreditsScene::~CreditsScene() {
_musicResource->unload();
delete _musicResource;
+ _vm->toggleSoundUpdate(false);
}
void CreditsScene::update() {
@@ -460,7 +472,7 @@ Widget::Widget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene
SetUpdateHandler(&Widget::update);
SetMessageHandler(&Widget::handleMessage);
-
+
setPosition(x, y);
}
@@ -523,7 +535,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() {
@@ -564,7 +576,8 @@ TextEditWidget::TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateM
_maxVisibleChars = (_rect.x2 - _rect.x1) / _fontSurface->getCharWidth();
_cursorPos = 0;
-
+ _textLabelWidget = NULL;
+
SetUpdateHandler(&TextEditWidget::update);
SetMessageHandler(&TextEditWidget::handleMessage);
}
@@ -608,7 +621,7 @@ void TextEditWidget::initialize() {
_textLabelWidget->initialize();
if (_cursorFileHash != 0) {
cursorSpriteResource.load(_cursorFileHash, true);
- _cursorSurface = new BaseSurface(_vm, 0, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height);
+ _cursorSurface = new BaseSurface(_vm, 0, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height, "cursor");
_cursorSurface->drawSpriteResourceEx(cursorSpriteResource, false, false, cursorSpriteResource.getDimensions().width, cursorSpriteResource.getDimensions().height);
_cursorSurface->setVisible(!_readOnly);
}
@@ -757,9 +770,7 @@ void SavegameListBox::onClick() {
mousePos.y -= _y + _rect.y1;
if (mousePos.x >= 0 && mousePos.x <= _rect.x2 - _rect.x1 &&
mousePos.y >= 0 && mousePos.y <= _rect.y2 - _rect.y1) {
- // We add 1 to the char height to ensure that the correct entry is chosen if the
- // user clicks at the bottom the text entry
- int newIndex = _firstVisibleItem + mousePos.y / (_fontSurface->getCharHeight() + 1);
+ int newIndex = _firstVisibleItem + mousePos.y / _fontSurface->getCharHeight();
if (newIndex <= _lastVisibleItem) {
_currIndex = newIndex;
refresh();
@@ -797,7 +808,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();
@@ -821,7 +832,7 @@ void SavegameListBox::scrollUp() {
}
void SavegameListBox::scrollDown() {
- if (_lastVisibleItem < (int)_textLabelItems.size()) {
+ if (_lastVisibleItem < (int)_textLabelItems.size() - 1) {
++_firstVisibleItem;
++_lastVisibleItem;
refresh();
@@ -838,7 +849,7 @@ void SavegameListBox::pageUp() {
}
void SavegameListBox::pageDown() {
- int amount = MIN((int)_textLabelItems.size() - _lastVisibleItem, _maxVisibleItemsCount);
+ int amount = MIN((int)_textLabelItems.size() - _lastVisibleItem - 1, _maxVisibleItemsCount);
if (amount > 0) {
_firstVisibleItem += amount;
_lastVisibleItem += amount;
@@ -846,17 +857,68 @@ void SavegameListBox::pageDown() {
}
}
+int GameStateMenu::scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc) {
+ const EnginePlugin *plugin = NULL;
+ EngineMan.findGame(ConfMan.get("gameid"), &plugin);
+ GUI::SaveLoadChooser *dialog;
+ Common::String desc;
+ int slot;
+
+ if (isSave) {
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+
+ slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ desc = dialog->getResultString();
+
+ if (desc.empty())
+ desc = dialog->createDefaultSaveDescription(slot);
+
+ if (desc.size() > 29)
+ desc = Common::String(desc.c_str(), 29);
+
+ saveDesc = desc;
+ } else {
+ dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ }
+
+ delete dialog;
+
+ return slot;
+}
+
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);
-
+
+ if (!ConfMan.getBool("originalsaveload")) {
+ Common::String saveDesc;
+ int saveCount = savegameList->size();
+ int slot = scummVMSaveLoadDialog(isSave, saveDesc);
+
+ if (slot >= 0) {
+ if (!isSave) {
+ ((MenuModule*)_parentModule)->setLoadgameInfo(slot);
+ } else {
+ ((MenuModule*)_parentModule)->setSavegameInfo(saveDesc,
+ slot, slot >= saveCount);
+ }
+ leaveScene(0);
+ } else {
+ leaveScene(1);
+ }
+ return;
+ }
+
setBackground(backgroundFileHash);
setPalette(backgroundFileHash);
insertScreenMouse(mouseFileHash, mouseRect);
@@ -869,13 +931,13 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
_textEditWidget = new TextEditWidget(_vm, textEditX, textEditY, this, 29,
_fontSurface, textEditBackgroundFileHash, textEditRect);
- if (textEditCursorFileHash != 0)
+ if (isSave)
_textEditWidget->setCursor(textEditCursorFileHash, 2, 13);
else
_textEditWidget->setReadOnly(true);
_textEditWidget->initialize();
setCurrWidget(_textEditWidget);
-
+
for (uint buttonIndex = 0; buttonIndex < 6; ++buttonIndex) {
Sprite *menuButton = insertSprite<MenuButton>(this, buttonIndex,
buttonFileHashes[buttonIndex], buttonCollisionBounds[buttonIndex]);
@@ -884,7 +946,6 @@ GameStateMenu::GameStateMenu(NeverhoodEngine *vm, Module *parentModule, Savegame
SetUpdateHandler(&Scene::update);
SetMessageHandler(&GameStateMenu::handleMessage);
-
}
GameStateMenu::~GameStateMenu() {
@@ -969,17 +1030,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,
@@ -1003,17 +1064,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,
@@ -1036,21 +1097,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) {
@@ -1071,10 +1132,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);
@@ -1097,7 +1158,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 08858ad204..9da9c849a9 100644
--- a/engines/neverhood/menumodule.h
+++ b/engines/neverhood/menumodule.h
@@ -45,6 +45,7 @@ public:
void setLoadgameInfo(uint index);
void setSavegameInfo(const Common::String &description, uint index, bool newSavegame);
void setDeletegameInfo(uint index);
+ void refreshSaveGameList();
protected:
int _sceneNum;
byte *_savedPaletteData;
@@ -78,7 +79,6 @@ class MainMenu : public Scene {
public:
MainMenu(NeverhoodEngine *vm, Module *parentModule);
protected:
- Sprite *_musicOnButton;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
@@ -123,8 +123,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();
@@ -205,13 +205,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);
@@ -229,6 +229,7 @@ protected:
Common::String _savegameDescription;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
virtual void performAction();
+ int scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc);
};
class SaveGameMenu : public GameStateMenu {
diff --git a/engines/neverhood/microtiles.cpp b/engines/neverhood/microtiles.cpp
index e19be52b5a..3dd6475046 100644
--- a/engines/neverhood/microtiles.cpp
+++ b/engines/neverhood/microtiles.cpp
@@ -118,8 +118,6 @@ RectangleList *MicroTileArray::getRectangles() {
for (y = 0; y < _tilesH; ++y) {
for (x = 0; x < _tilesW; ++x) {
-
- int start;
int finish = 0;
BoundingBox boundingBox = _tiles[i];
@@ -132,8 +130,6 @@ RectangleList *MicroTileArray::getRectangles() {
y0 = (y * TileSize) + TileY0(boundingBox);
y1 = (y * TileSize) + TileY1(boundingBox);
- start = i;
-
if (TileX1(boundingBox) == TileSize - 1 && x != _tilesW - 1) { // check if the tile continues
while (!finish) {
++x;
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/module.h b/engines/neverhood/module.h
index e98012cbea..8ab2159030 100644
--- a/engines/neverhood/module.h
+++ b/engines/neverhood/module.h
@@ -48,9 +48,11 @@ public:
Module(NeverhoodEngine *vm, Module *parentModule);
virtual ~Module();
virtual void draw();
+ SceneType getSceneType() { return _sceneType; }
+
+ Entity *_childObject;
protected:
Module *_parentModule;
- Entity *_childObject;
bool _done;
uint32 _moduleResult;
SceneType _sceneType;
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index 714fc3079b..9c1220134c 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/neverhood
MODULE_OBJS = \
background.o \
blbarchive.o \
+ console.o \
detection.o \
diskplayerscene.o \
entity.o \
@@ -14,26 +15,44 @@ MODULE_OBJS = \
microtiles.o \
module.o \
modules/module1000.o \
+ modules/module1000_sprites.o \
modules/module1100.o \
+ modules/module1100_sprites.o \
modules/module1200.o \
+ modules/module1200_sprites.o \
modules/module1300.o \
+ modules/module1300_sprites.o \
modules/module1400.o \
+ modules/module1400_sprites.o \
modules/module1500.o \
modules/module1600.o \
+ modules/module1600_sprites.o \
modules/module1700.o \
+ modules/module1700_sprites.o \
modules/module1800.o \
modules/module1900.o \
+ modules/module1900_sprites.o \
modules/module2000.o \
+ modules/module2000_sprites.o \
modules/module2100.o \
+ modules/module2100_sprites.o \
modules/module2200.o \
+ modules/module2200_sprites.o \
modules/module2300.o \
modules/module2400.o \
+ modules/module2400_sprites.o \
modules/module2500.o \
+ modules/module2500_sprites.o \
modules/module2600.o \
+ modules/module2600_sprites.o \
modules/module2700.o \
+ modules/module2700_sprites.o \
modules/module2800.o \
+ modules/module2800_sprites.o \
modules/module2900.o \
+ modules/module2900_sprites.o \
modules/module3000.o \
+ modules/module3000_sprites.o \
mouse.o \
navigationscene.o \
neverhood.o \
diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp
index ef2872ba2e..534fb2ec2f 100644
--- a/engines/neverhood/modules/module1000.cpp
+++ b/engines/neverhood/modules/module1000.cpp
@@ -21,15 +21,14 @@
*/
#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1000_sprites.h"
namespace Neverhood {
Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
- debug("Create Module1000(%d)", which);
- _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
+ _musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
_vm->_soundMan->addMusic(0x03294419, 0x061880C6);
_vm->_soundMan->addMusic(0x03294419, _musicFileHash);
@@ -48,7 +47,7 @@ Module1000::~Module1000() {
}
void Module1000::createScene(int sceneNum, int which) {
- debug("Module1000::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1000::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -120,231 +119,18 @@ void Module1000::updateScene() {
}
}
-// Scene1001
-
-AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(800, 137, 242);
- _x = 726;
- _y = 440;
- stShowIdleDoor();
- loadSound(1, 0xED403E03);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Door::handleMessage);
-}
-
-uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- hammerHitsDoor();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return 0;
-}
-
-void AsScene1001Door::hammerHitsDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 0:
- case 1:
- playSound(0, 0x65482F03);
- startAnimation(0x624C0498, 1, 3);
- NextState(&AsScene1001Door::stShowIdleDoor);
- break;
- case 2:
- playSound(1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorMove);
- break;
- default:
- // Nothing
- break;
- }
- incGlobalVar(V_DOOR_STATUS, 1);
-}
-
-void AsScene1001Door::stShowIdleDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 1:
- startAnimation(0x624C0498, 4, -1);
- _newStickFrameIndex = 4;
- break;
- case 2:
- startAnimation(0x624C0498, 1, -1);
- _newStickFrameIndex = 1;
- break;
- case 3:
- stopAnimation();
- setVisible(false);
- break;
- default:
- startAnimation(0x624C0498, 0, -1);
- _newStickFrameIndex = 0;
- break;
- }
-}
-
-void AsScene1001Door::stBustedDoorMove() {
- setGlobalVar(V_DOOR_BUSTED, 1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorGone);
- _x = 30;
-}
-
-void AsScene1001Door::stBustedDoorGone() {
- playSound(0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
- : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
-
- _x = 547;
- _y = 206;
- createSurface(900, 177, 192);
- startAnimation(0x022C90D4, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Hammer::handleMessage);
-}
-
-uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00352100)
- sendMessage(_asDoor, 0x2000, 0);
- else if (param.asInteger() == 0x0A1A0109)
- playSound(0, 0x66410886);
- break;
- case 0x2000:
- startAnimation(0x022C90D4, 1, -1);
- playSound(0, 0xE741020A);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return 0;
-}
-
-AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 320;
- _y = 240;
- createSurface(100, 66, 129);
- startAnimation(0xC68C2299, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Window::handleMessage);
-}
-
-uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0E0A1410)
- playSound(0, 0x60803F10);
- break;
- case 0x2001:
- startAnimation(0xC68C2299, 0, -1);
- break;
- case 0x3002:
- SetMessageHandler(NULL);
- setGlobalVar(V_WINDOW_OPEN, 1);
- setVisible(false);
- break;
- }
- return 0;
-}
-
-AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(1010, 71, 73);
- setDoDeltaX(deltaXType);
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- _x = x;
- _y = y;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Lever::handleMessage);
-}
-
-uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00C0C444)
- sendMessage(_parentScene, 0x480F, 0);
- else if (param.asInteger() == 0xC41A02C0)
- playSound(0, 0x40581882);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- break;
- case 0x480F:
- startAnimation(0x04A98C36, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
-
- _priority = 1100;
- _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
- setVisible(false);
- SetUpdateHandler(&SsCommonButtonSprite::update);
- SetMessageHandler(&SsCommonButtonSprite::handleMessage);
-}
-
-void SsCommonButtonSprite::update() {
- if (_countdown != 0 && (--_countdown) == 0)
- setVisible(false);
-}
-
-uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- _countdown = 8;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asDoor(NULL), _asWindow(NULL) {
Sprite *tempSprite;
SetMessageHandler(&Scene1001::handleMessage);
-
+
setHitRects(0x004B4860);
setBackground(0x4086520E);
setPalette(0x4086520E);
insertScreenMouse(0x6520A400);
-
+
if (which < 0) {
// Restoring game
setRectList(0x004B49F0);
@@ -375,7 +161,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);
@@ -441,719 +227,6 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// Scene1002
-
-AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
-
- SetUpdateHandler(&AsScene1002Ring::update);
-
- if (_isSpecial) {
- createSurface(990, 68, 314);
- if (isRingLow) {
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- } else {
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
- } else {
- createSurface(990, 68, 138);
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
-
- setClipRect(0, clipY1, 640, 480);
-
- _x = x;
- _y = y;
-
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
-
-}
-
-void AsScene1002Ring::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4806:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x4806, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
- startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
- break;
- case 0x480F:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x480F, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
- startAnimation(0x861A2020, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmRingIdle(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x05410F72)
- playSound(0, 0x21EE40A9);
- break;
- case 0x3002:
- startAnimation(0xA85C4011, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
- : StaticSprite(vm, 1200) {
-
- loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
- setClipRect(clipRect);
- SetUpdateHandler(&AsScene1002Door::update);
- SetMessageHandler(&AsScene1002Door::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1002Door::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
- SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
- break;
- case 0x4809:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
- SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002Door::suOpenDoor() {
- if (_y > 49) {
- _y -= 8;
- if (_y < 49) {
- SetSpriteUpdate(NULL);
- _y = 49;
- }
- _needRefresh = true;
- }
-}
-
-void AsScene1002Door::suCloseDoor() {
- if (_y < 239) {
- _y += 8;
- if (_y > 239) {
- SetSpriteUpdate(NULL);
- _y = 239;
- }
- _needRefresh = true;
- }
-}
-
-AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface(1025, 88, 165);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
-}
-
-uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- _x = ((Sprite*)sender)->getX() - 98;
- _y = ((Sprite*)sender)->getY() - 111;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
- : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
-
- createSurface(800, 136, 147);
- setClipRect(clipRect);
- suDoorSpy();
- loadSound(0, 0xC0C40298);
- startAnimation(0x586C1D48, 0, 0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
- SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
-}
-
-uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0xA61CA1C2)
- sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
- else if (param.asInteger() == 0x14CE0620)
- playSound(0);
- break;
- case 0x2003:
- stDoorSpyBoxingGlove();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002DoorSpy::suDoorSpy() {
- _x = _asDoor->getX() + 34;
- _y = _asDoor->getY() + 175;
-}
-
-void AsScene1002DoorSpy::stDoorSpyIdle() {
- setClipRect(_clipRect);
- _parentScene->setSurfacePriority(getSurface(), 800);
- startAnimation(0x586C1D48, 0, 0);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
-}
-
-void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
- setClipRect(0, 0, 640, 480);
- _parentScene->setSurfacePriority(getSurface(), 1200);
- startAnimation(0x586C1D48, 1, -1);
- SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
- NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
-}
-
-SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0) {
-
- _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- createSurface(surfacePriority, 40, 40);
- loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- setVisible(false);
- SetUpdateHandler(&SsCommonPressButton::update);
- SetMessageHandler(&SsCommonPressButton::handleMessage);
-}
-
-void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-void SsCommonPressButton::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- if (_status == 1) {
- _status = 2;
- loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 2) {
- _status = 3;
- loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 3) {
- _status = 0;
- setVisible(false);
- }
- }
-}
-
-uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- _status = 1;
- _countdown = 4;
- setVisible(true);
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
-AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
-
- createSurface(995, 175, 195);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- setDoDeltaX(1);
- _x = 366;
- _y = 435;
- stRingGrabbed();
- } else {
- _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
- _y = 435;
- stIdle();
- }
- } else {
- _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
- _y = 364;
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
- stRingGrabbed();
- } else {
- stIdle();
- }
- }
- _flags = 4;
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-void AsScene1002VenusFlyTrap::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- AnimatedSprite::update();
-}
-
-void AsScene1002VenusFlyTrap::upIdle() {
- if (_countdown == 0 && _klaymen->getX() - 20 > _x)
- setDoDeltaX(1);
- else if (_klaymen->getX() + 20 < _x)
- setDoDeltaX(0);
- update();
-}
-
-uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x1011:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- } else {
- if (_x >= 174 && _x <= 430) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- }
- break;
- case 0x480B:
- setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR))
- stRelease();
- else
- stWalk();
- } else {
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
- stRelease();
- else
- stWalk();
- }
- break;
- case 0x480C:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- messageResult = 1;
- else
- messageResult = 0;
- } else {
- if (_x >= 174 && _x <= 430)
- messageResult = 1;
- else
- messageResult = 0;
- }
- break;
- case 0x480E:
- if (param.asInteger() == 1)
- stGrabRing();
- break;
- case 0x4810:
- swallowKlaymen();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x41881801) {
- if (_isSecond) {
- if (_x > 330)
- sendMessage(_klaymen, 0x4811, 2);
- else
- sendMessage(_klaymen, 0x4811, 0);
- } else {
- sendMessage(_klaymen, 0x4811, 0);
- }
- } else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002VenusFlyTrap::stWalkBack() {
- setDoDeltaX(2);
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stWalk() {
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stRelease() {
- sendMessage(_parentScene, 0x4807, 0);
- startAnimation(0x82292851, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stGrabRing() {
- setDoDeltaX(1);
- startAnimation(0x86A82A11, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
-}
-
-void AsScene1002VenusFlyTrap::stRingGrabbed() {
- startAnimation(0xB5A86034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInside() {
- startAnimation(0x31303094, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(NULL);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
- _countdown = 24;
-}
-
-void AsScene1002VenusFlyTrap::stIdle() {
- startAnimation(0xC8204250, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- } else {
- if (_x >= 174 && _x <= 430)
- setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- }
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
- startAnimation(0x152920C4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
-}
-
-void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
- startAnimation(0x84001117, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::swallowKlaymen() {
- if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
- if (_isSecond)
- setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
- else
- setDoDeltaX(_x > 320 ? 1 : 0);
- sendMessage(_klaymen, 0x2001, 0);
- startAnimation(0x8C2C80D4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
- }
-}
-
-AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _countdown(0) {
-
- createSurface(850, 186, 212);
- _x = 320;
- _y = 240;
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- startAnimation(0x004A4495, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
- SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- if (_isDoorClosed)
- stCloseDoor();
- else
- stOpenDoor();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x4808:
- _isDoorClosed = false;
- _countdown = 2;
- break;
- case 0x4809:
- _isDoorClosed = true;
- _countdown = 2;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002OutsideDoorBackground::stOpenDoor() {
- startAnimation(0x004A4495, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::stCloseDoor() {
- startAnimation(0x004A4495, -1, -1);
- _playBackwards = true;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
- NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
-}
-
-void AsScene1002OutsideDoorBackground::stDoorClosed() {
- setVisible(false);
- stopAnimation();
-}
-
-AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
-
- createSurface(1200, 40, 163);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1002KlaymenLadderHands::update() {
- if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
- startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
- startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
- _isClipRectSaved(false) {
-
- createSurface(1000, 33, 41);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
- SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
-}
-
-void AsScene1002KlaymenPeekHand::update() {
- if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
- startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_parentScene, 0x1022, 1200);
- _isClipRectSaved = true;
- _savedClipRect = _surface->getClipRect();
- setClipRect(0, 0, 640, 480);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_parentScene, 0x1022, 1000);
- if (_isClipRectSaved)
- setClipRect(_savedClipRect);
- }
- break;
- }
- return messageResult;
-}
-
Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isKlaymenFloor(false), _isClimbingLadder(false) {
@@ -1247,7 +320,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
-
+
setRectList(0x004B43A0);
loadSound(1, 0x60755842);
@@ -1324,11 +397,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);
@@ -1362,11 +435,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);
@@ -1381,70 +454,15 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
setSpriteSurfacePriority(_ssCeiling, 1015);
setSpriteSurfacePriority(_ssLadderArch, 1015);
break;
- }
- return messageResult;
-}
-
-// StaticScene
-
-StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash)
- : Scene(vm, parentModule) {
-
- SetMessageHandler(&StaticScene::handleMessage);
-
- setBackground(backgroundFileHash);
- setPalette(backgroundFileHash);
- insertPuzzleMouse(cursorFileHash, 20, 620);
-}
-
-uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Scene::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x0001:
- if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
- leaveScene(0);
- break;
}
- return 0;
-}
-
-// Scene1004
-
-AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 330;
- _y = 327;
- createSurface(800, 56, 50);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1004TrashCan::handleMessage);
-}
-
-uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x225A8587)
- playSound(0, 0x109AFC4C);
- break;
- case 0x2002:
- startAnimation(0xEB312C11, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return 0;
+ return messageResult;
}
Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
Sprite *tempSprite;
-
+
SetUpdateHandler(&Scene1004::update);
SetMessageHandler(&Scene1004::handleMessage);
@@ -1477,16 +495,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());
@@ -1520,7 +538,7 @@ uint32 Scene1004::handleMessage(int messageNum, const MessageParam &param, Entit
break;
}
return messageResult;
-}
+}
void Scene1004::updatePaletteArea() {
if (_klaymen->getY() < 150) {
@@ -1538,8 +556,6 @@ void Scene1004::updatePaletteArea() {
}
}
-// Scene1005
-
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1559,7 +575,7 @@ Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
}
drawTextToBackground();
-
+
}
uint32 Scene1005::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1567,7 +583,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;
@@ -1616,19 +632,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))
@@ -1643,7 +659,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;
@@ -1662,7 +678,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..4b17c92b3b 100644
--- a/engines/neverhood/modules/module1000.h
+++ b/engines/neverhood/modules/module1000.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1000
-
class Module1000 : public Module {
public:
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,53 +40,6 @@ protected:
void updateScene();
};
-// Scene1001
-
-class AsScene1001Door : public AnimatedSprite {
-public:
- AsScene1001Door(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void hammerHitsDoor();
- void stShowIdleDoor();
- void stBustedDoorMove();
- void stBustedDoorGone();
-};
-
-class AsScene1001Hammer : public AnimatedSprite {
-public:
- AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
-protected:
- Sprite *_asDoor;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Window : public AnimatedSprite {
-public:
- AsScene1001Window(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Lever : public AnimatedSprite {
-public:
- AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonButtonSprite : public StaticSprite {
-public:
- SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1001 : public Scene {
public:
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -102,136 +53,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// TODO: Move this to some common file since it's used several times
-
-class StaticScene : public Scene {
-public:
- StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-// Scene1002
-
-class AsScene1002Ring : public AnimatedSprite {
-public:
- AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
-protected:
- Scene *_parentScene;
- bool _isSpecial;
- void update();
- uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002Door : public StaticSprite {
-public:
- AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
-protected:
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpenDoor();
- void suCloseDoor();
-};
-
-class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
-public:
- AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002DoorSpy : public AnimatedSprite {
-public:
- AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
-protected:
- Scene *_parentScene;
- Sprite *_asDoor;
- Sprite *_asBoxingGloveHitEffect;
- NRect _clipRect;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suDoorSpy();
- void stDoorSpyIdle();
- void stDoorSpyBoxingGlove();
-};
-
-class SsCommonPressButton : public StaticSprite {
-public:
- SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
- void setFileHashes(uint32 fileHash1, uint32 fileHash2);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHashes[2];
- int _status;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002VenusFlyTrap : public AnimatedSprite {
-public:
- AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _isSecond;
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
- void stWalkBack();
- void stWalk();
- void stRelease();
- void stGrabRing();
- void stRingGrabbed();
- void stKlaymenInside();
- void stIdle();
- void stKlaymenInsideMoving();
- void stSpitOutKlaymen();
- void swallowKlaymen();
-};
-
-class AsScene1002OutsideDoorBackground : public AnimatedSprite {
-public:
- AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isDoorClosed;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stDoorClosed();
-};
-
-class AsScene1002KlaymenLadderHands : public AnimatedSprite {
-public:
- AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
-protected:
- Klaymen *_klaymen;
- void update();
-};
-
-class AsScene1002KlaymenPeekHand : public AnimatedSprite {
-public:
- AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
-protected:
- Scene *_parentScene;
- Klaymen *_klaymen;
- bool _isClipRectSaved;
- NRect _savedClipRect;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1002 : public Scene {
public:
Scene1002(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -260,15 +81,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1004
-
-class AsScene1004TrashCan : public AnimatedSprite {
-public:
- AsScene1004TrashCan(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1004 : public Scene {
public:
Scene1004(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -281,8 +93,6 @@ protected:
void updatePaletteArea();
};
-// Scene1005
-
class Scene1005 : public Scene {
public:
Scene1005(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1000_sprites.cpp b/engines/neverhood/modules/module1000_sprites.cpp
new file mode 100644
index 0000000000..573474de02
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.cpp
@@ -0,0 +1,1632 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1000_sprites.h"
+
+namespace Neverhood {
+
+AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(800, 137, 242);
+ _x = 726;
+ _y = 440;
+ stShowIdleDoor();
+ loadSound(1, 0xED403E03);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Door::handleMessage);
+}
+
+uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ hammerHitsDoor();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return 0;
+}
+
+void AsScene1001Door::hammerHitsDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 0:
+ case 1:
+ playSound(0, 0x65482F03);
+ startAnimation(0x624C0498, 1, 3);
+ NextState(&AsScene1001Door::stShowIdleDoor);
+ break;
+ case 2:
+ playSound(1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorMove);
+ break;
+ default:
+ // Nothing
+ break;
+ }
+ incGlobalVar(V_DOOR_STATUS, 1);
+}
+
+void AsScene1001Door::stShowIdleDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 1:
+ startAnimation(0x624C0498, 4, -1);
+ _newStickFrameIndex = 4;
+ break;
+ case 2:
+ startAnimation(0x624C0498, 1, -1);
+ _newStickFrameIndex = 1;
+ break;
+ case 3:
+ stopAnimation();
+ setVisible(false);
+ break;
+ default:
+ startAnimation(0x624C0498, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ }
+}
+
+void AsScene1001Door::stBustedDoorMove() {
+ setGlobalVar(V_DOOR_BUSTED, 1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorGone);
+ _x = 30;
+}
+
+void AsScene1001Door::stBustedDoorGone() {
+ playSound(0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
+ : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
+
+ _x = 547;
+ _y = 206;
+ createSurface(900, 177, 192);
+ startAnimation(0x022C90D4, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Hammer::handleMessage);
+}
+
+uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x00352100)
+ sendMessage(_asDoor, 0x2000, 0);
+ else if (param.asInteger() == 0x0A1A0109)
+ playSound(0, 0x66410886);
+ break;
+ case 0x2000:
+ startAnimation(0x022C90D4, 1, -1);
+ playSound(0, 0xE741020A);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(100, 66, 129);
+ startAnimation(0xC68C2299, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Window::handleMessage);
+}
+
+uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0E0A1410)
+ playSound(0, 0x60803F10);
+ break;
+ case 0x2001:
+ startAnimation(0xC68C2299, 0, -1);
+ break;
+ case 0x3002:
+ SetMessageHandler(NULL);
+ setGlobalVar(V_WINDOW_OPEN, 1);
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(1010, 71, 73);
+ setDoDeltaX(deltaXType);
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ _x = x;
+ _y = y;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Lever::handleMessage);
+}
+
+uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x00C0C444)
+ sendMessage(_parentScene, 0x480F, 0);
+ else if (param.asInteger() == 0xC41A02C0)
+ playSound(0, 0x40581882);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x3002:
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ case 0x480F:
+ startAnimation(0x04A98C36, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
+
+ _priority = 1100;
+ _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
+ setVisible(false);
+ SetUpdateHandler(&SsCommonButtonSprite::update);
+ SetMessageHandler(&SsCommonButtonSprite::handleMessage);
+}
+
+void SsCommonButtonSprite::update() {
+ if (_countdown != 0 && (--_countdown) == 0)
+ setVisible(false);
+}
+
+uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ _countdown = 8;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
+
+ SetUpdateHandler(&AsScene1002Ring::update);
+
+ if (_isSpecial) {
+ createSurface(990, 68, 314);
+ if (isRingLow) {
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ } else {
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+ } else {
+ createSurface(990, 68, 138);
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+
+ setClipRect(0, clipY1, 640, 480);
+
+ _x = x;
+ _y = y;
+
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+
+}
+
+void AsScene1002Ring::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4806:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, 0x4806, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
+ startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
+ break;
+ case 0x480F:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, 0x480F, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
+ startAnimation(0x861A2020, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmRingIdle(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x05410F72)
+ playSound(0, 0x21EE40A9);
+ break;
+ case 0x3002:
+ startAnimation(0xA85C4011, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
+ : StaticSprite(vm, 1200) {
+
+ loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
+ setClipRect(clipRect);
+ SetUpdateHandler(&AsScene1002Door::update);
+ SetMessageHandler(&AsScene1002Door::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1002Door::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
+ SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
+ break;
+ case 0x4809:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
+ SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002Door::suOpenDoor() {
+ if (_y > 49) {
+ _y -= 8;
+ if (_y < 49) {
+ SetSpriteUpdate(NULL);
+ _y = 49;
+ }
+ _needRefresh = true;
+ }
+}
+
+void AsScene1002Door::suCloseDoor() {
+ if (_y < 239) {
+ _y += 8;
+ if (_y > 239) {
+ SetSpriteUpdate(NULL);
+ _y = 239;
+ }
+ _needRefresh = true;
+ }
+}
+
+AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface(1025, 88, 165);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
+}
+
+uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ _x = ((Sprite*)sender)->getX() - 98;
+ _y = ((Sprite*)sender)->getY() - 111;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
+ : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
+
+ createSurface(800, 136, 147);
+ setClipRect(clipRect);
+ suDoorSpy();
+ loadSound(0, 0xC0C40298);
+ startAnimation(0x586C1D48, 0, 0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+ SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
+}
+
+uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0xA61CA1C2)
+ sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
+ else if (param.asInteger() == 0x14CE0620)
+ playSound(0);
+ break;
+ case 0x2003:
+ stDoorSpyBoxingGlove();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002DoorSpy::suDoorSpy() {
+ _x = _asDoor->getX() + 34;
+ _y = _asDoor->getY() + 175;
+}
+
+void AsScene1002DoorSpy::stDoorSpyIdle() {
+ setClipRect(_clipRect);
+ _parentScene->setSurfacePriority(getSurface(), 800);
+ startAnimation(0x586C1D48, 0, 0);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+}
+
+void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
+ setClipRect(0, 0, 640, 480);
+ _parentScene->setSurfacePriority(getSurface(), 1200);
+ startAnimation(0x586C1D48, 1, -1);
+ SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
+ NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
+}
+
+SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
+
+ _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ createSurface(surfacePriority, 40, 40);
+ loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ setVisible(false);
+ SetUpdateHandler(&SsCommonPressButton::update);
+ SetMessageHandler(&SsCommonPressButton::handleMessage);
+}
+
+void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+void SsCommonPressButton::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (_status == 1) {
+ _status = 2;
+ loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 2) {
+ _status = 3;
+ loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 3) {
+ _status = 0;
+ setVisible(false);
+ }
+ }
+}
+
+uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ _status = 1;
+ _countdown = 4;
+ setVisible(true);
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
+
+ createSurface(995, 175, 195);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ setDoDeltaX(1);
+ _x = 366;
+ _y = 435;
+ stRingGrabbed();
+ } else {
+ _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
+ _y = 435;
+ stIdle();
+ }
+ } else {
+ _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
+ _y = 364;
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
+ stRingGrabbed();
+ } else {
+ stIdle();
+ }
+ }
+ _flags = 4;
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+void AsScene1002VenusFlyTrap::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ AnimatedSprite::update();
+}
+
+void AsScene1002VenusFlyTrap::upIdle() {
+ if (_countdown == 0 && _klaymen->getX() - 20 > _x)
+ setDoDeltaX(1);
+ else if (_klaymen->getX() + 20 < _x)
+ setDoDeltaX(0);
+ update();
+}
+
+uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case 0x1011:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ }
+ break;
+ case 0x480B:
+ setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR))
+ stRelease();
+ else
+ stWalk();
+ } else {
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
+ stRelease();
+ else
+ stWalk();
+ }
+ break;
+ case 0x480C:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ } else {
+ if (_x >= 174 && _x <= 430)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ }
+ break;
+ case 0x480E:
+ if (param.asInteger() == 1)
+ stGrabRing();
+ break;
+ case 0x4810:
+ swallowKlaymen();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 995);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x41881801) {
+ if (_isSecond) {
+ if (_x > 330)
+ sendMessage(_klaymen, 0x4811, 2);
+ else
+ sendMessage(_klaymen, 0x4811, 0);
+ } else {
+ sendMessage(_klaymen, 0x4811, 0);
+ }
+ } else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 995);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002VenusFlyTrap::stWalkBack() {
+ setDoDeltaX(2);
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stWalk() {
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stRelease() {
+ sendMessage(_parentScene, 0x4807, 0);
+ startAnimation(0x82292851, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stGrabRing() {
+ setDoDeltaX(1);
+ startAnimation(0x86A82A11, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
+}
+
+void AsScene1002VenusFlyTrap::stRingGrabbed() {
+ startAnimation(0xB5A86034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInside() {
+ startAnimation(0x31303094, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(NULL);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
+ _countdown = 24;
+}
+
+void AsScene1002VenusFlyTrap::stIdle() {
+ startAnimation(0xC8204250, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430)
+ setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ }
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
+ startAnimation(0x152920C4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
+}
+
+void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
+ startAnimation(0x84001117, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::swallowKlaymen() {
+ if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
+ if (_isSecond)
+ setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
+ else
+ setDoDeltaX(_x > 320 ? 1 : 0);
+ sendMessage(_klaymen, 0x2001, 0);
+ startAnimation(0x8C2C80D4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
+ }
+}
+
+AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _countdown(0), _isDoorClosed(true) {
+
+ createSurface(850, 186, 212);
+ _x = 320;
+ _y = 240;
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ startAnimation(0x004A4495, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (_isDoorClosed)
+ stCloseDoor();
+ else
+ stOpenDoor();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case 0x4808:
+ _isDoorClosed = false;
+ _countdown = 2;
+ break;
+ case 0x4809:
+ _isDoorClosed = true;
+ _countdown = 2;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002OutsideDoorBackground::stOpenDoor() {
+ startAnimation(0x004A4495, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::stCloseDoor() {
+ startAnimation(0x004A4495, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
+ NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
+}
+
+void AsScene1002OutsideDoorBackground::stDoorClosed() {
+ setVisible(false);
+ stopAnimation();
+}
+
+AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
+
+ createSurface(1200, 40, 163);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1002KlaymenLadderHands::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
+ startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
+ startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
+ _isClipRectSaved(false) {
+
+ createSurface(1000, 33, 41);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
+ SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
+}
+
+void AsScene1002KlaymenPeekHand::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
+ startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_parentScene, 0x1022, 1200);
+ _isClipRectSaved = true;
+ _savedClipRect = _surface->getClipRect();
+ setClipRect(0, 0, 640, 480);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_parentScene, 0x1022, 1000);
+ if (_isClipRectSaved)
+ setClipRect(_savedClipRect);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 330;
+ _y = 327;
+ createSurface(800, 56, 50);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1004TrashCan::handleMessage);
+}
+
+uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x225A8587)
+ playSound(0, 0x109AFC4C);
+ break;
+ case 0x2002:
+ startAnimation(0xEB312C11, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
+ {1, kIdlePickEar},
+ {2, kIdleWonderAbout}
+};
+
+KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+}
+
+uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 2)
+ GotoState(&KmScene1001::stSleeping);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1001::stPullHammerLever);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4836:
+ if (param.asInteger() == 1) {
+ sendMessage(_parentScene, 0x2002, 0);
+ GotoState(&KmScene1001::stWakeUp);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1001::stWakeUp() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x527AC970, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1001::stSleeping() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x5A38C110, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmSleeping);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1001::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x03060012) {
+ playSound(0, 0xC0238244);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1001::stPullHammerLever() {
+ if (!stStartAction(AnimationCallback(&KmScene1001::stPullHammerLever))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x00648953, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmPullHammerLever);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ }
+}
+
+uint32 KmScene1001::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209)
+ sendMessage(_attachedSprite, 0x480F, 0);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable1();
+}
+
+void KmScene1002::xUpdate() {
+ if (_x >= 250 && _x <= 435 && _y >= 420) {
+ if (_idleTableNum == 0) {
+ setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
+ _idleTableNum = 1;
+ }
+ } else if (_idleTableNum == 1) {
+ setKlaymenIdleTable1();
+ _idleTableNum = 0;
+ }
+}
+
+uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stStandIdleSpecial);
+ break;
+ case 0x2007:
+ _otherSprite = (Sprite*)param.asEntity();
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ if (param.asInteger() == 1)
+ GotoState(&KmScene1002::stJumpAndFall);
+ else if (param.asInteger() == 2)
+ GotoState(&KmScene1002::stDropFromRing);
+ break;
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4805:
+ switch (param.asInteger()) {
+ case 1:
+ GotoState(&KmScene1002::stJumpToRing1);
+ break;
+ case 2:
+ GotoState(&KmScene1002::stJumpToRing2);
+ break;
+ case 3:
+ GotoState(&KmScene1002::stJumpToRing3);
+ break;
+ case 4:
+ GotoState(&KmScene1002::stJumpToRing4);
+ break;
+ }
+ break;
+ case 0x480A:
+ GotoState(&KmScene1002::stMoveVenusFlyTrap);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1002::stJumpToRingVenusFlyTrap);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&KmScene1002::stPressDoorButton);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ startWalkToAttachedSpriteXDistance(param.asInteger());
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2005, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2005, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2005, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2006, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1002::setupJumpToRing() {
+ _acceptInput = false;
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRing);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ NextState(&KmScene1002::stHangOnRing);
+ sendMessage(_attachedSprite, 0x482B, 0);
+}
+
+uint32 KmScene1002::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x4806, 0);
+ _acceptInput = true;
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHangOnRing() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4829E0B8, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1002::stJumpToRing1() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing1))) {
+ _busyStatus = 0;
+ startAnimation(0xD82890BA, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRing2() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing2))) {
+ _busyStatus = 0;
+ startAnimation(0x900980B2, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRing3() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing3))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ startAnimation(0xBA1910B2, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ SetMessageHandler(&KmScene1002::hmJumpToRing3);
+ NextState(&KmScene1002::stHoldRing3);
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x4806, 0);
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHoldRing3() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4A293FB0, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHoldRing3);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1002::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ if (messageNum == 0x1008) {
+ stReleaseRing();
+ return 0;
+ }
+ return hmLowLevel(messageNum, param, sender);
+}
+
+void KmScene1002::stJumpToRing4() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing4))) {
+ _busyStatus = 0;
+ startAnimation(0xB8699832, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRingVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRingVenusFlyTrap))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x584984B4, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRingVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&KmScene1002::stLandOnFeet);
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x480F, 0);
+ } else if (param.asInteger() == 0x586B0300) {
+ sendMessage(_otherSprite, 0x480E, 1);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stJumpAndFall() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpAndFall))) {
+ sendMessage(_parentScene, 0x1024, 3);
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0xB93AB151, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpAndFall);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+ }
+}
+
+void KmScene1002::stDropFromRing() {
+ if (_attachedSprite) {
+ _x = _attachedSprite->getX();
+ sendMessage(_attachedSprite, 0x4807, 0);
+ _attachedSprite = NULL;
+ }
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x586984B1, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+}
+
+uint32 KmScene1002::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x1307050A) {
+ playSound(0, 0x40428A09);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stMoveVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stMoveVenusFlyTrap))) {
+ _busyStatus = 2;
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x5C01A870, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+ }
+}
+
+void KmScene1002::stContinueMovingVenusFlyTrap() {
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ startAnimationByHash(0x5C01A870, 0x01084280, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+}
+
+void KmScene1002::evMoveVenusFlyTrapDone() {
+ sendMessage(_attachedSprite, 0x482A, 0);
+}
+
+uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x01084280) {
+ sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
+ } else if (param.asInteger() == 0x02421405) {
+ if (_isMoveObjectRequested) {
+ if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
+ stContinueMovingVenusFlyTrap();
+ } else {
+ SetMessageHandler(&KmScene1002::hmFirstMoveVenusFlyTrap);
+ }
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ case 0x480A:
+ _isMoveObjectRequested = true;
+ return 0;
+ }
+ return hmLowLevelAnimation(messageNum, param, sender);
+}
+
+uint32 KmScene1002::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stPressDoorButton() {
+ _busyStatus = 2;
+ _acceptInput = true;
+ setDoDeltaX(0);
+ startAnimation(0x1CD89029, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmPressDoorButton);
+ SetSpriteUpdate(&Klaymen::suAction);
+}
+
+void KmScene1002::stHitByBoxingGlove() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHitByBoxingGlove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evHitByBoxingGloveDone);
+}
+
+void KmScene1002::evHitByBoxingGloveDone() {
+ sendMessage(_parentScene, 0x1024, 1);
+}
+
+uint32 KmScene1002::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x942D2081) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x2003, 0);
+ } else if (param.asInteger() == 0xDA600012) {
+ stHitByBoxingGlove();
+ } else if (param.asInteger() == 0x0D01B294) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x480B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene1002::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
+ int16 speedUpFrameIndex;
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 435;
+ }
+ messageResult = 0;
+ break;
+ case 0x100D:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x01900A04);
+}
+
+uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481E:
+ GotoState(&KmScene1004::stReadNote);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4828:
+ GotoState(&Klaymen::stTurnToBackToUse);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene1004::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x04684052) {
+ _acceptInput = true;
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1004::stReadNote() {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x123E9C9F, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1004::hmReadNote);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1000_sprites.h b/engines/neverhood/modules/module1000_sprites.h
new file mode 100644
index 0000000000..564b3cc335
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.h
@@ -0,0 +1,262 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1001Door : public AnimatedSprite {
+public:
+ AsScene1001Door(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void hammerHitsDoor();
+ void stShowIdleDoor();
+ void stBustedDoorMove();
+ void stBustedDoorGone();
+};
+
+class AsScene1001Hammer : public AnimatedSprite {
+public:
+ AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
+protected:
+ Sprite *_asDoor;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Window : public AnimatedSprite {
+public:
+ AsScene1001Window(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Lever : public AnimatedSprite {
+public:
+ AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonButtonSprite : public StaticSprite {
+public:
+ SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Ring : public AnimatedSprite {
+public:
+ AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
+protected:
+ Scene *_parentScene;
+ bool _isSpecial;
+ void update();
+ uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Door : public StaticSprite {
+public:
+ AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
+protected:
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpenDoor();
+ void suCloseDoor();
+};
+
+class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
+public:
+ AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002DoorSpy : public AnimatedSprite {
+public:
+ AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
+protected:
+ Scene *_parentScene;
+ Sprite *_asDoor;
+ Sprite *_asBoxingGloveHitEffect;
+ NRect _clipRect;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suDoorSpy();
+ void stDoorSpyIdle();
+ void stDoorSpyBoxingGlove();
+};
+
+class SsCommonPressButton : public StaticSprite {
+public:
+ SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+ void setFileHashes(uint32 fileHash1, uint32 fileHash2);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHashes[2];
+ int _status;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002VenusFlyTrap : public AnimatedSprite {
+public:
+ AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isSecond;
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
+ void stWalkBack();
+ void stWalk();
+ void stRelease();
+ void stGrabRing();
+ void stRingGrabbed();
+ void stKlaymenInside();
+ void stIdle();
+ void stKlaymenInsideMoving();
+ void stSpitOutKlaymen();
+ void swallowKlaymen();
+};
+
+class AsScene1002OutsideDoorBackground : public AnimatedSprite {
+public:
+ AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isDoorClosed;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stDoorClosed();
+};
+
+class AsScene1002KlaymenLadderHands : public AnimatedSprite {
+public:
+ AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
+protected:
+ Klaymen *_klaymen;
+ void update();
+};
+
+class AsScene1002KlaymenPeekHand : public AnimatedSprite {
+public:
+ AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
+protected:
+ Scene *_parentScene;
+ Klaymen *_klaymen;
+ bool _isClipRectSaved;
+ NRect _savedClipRect;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1004TrashCan : public AnimatedSprite {
+public:
+ AsScene1004TrashCan(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1001 : public Klaymen {
+public:
+ KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stWakeUp();
+ void stSleeping();
+ void stPullHammerLever();
+ uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1002 : public Klaymen {
+public:
+ KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stJumpToRing1();
+ void stJumpToRing2();
+ void stJumpToRing3();
+ void stJumpToRing4();
+ void setupJumpToRing();
+ void stHangOnRing();
+ void stHoldRing3();
+ void stDropFromRing();
+ void stJumpToRingVenusFlyTrap();
+ void stJumpAndFall();
+ void stMoveVenusFlyTrap();
+ void stContinueMovingVenusFlyTrap();
+ void evMoveVenusFlyTrapDone();
+ void stPressDoorButton();
+ void stHitByBoxingGlove();
+ void evHitByBoxingGloveDone();
+
+ uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender);
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1004 : public Klaymen {
+public:
+ KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stReadNote();
+ uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1000_SPRITES_H */
diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp
index 5a5e52e5b0..af2df2e742 100644
--- a/engines/neverhood/modules/module1100.cpp
+++ b/engines/neverhood/modules/module1100.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1100.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1100.h"
+#include "neverhood/modules/module1100_sprites.h"
namespace Neverhood {
@@ -40,7 +41,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) {
@@ -64,7 +65,8 @@ Module1100::~Module1100() {
void Module1100::createScene(int sceneNum, int which) {
static const uint32 kSmackerFileHashList06[] = {0x10880805, 0x1088081D, 0};
static const uint32 kSmackerFileHashList07[] = {0x00290321, 0x01881000, 0};
- debug("Module1100::createScene(%d, %d)", sceneNum, which);
+ static const byte kNavigationTypes02[] = {1, 0, 4, 1};
+ debug(1, "Module1100::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -80,9 +82,9 @@ void Module1100::createScene(int sceneNum, int which) {
case 2:
_vm->gameState().sceneNum = 2;
if (getGlobalVar(V_ROBOT_TARGET)) {
- createNavigationScene(0x004B84F0, which);
+ createNavigationScene(0x004B84F0, which, kNavigationTypes02);
} else {
- createNavigationScene(0x004B8490, which);
+ createNavigationScene(0x004B8490, which, kNavigationTypes02);
}
break;
case 3:
@@ -235,6 +237,13 @@ void Module1100::updateScene() {
}
}
+static const uint32 kScene1105BackgroundFileHashes[] = {
+ 0x20018662,
+ 0x20014202,
+ 0x20012202,
+ 0x20010002 // CHECKME: This used ??
+};
+
static const uint32 kScene1105FileHashes[] = {
0x00028006,
0x0100A425,
@@ -248,209 +257,29 @@ static const uint32 kScene1105FileHashes[] = {
0xB14A891E
};
-static const uint32 kScene1105BackgroundFileHashes[] = {
- 0x20018662,
- 0x20014202,
- 0x20012202,
- 0x20010002 // CHECKME: This used ??
-};
-
-static const uint32 kSsScene1105SymbolDieFileHashes[] = {
- 0,
- 0x90898414,
- 0x91098414,
- 0x92098414,
- 0x94098414,
- 0x98098414,
- 0x80098414,
- 0xB0098414,
- 0xD0098414,
- 0x10098414
-};
-
-SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
- : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
-
- _collisionBounds = collisionBounds;
- SetMessageHandler(&SsScene1105Button::handleMessage);
- SetUpdateHandler(&SsScene1105Button::update);
- setVisible(false);
-}
-
-void SsScene1105Button::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x4807, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- }
- break;
- case 0x480B:
- _countdown = 8;
- setVisible(true);
- playSound(0, 0x44141000);
- break;
- }
- return messageResult;
-}
-
-SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
-}
-
-void SsScene1105Symbol::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
- : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
-
- _x = x;
- _y = y;
- createSurface(200, 50, 50);
- loadSymbolSprite();
- SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
-}
-
-uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSymbolSprite();
- break;
- }
- return messageResult;
-}
-
-void SsScene1105SymbolDie::loadSymbolSprite() {
- loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
-}
-
-void SsScene1105SymbolDie::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(100, 556, 328);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
- startAnimation(0x65084002, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- updatePosition();
- loadSound(0, 0xCE840261);
- loadSound(1, 0xCCA41A62);
-}
-
-uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- if (getGlobalVar(V_ROBOT_TARGET)) {
- startAnimation(0x6B0C0432, 0, -1);
- playSound(0);
- } else {
- startAnimation(0x65084002, 0, -1);
- playSound(1);
- }
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- break;
- }
- return messageResult;
-}
-
-void AsScene1105TeddyBear::show() {
- setVisible(true);
- _needRefresh = true;
- updatePosition();
-}
-
-void AsScene1105TeddyBear::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
-
- loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44045140);
- SetUpdateHandler(&SsScene1105OpenButton::update);
- SetMessageHandler(&SsScene1105OpenButton::handleMessage);
-}
-
-void SsScene1105OpenButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2001, 0);
- }
-}
-
-uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isClicked) {
- playSound(0);
- setVisible(true);
- _isClicked = true;
- _countdown = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
-
+
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) {
@@ -465,7 +294,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
_backgroundIndex = 15;
SetUpdateHandler(&Scene1105::upClosePanel);
} else
- _isPanelOpen = true;
+ _isClosePanelDone = true;
_leaveResult = 0;
}
}
@@ -554,27 +383,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() {
@@ -625,13 +454,6 @@ void Scene1105::upClosePanel() {
}
void Scene1105::update() {
-
- // DEBUG: Show the correct code
- debug("(%d, %d) (%d, %d) (%d, %d)",
- getSubVar(VA_GOOD_DICE_NUMBERS, 0), getSubVar(VA_CURR_DICE_NUMBERS, 0),
- getSubVar(VA_GOOD_DICE_NUMBERS, 1), getSubVar(VA_CURR_DICE_NUMBERS, 1),
- getSubVar(VA_GOOD_DICE_NUMBERS, 2), getSubVar(VA_CURR_DICE_NUMBERS, 2));
-
Scene::update();
if (_countdown != 0 && (--_countdown == 0))
createObjects();
@@ -645,13 +467,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/module1100.h b/engines/neverhood/modules/module1100.h
index 373f6b703f..38bac1f298 100644
--- a/engines/neverhood/modules/module1100.h
+++ b/engines/neverhood/modules/module1100.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1100
-
class Module1100 : public Module {
public:
Module1100(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,52 +40,9 @@ protected:
void updateScene();
};
-class SsScene1105Button : public StaticSprite {
-public:
- SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105Symbol : public StaticSprite {
-public:
- SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
- void hide();
-};
-
-class SsScene1105SymbolDie : public StaticSprite {
-public:
- SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
- void hide();
-protected:
- uint _dieIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void loadSymbolSprite();
-};
-
-class AsScene1105TeddyBear : public AnimatedSprite {
-public:
- AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
- void show();
- void hide();
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105OpenButton : public StaticSprite {
-public:
- SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1105TeddyBear;
+class SsScene1105Symbol;
+class SsScene1105SymbolDie;
class Scene1105 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1100_sprites.cpp b/engines/neverhood/modules/module1100_sprites.cpp
new file mode 100644
index 0000000000..51e0bb3f49
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.cpp
@@ -0,0 +1,265 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1100_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene1105SymbolDieFileHashes[] = {
+ 0,
+ 0x90898414,
+ 0x91098414,
+ 0x92098414,
+ 0x94098414,
+ 0x98098414,
+ 0x80098414,
+ 0xB0098414,
+ 0xD0098414,
+ 0x10098414
+};
+
+SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
+ : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
+
+ _collisionBounds = collisionBounds;
+ SetMessageHandler(&SsScene1105Button::handleMessage);
+ SetUpdateHandler(&SsScene1105Button::update);
+ setVisible(false);
+}
+
+void SsScene1105Button::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, 0x4807, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ }
+ break;
+ case 0x480B:
+ _countdown = 8;
+ setVisible(true);
+ playSound(0, 0x44141000);
+ break;
+ }
+ return messageResult;
+}
+
+SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
+}
+
+void SsScene1105Symbol::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
+ : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
+
+ _x = x;
+ _y = y;
+ createSurface(200, 50, 50);
+ loadSymbolSprite();
+ SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
+}
+
+uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ loadSymbolSprite();
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1105SymbolDie::loadSymbolSprite() {
+ loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
+}
+
+void SsScene1105SymbolDie::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(100, 556, 328);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
+ startAnimation(0x65084002, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+ loadSound(0, 0xCE840261);
+ loadSound(1, 0xCCA41A62);
+}
+
+uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ if (getGlobalVar(V_ROBOT_TARGET)) {
+ startAnimation(0x6B0C0432, 0, -1);
+ playSound(0);
+ } else {
+ startAnimation(0x65084002, 0, -1);
+ playSound(1);
+ }
+ break;
+ case 0x3002:
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1105TeddyBear::show() {
+ setVisible(true);
+ _needRefresh = true;
+ updatePosition();
+}
+
+void AsScene1105TeddyBear::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
+
+ loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44045140);
+ SetUpdateHandler(&SsScene1105OpenButton::update);
+ SetMessageHandler(&SsScene1105OpenButton::handleMessage);
+}
+
+void SsScene1105OpenButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2001, 0);
+ }
+}
+
+uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isClicked) {
+ playSound(0);
+ setVisible(true);
+ _isClicked = true;
+ _countdown = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x2C2A4A1C);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x3C2E4245);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1100_sprites.h b/engines/neverhood/modules/module1100_sprites.h
new file mode 100644
index 0000000000..c8e5a838da
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1105Button : public StaticSprite {
+public:
+ SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105Symbol : public StaticSprite {
+public:
+ SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
+ void hide();
+};
+
+class SsScene1105SymbolDie : public StaticSprite {
+public:
+ SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
+ void hide();
+protected:
+ uint _dieIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void loadSymbolSprite();
+};
+
+class AsScene1105TeddyBear : public AnimatedSprite {
+public:
+ AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
+ void show();
+ void hide();
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105OpenButton : public StaticSprite {
+public:
+ SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1109 : public Klaymen {
+public:
+ KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1100_SPRITES_H */
diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp
index 3be3635645..975545091d 100644
--- a/engines/neverhood/modules/module1200.cpp
+++ b/engines/neverhood/modules/module1200.cpp
@@ -21,12 +21,13 @@
*/
#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module1200_sprites.h"
namespace Neverhood {
Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
SetMessageHandler(&Module1200::handleMessage);
if (which < 0)
@@ -45,7 +46,7 @@ Module1200::~Module1200() {
}
void Module1200::createScene(int sceneNum, int which) {
- debug("Module1200::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1200::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -92,566 +93,10 @@ void Module1200::updateScene() {
}
}
-// Scene1201
-
static const uint32 kScene1201InitArray[] = {
1, 0, 2, 4, 5, 3, 6, 7, 8, 10, 9, 11, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1201PointArray[] = {
- {218, 193}, {410, 225}, {368, 277},
- {194, 227}, {366, 174}, {458, 224},
- {242, 228}, {512, 228}, {458, 277},
- {217, 233}, {458, 173}, {410, 276},
- {203, 280}, {371, 226}, {508, 279},
- {230, 273}, {410, 171}, {493, 174}
-};
-
-static const uint32 kScene1201TntFileHashList1[] = {
- 0x2098212D, 0x1600437E, 0x1600437E,
- 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
- 0x00212062, 0x384010B6, 0x384010B6,
- 0x07A01080, 0xD80C2837, 0xD80C2837,
- 0x03A22092, 0xD8802CB6, 0xD8802CB6,
- 0x03A93831, 0xDA460476, 0xDA460476
-};
-
-static const uint32 kScene1201TntFileHashList2[] = {
- 0x3040C676, 0x10914448, 0x10914448,
- 0x3448A066, 0x1288C049, 0x1288C049,
- 0x78C0E026, 0x3098D05A, 0x3098D05A,
- 0x304890E6, 0x1284E048, 0x1284E048,
- 0xB140A1E6, 0x5088A068, 0x5088A068,
- 0x74C4C866, 0x3192C059, 0x3192C059
-};
-
-SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
- : StaticSprite(vm, 900) {
-
- int16 x = kScene1201PointArray[pointIndex].x;
- int16 y = kScene1201PointArray[pointIndex].y;
- if (x < 300)
- loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
- else
- loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y);
- setClipRect(0, 0, 640, clipY2);
-}
-
-AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
-
- if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
- SetMessageHandler(&AsScene1201Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _nameHash, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
- : AnimatedSprite(vm, 1200) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntManRope::handleMessage);
- createSurface(10, 34, 149);
- _x = 202;
- _y = -32;
- if (isDummyHanging) {
- startAnimation(0x928F0C10, 15, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0x928F0C10, 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0x47900E06);
- break;
- case 0x2006:
- startAnimation(0x928F0C10, 1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return messageResult;
-}
-
-AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
-
- createSurface1(0xD088AC30, 100);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AsScene1201RightDoor::update);
- SetMessageHandler(&AsScene1201RightDoor::handleMessage);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (isOpen) {
- startAnimation(0xD088AC30, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 25;
- } else {
- stopAnimation();
- setVisible(false);
- }
-}
-
-void AsScene1201RightDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4829:
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201RightDoor::stOpenDoor() {
- startAnimation(0xD088AC30, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen20"));
-}
-
-void AsScene1201RightDoor::stCloseDoor() {
- startAnimation(0xD088AC30, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose20"));
- NextState(&AsScene1201RightDoor::stCloseDoorDone);
-}
-
-void AsScene1201RightDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- createSurface(1200, 69, 98);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- setVisible(false);
-}
-
-uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- _x = 436;
- _y = 339;
- startAnimation(0xA060C599, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
- _isMoving(false) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- createSurface(990, 106, 181);
- _x = 201;
- if (isComingDown) {
- _y = 297;
- stComingDown();
- } else {
- _y = 334;
- stStanding();
- }
-}
-
-AsScene1201TntMan::~AsScene1201TntMan() {
- _vm->_soundMan->deleteSoundGroup(0x01D00560);
-}
-
-uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x092870C0)
- sendMessage(_asTntManRope, 0x2006, 0);
- else if (param.asInteger() == 0x11CA0144)
- playSound(0, 0x51800A04);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x2002, 0);
- messageResult = 1;
- break;
- case 0x480B:
- if (!_isMoving) {
- _sprite = (Sprite*)sender;
- stMoving();
- }
- break;
- }
- return messageResult;
-
-}
-
-uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201TntMan::suMoving() {
- _x = _sprite->getX() + 100;
-}
-
-void AsScene1201TntMan::stStanding() {
- startAnimation(0x654913D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1201TntMan::stComingDown() {
- startAnimation(0x356803D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::hmComingDown);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&AsScene1201TntMan::stStanding);
-}
-
-void AsScene1201TntMan::stMoving() {
- _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
- _vm->_soundMan->playSoundLooping(0x4B044624);
- _isMoving = true;
- startAnimation(0x85084190, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(&AsScene1201TntMan::suMoving);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
- : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
-
- createSurface1(0x828C0411, 995);
- SetUpdateHandler(&AsScene1201TntManFlame::update);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
- startAnimation(0x828C0411, 0, -1);
- setVisible(false);
-}
-
-AsScene1201TntManFlame::~AsScene1201TntManFlame() {
- _vm->_soundMan->deleteSoundGroup(0x041080A4);
-}
-
-void AsScene1201TntManFlame::update() {
- AnimatedSprite::update();
- if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
- setVisible(true);
- SetUpdateHandler(&AnimatedSprite::update);
- _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
- _vm->_soundMan->playSoundLooping(0x460A1050);
- }
-}
-
-void AsScene1201TntManFlame::suUpdate() {
- _x = _asTntMan->getX() - 18;
- _y = _asTntMan->getY() - 158;
-}
-
-AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
-
- createSurface(1100, 57, 60);
- SetUpdateHandler(&AsScene1201Match::update);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- switch (getGlobalVar(V_MATCH_STATUS)) {
- case 0:
- _x = 521;
- _y = 112;
- _status = 0;
- stIdleOnDoorFrame();
- break;
- case 1:
- _x = 521;
- _y = 112;
- _status = 2;
- stOnDoorFrameAboutToMove();
- loadSound(0, 0xD00230CD);
- break;
- case 2:
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- _status = 0;
- stIdleOnFloor();
- break;
- }
-}
-
-void AsScene1201Match::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x86668011)
- playSound(0);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setVisible(false);
- setGlobalVar(V_MATCH_STATUS, 3);
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Match::stOnDoorFrameMoving() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- if (_status == 0) {
- NextState(&AsScene1201Match::stFallingFromDoorFrame);
- } else {
- NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
- }
-}
-
-void AsScene1201Match::stFallingFromDoorFrame() {
- setGlobalVar(V_MATCH_STATUS, 2);
- _x -= 199;
- _y += 119;
- startAnimation(0x018D0240, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- NextState(&AsScene1201Match::stIdleOnFloor);
-}
-
-void AsScene1201Match::stOnDoorFrameAboutToMove() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- _newStickFrameIndex = 0;
- if (_status != 0) {
- _countdown = 36;
- _status--;
- NextState(&AsScene1201Match::stOnDoorFrameMoving);
- }
-}
-
-void AsScene1201Match::stIdleOnDoorFrame() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1201Match::stIdleOnFloor() {
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
-
- // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
-
- createSurface(1100, 203, 199);
- SetUpdateHandler(&AsScene1201Creature::update);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _x = 540;
- _y = 320;
- stWaiting();
-}
-
-void AsScene1201Creature::update() {
- bool oldKlaymenTooClose = _klaymenTooClose;
- _klaymenTooClose = _klaymen->getX() >= 385;
- if (_klaymenTooClose != oldKlaymenTooClose)
- stWaiting();
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0xCD298116);
- break;
- case 0x2004:
- GotoState(&AsScene1201Creature::stStartReachForTntDummy);
- break;
- case 0x2006:
- GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmWaiting(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018) {
- playSound(0, 0xCD298116);
- sendMessage(_parentScene, 0x4814, 0);
- sendMessage(_klaymen, 0x4814, 0);
- }
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Creature::stWaiting() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stPincerSnap);
- _countdown = 36;
-}
-
-void AsScene1201Creature::stPincerSnap() {
- if (!_klaymenTooClose) {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
- NextState(&AsScene1201Creature::stWaiting);
- }
-}
-
-void AsScene1201Creature::stStartReachForTntDummy() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stReachForTntDummy);
- _countdown = 48;
-}
-
-void AsScene1201Creature::stReachForTntDummy() {
- startAnimation(0x5A201453, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _countdown = 0;
-}
-
-void AsScene1201Creature::stPincerSnapKlaymen() {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
- NextState(&AsScene1201Creature::stWaiting);
- _countdown = 0;
-}
-
-AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
-
- _x = 320;
- _y = 240;
- createSurface(800, 55, 199);
- if (_klaymen->getX() < 100) {
- startAnimation(0x508A111B, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen03"));
- } else {
- startAnimation(0x508A111B, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
-}
-
-uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201LeftDoor::stCloseDoor() {
- startAnimation(0x508A111B, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _creatureExploded(false), _asMatch(NULL), _asTntMan(NULL),
_asCreature(NULL), _asTntManRope(NULL), _asLeftDoor(NULL), _asRightDoor(NULL), _asTape(NULL) {
@@ -664,7 +109,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 +117,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 +180,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 +201,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 +228,10 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004AEE58);
} else {
setRectList(0x004AEDC8);
- }
-
+ }
+
} else {
-
+
insertStaticSprite(0x8E8A1981, 900);
uint32 tntIndex = 0;
@@ -795,7 +240,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 +256,7 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004AEE18);
else
setRectList(0x004AED88);
-
+
}
tempSprite = insertStaticSprite(0x63D400BC, 900);
@@ -875,7 +320,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,102 +348,17 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x8000:
sendMessage(_asKlaymenHead, 0x2006, 0);
- break;
+ break;
}
return messageResult;
}
-// Scene1202
-
static const uint32 kScene1202Table[] = {
1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1202Points[] = {
- {203, 140}, {316, 212}, {277, 264},
- {176, 196}, {275, 159}, {366, 212},
- {230, 195}, {412, 212}, {368, 263},
- {204, 192}, {365, 164}, {316, 262},
- {191, 255}, {280, 213}, {406, 266},
- {214, 254}, {316, 158}, {402, 161}
-};
-
-static const uint32 kScene1202FileHashes[] = {
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
-};
-
-AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
-
- int positionIndex;
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
- createSurface(900, 37, 67);
- _x = kScene1202Points[positionIndex].x;
- _y = kScene1202Points[positionIndex].y;
- stShowIdle();
-}
-
-uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2000, _itemIndex);
- messageResult = 1;
- break;
- case 0x2001:
- _newPosition = (int)param.asInteger();
- stChangePositionFadeOut();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1202TntItem::stShowIdle() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1202TntItem::stChangePositionFadeOut() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionFadeIn);
-}
-
-void AsScene1202TntItem::stChangePositionFadeIn() {
- _x = kScene1202Points[_newPosition].x;
- _y = kScene1202Points[_newPosition].y;
- startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
- _playBackwards = true;
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionDone);
-}
-
-void AsScene1202TntItem::stChangePositionDone() {
- sendMessage(_parentScene, 0x2002, _itemIndex);
- stShowIdle();
-}
-
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule), _paletteResource(vm),
+ : Scene(vm, parentModule), _paletteResource(vm),
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
SetMessageHandler(&Scene1202::handleMessage);
@@ -1093,8 +453,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/module1200.h b/engines/neverhood/modules/module1200.h
index c97dc98986..d9d4dd11f2 100644
--- a/engines/neverhood/modules/module1200.h
+++ b/engines/neverhood/modules/module1200.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1200
-
class Module1200 : public Module {
public:
Module1200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -41,123 +39,7 @@ protected:
void updateScene();
};
-// Scene1201
-
-class AsScene1201Tape : public AnimatedSprite {
-public:
- AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _nameHash;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntManRope : public AnimatedSprite {
-public:
- AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201RightDoor : public AnimatedSprite {
-public:
- AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1201KlaymenHead : public AnimatedSprite {
-public:
- AsScene1201KlaymenHead(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntMan : public AnimatedSprite {
-public:
- AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
- virtual ~AsScene1201TntMan();
-protected:
- Scene *_parentScene;
- Sprite *_asTntManRope;
- Sprite *_sprite;
- bool _isMoving;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void stStanding();
- void stComingDown();
- void stMoving();
-};
-
-class AsScene1201TntManFlame : public AnimatedSprite {
-public:
- AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
- ~AsScene1201TntManFlame();
-protected:
- Sprite *_asTntMan;
- void update();
- void suUpdate();
-};
-
-class AsScene1201Match : public AnimatedSprite {
-public:
- AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- int _status;
- void update();
- uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
- void stOnDoorFrameMoving();
- void stFallingFromDoorFrame();
- void stOnDoorFrameAboutToMove();
- void stIdleOnDoorFrame();
- void stIdleOnFloor();
-};
-
-class AsScene1201Creature : public AnimatedSprite {
-public:
- AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _klaymenTooClose;
- void update();
- uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
- void stWaiting();
- void stPincerSnap();
- void stStartReachForTntDummy();
- void stReachForTntDummy();
- void stPincerSnapKlaymen();
-};
-
-class AsScene1201LeftDoor : public AnimatedSprite {
-public:
- AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stCloseDoor();
-};
-
-class SsScene1201Tnt : public StaticSprite {
-public:
- SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
-protected:
- uint32 _elemIndex;
-};
+class AsScene1201TntMan;
class Scene1201 : public Scene {
public:
@@ -177,22 +59,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1202
-
-class AsScene1202TntItem : public AnimatedSprite {
-public:
- AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
-protected:
- Scene *_parentScene;
- int _itemIndex, _newPosition;
- uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
- void stShowIdle();
- void stChangePositionFadeOut();
- void stChangePositionFadeIn();
- void stChangePositionDone();
-};
-
class Scene1202 : public Scene {
public:
Scene1202(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1200_sprites.cpp b/engines/neverhood/modules/module1200_sprites.cpp
new file mode 100644
index 0000000000..da38924d9a
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.cpp
@@ -0,0 +1,810 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1200_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kScene1201TntFileHashList1[] = {
+ 0x2098212D, 0x1600437E, 0x1600437E,
+ 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
+ 0x00212062, 0x384010B6, 0x384010B6,
+ 0x07A01080, 0xD80C2837, 0xD80C2837,
+ 0x03A22092, 0xD8802CB6, 0xD8802CB6,
+ 0x03A93831, 0xDA460476, 0xDA460476
+};
+
+static const uint32 kScene1201TntFileHashList2[] = {
+ 0x3040C676, 0x10914448, 0x10914448,
+ 0x3448A066, 0x1288C049, 0x1288C049,
+ 0x78C0E026, 0x3098D05A, 0x3098D05A,
+ 0x304890E6, 0x1284E048, 0x1284E048,
+ 0xB140A1E6, 0x5088A068, 0x5088A068,
+ 0x74C4C866, 0x3192C059, 0x3192C059
+};
+
+SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
+ : StaticSprite(vm, 900) {
+
+ int16 x = kScene1201PointArray[pointIndex].x;
+ int16 y = kScene1201PointArray[pointIndex].y;
+ if (x < 300)
+ loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
+ else
+ loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
+ setClipRect(0, 0, 640, clipY2);
+}
+
+AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
+
+ if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
+ SetMessageHandler(&AsScene1201Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_TAPE, _nameHash, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
+ : AnimatedSprite(vm, 1200) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntManRope::handleMessage);
+ createSurface(10, 34, 149);
+ _x = 202;
+ _y = -32;
+ if (isDummyHanging) {
+ startAnimation(0x928F0C10, 15, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0x928F0C10, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0x47900E06);
+ break;
+ case 0x2006:
+ startAnimation(0x928F0C10, 1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
+
+ createSurface1(0xD088AC30, 100);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AsScene1201RightDoor::update);
+ SetMessageHandler(&AsScene1201RightDoor::handleMessage);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (isOpen) {
+ startAnimation(0xD088AC30, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 25;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+}
+
+void AsScene1201RightDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4829:
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201RightDoor::stOpenDoor() {
+ startAnimation(0xD088AC30, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen20"));
+}
+
+void AsScene1201RightDoor::stCloseDoor() {
+ startAnimation(0xD088AC30, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose20"));
+ NextState(&AsScene1201RightDoor::stCloseDoorDone);
+}
+
+void AsScene1201RightDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ createSurface(1200, 69, 98);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ setVisible(false);
+}
+
+uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2006:
+ _x = 436;
+ _y = 339;
+ startAnimation(0xA060C599, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
+ _isMoving(false) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ createSurface(990, 106, 181);
+ _x = 201;
+ if (isComingDown) {
+ _y = 297;
+ stComingDown();
+ } else {
+ _y = 334;
+ stStanding();
+ }
+}
+
+AsScene1201TntMan::~AsScene1201TntMan() {
+ _vm->_soundMan->deleteSoundGroup(0x01D00560);
+}
+
+uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x092870C0)
+ sendMessage(_asTntManRope, 0x2006, 0);
+ else if (param.asInteger() == 0x11CA0144)
+ playSound(0, 0x51800A04);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x2002, 0);
+ messageResult = 1;
+ break;
+ case 0x480B:
+ if (!_isMoving) {
+ _sprite = (Sprite*)sender;
+ stMoving();
+ }
+ break;
+ }
+ return messageResult;
+
+}
+
+uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201TntMan::suMoving() {
+ _x = _sprite->getX() + 100;
+}
+
+void AsScene1201TntMan::stStanding() {
+ startAnimation(0x654913D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1201TntMan::stComingDown() {
+ startAnimation(0x356803D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::hmComingDown);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&AsScene1201TntMan::stStanding);
+}
+
+void AsScene1201TntMan::stMoving() {
+ _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
+ _vm->_soundMan->playSoundLooping(0x4B044624);
+ _isMoving = true;
+ startAnimation(0x85084190, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntMan::suMoving);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
+ : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
+
+ createSurface1(0x828C0411, 995);
+ SetUpdateHandler(&AsScene1201TntManFlame::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
+ startAnimation(0x828C0411, 0, -1);
+ setVisible(false);
+}
+
+AsScene1201TntManFlame::~AsScene1201TntManFlame() {
+ _vm->_soundMan->deleteSoundGroup(0x041080A4);
+}
+
+void AsScene1201TntManFlame::update() {
+ AnimatedSprite::update();
+ if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
+ setVisible(true);
+ SetUpdateHandler(&AnimatedSprite::update);
+ _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
+ _vm->_soundMan->playSoundLooping(0x460A1050);
+ }
+}
+
+void AsScene1201TntManFlame::suUpdate() {
+ _x = _asTntMan->getX() - 18;
+ _y = _asTntMan->getY() - 158;
+}
+
+AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
+
+ createSurface(1100, 57, 60);
+ SetUpdateHandler(&AsScene1201Match::update);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ switch (getGlobalVar(V_MATCH_STATUS)) {
+ case 0:
+ _x = 521;
+ _y = 112;
+ _status = 0;
+ stIdleOnDoorFrame();
+ break;
+ case 1:
+ _x = 521;
+ _y = 112;
+ _status = 2;
+ stOnDoorFrameAboutToMove();
+ loadSound(0, 0xD00230CD);
+ break;
+ case 2:
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ _status = 0;
+ stIdleOnFloor();
+ break;
+ }
+}
+
+void AsScene1201Match::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x86668011)
+ playSound(0);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setVisible(false);
+ setGlobalVar(V_MATCH_STATUS, 3);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Match::stOnDoorFrameMoving() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ if (_status == 0) {
+ NextState(&AsScene1201Match::stFallingFromDoorFrame);
+ } else {
+ NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
+ }
+}
+
+void AsScene1201Match::stFallingFromDoorFrame() {
+ setGlobalVar(V_MATCH_STATUS, 2);
+ _x -= 199;
+ _y += 119;
+ startAnimation(0x018D0240, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ NextState(&AsScene1201Match::stIdleOnFloor);
+}
+
+void AsScene1201Match::stOnDoorFrameAboutToMove() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ _newStickFrameIndex = 0;
+ if (_status != 0) {
+ _countdown = 36;
+ _status--;
+ NextState(&AsScene1201Match::stOnDoorFrameMoving);
+ }
+}
+
+void AsScene1201Match::stIdleOnDoorFrame() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1201Match::stIdleOnFloor() {
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
+
+ // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
+
+ createSurface(1100, 203, 199);
+ SetUpdateHandler(&AsScene1201Creature::update);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _x = 540;
+ _y = 320;
+ stWaiting();
+}
+
+void AsScene1201Creature::update() {
+ bool oldKlaymenTooClose = _klaymenTooClose;
+ _klaymenTooClose = _klaymen->getX() >= 385;
+ if (_klaymenTooClose != oldKlaymenTooClose)
+ stWaiting();
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0xCD298116);
+ break;
+ case 0x2004:
+ GotoState(&AsScene1201Creature::stStartReachForTntDummy);
+ break;
+ case 0x2006:
+ GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmWaiting(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018) {
+ playSound(0, 0xCD298116);
+ sendMessage(_parentScene, 0x4814, 0);
+ sendMessage(_klaymen, 0x4814, 0);
+ }
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Creature::stWaiting() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stPincerSnap);
+ _countdown = 36;
+}
+
+void AsScene1201Creature::stPincerSnap() {
+ if (!_klaymenTooClose) {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
+ NextState(&AsScene1201Creature::stWaiting);
+ }
+}
+
+void AsScene1201Creature::stStartReachForTntDummy() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stReachForTntDummy);
+ _countdown = 48;
+}
+
+void AsScene1201Creature::stReachForTntDummy() {
+ startAnimation(0x5A201453, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _countdown = 0;
+}
+
+void AsScene1201Creature::stPincerSnapKlaymen() {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
+ NextState(&AsScene1201Creature::stWaiting);
+ _countdown = 0;
+}
+
+AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(800, 55, 199);
+ if (_klaymen->getX() < 100) {
+ startAnimation(0x508A111B, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen03"));
+ } else {
+ startAnimation(0x508A111B, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
+}
+
+uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201LeftDoor::stCloseDoor() {
+ startAnimation(0x508A111B, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+static const NPoint kScene1202Points[] = {
+ {203, 140}, {316, 212}, {277, 264},
+ {176, 196}, {275, 159}, {366, 212},
+ {230, 195}, {412, 212}, {368, 263},
+ {204, 192}, {365, 164}, {316, 262},
+ {191, 255}, {280, 213}, {406, 266},
+ {214, 254}, {316, 158}, {402, 161}
+};
+
+static const uint32 kScene1202FileHashes[] = {
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
+};
+
+AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
+
+ int positionIndex;
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
+ createSurface(900, 37, 67);
+ _x = kScene1202Points[positionIndex].x;
+ _y = kScene1202Points[positionIndex].y;
+ stShowIdle();
+}
+
+uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2000, _itemIndex);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _newPosition = (int)param.asInteger();
+ stChangePositionFadeOut();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1202TntItem::stShowIdle() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1202TntItem::stChangePositionFadeOut() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionFadeIn);
+}
+
+void AsScene1202TntItem::stChangePositionFadeIn() {
+ _x = kScene1202Points[_newPosition].x;
+ _y = kScene1202Points[_newPosition].y;
+ startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
+ _playBackwards = true;
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionDone);
+}
+
+void AsScene1202TntItem::stChangePositionDone() {
+ sendMessage(_parentScene, 0x2002, _itemIndex);
+ stShowIdle();
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
+ _doYHitIncr = true;
+}
+
+uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ GotoState(&Klaymen::stMoveObject);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4813:
+ GotoState(&KmScene1201::stFetchMatch);
+ break;
+ case 0x4814:
+ GotoState(&KmScene1201::stTumbleHeadless);
+ break;
+ case 0x4815:
+ GotoState(&KmScene1201::stCloseEyes);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1201::stTumbleHeadless() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(0);
+ startAnimation(0x2821C590, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmTumbleHeadless);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&Klaymen::stTryStandIdle);
+ sendMessage(_parentScene, 0x8000, 0);
+ playSound(0, 0x62E0A356);
+ }
+}
+
+void KmScene1201::stCloseEyes() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+uint32 KmScene1201::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x51281850) {
+ setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
+ } else if (param.asInteger() == 0x43000538) {
+ playSound(0, 0x21043059);
+ } else if (param.asInteger() == 0x02B20220) {
+ playSound(0, 0xC5408620);
+ } else if (param.asInteger() == 0x0A720138) {
+ playSound(0, 0xD4C08010);
+ } else if (param.asInteger() == 0xB613A180) {
+ playSound(0, 0x44051000);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1201::stFetchMatch() {
+ if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x9CAA0218, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene1201::stLightMatch);
+ }
+}
+
+void KmScene1201::stLightMatch() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x1222A513, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000F0082) {
+ playSound(0, 0x74E2810F);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1200_sprites.h b/engines/neverhood/modules/module1200_sprites.h
new file mode 100644
index 0000000000..ef1ec40ced
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.h
@@ -0,0 +1,187 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Used for both the scene sprites and the scene itself (for clipping)
+static const NPoint kScene1201PointArray[] = {
+ {218, 193}, {410, 225}, {368, 277},
+ {194, 227}, {366, 174}, {458, 224},
+ {242, 228}, {512, 228}, {458, 277},
+ {217, 233}, {458, 173}, {410, 276},
+ {203, 280}, {371, 226}, {508, 279},
+ {230, 273}, {410, 171}, {493, 174}
+};
+
+class AsScene1201Tape : public AnimatedSprite {
+public:
+ AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _nameHash;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntManRope : public AnimatedSprite {
+public:
+ AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201RightDoor : public AnimatedSprite {
+public:
+ AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1201KlaymenHead : public AnimatedSprite {
+public:
+ AsScene1201KlaymenHead(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntMan : public AnimatedSprite {
+public:
+ AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
+ virtual ~AsScene1201TntMan();
+protected:
+ Scene *_parentScene;
+ Sprite *_asTntManRope;
+ Sprite *_sprite;
+ bool _isMoving;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void stStanding();
+ void stComingDown();
+ void stMoving();
+};
+
+class AsScene1201TntManFlame : public AnimatedSprite {
+public:
+ AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
+ ~AsScene1201TntManFlame();
+protected:
+ Sprite *_asTntMan;
+ void update();
+ void suUpdate();
+};
+
+class AsScene1201Match : public AnimatedSprite {
+public:
+ AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ int _status;
+ void update();
+ uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
+ void stOnDoorFrameMoving();
+ void stFallingFromDoorFrame();
+ void stOnDoorFrameAboutToMove();
+ void stIdleOnDoorFrame();
+ void stIdleOnFloor();
+};
+
+class AsScene1201Creature : public AnimatedSprite {
+public:
+ AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _klaymenTooClose;
+ void update();
+ uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
+ void stWaiting();
+ void stPincerSnap();
+ void stStartReachForTntDummy();
+ void stReachForTntDummy();
+ void stPincerSnapKlaymen();
+};
+
+class AsScene1201LeftDoor : public AnimatedSprite {
+public:
+ AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stCloseDoor();
+};
+
+class SsScene1201Tnt : public StaticSprite {
+public:
+ SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
+};
+
+class AsScene1202TntItem : public AnimatedSprite {
+public:
+ AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
+protected:
+ Scene *_parentScene;
+ int _itemIndex, _newPosition;
+ uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
+ void stShowIdle();
+ void stChangePositionFadeOut();
+ void stChangePositionFadeIn();
+ void stChangePositionDone();
+};
+
+class KmScene1201 : public Klaymen {
+public:
+ KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCloseEyes();
+ void stTumbleHeadless();
+ void stFetchMatch();
+ void stLightMatch();
+
+ uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1200_SPRITES_H */
diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp
index 8dbfcf616c..312fb85ae7 100644
--- a/engines/neverhood/modules/module1300.cpp
+++ b/engines/neverhood/modules/module1300.cpp
@@ -20,16 +20,15 @@
*
*/
-#include "neverhood/modules/module1300.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/gamemodule.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
#include "neverhood/menumodule.h"
-#include "neverhood/navigationscene.h"
-#include "neverhood/smackerscene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1300.h"
+#include "neverhood/modules/module1300_sprites.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -45,7 +44,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 +55,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 +100,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)
break;
}
}
-
+
}
Module1300::~Module1300() {
@@ -109,7 +108,7 @@ Module1300::~Module1300() {
}
void Module1300::createScene(int sceneNum, int which) {
- debug("Module1300::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1300::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 1:
@@ -218,7 +217,7 @@ void Module1300::createScene(int sceneNum, int which) {
SetUpdateHandler(&Module1300::updateScene);
_childObject->handleUpdate();
}
-
+
void Module1300::updateScene() {
if (!updateChild()) {
switch (_sceneNum) {
@@ -274,7 +273,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);
@@ -311,113 +310,6 @@ void Module1300::updateScene() {
}
}
-AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x88148150, 500);
- if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
- startAnimation(0x88148150, 0, -1);
- _newStickFrameIndex = 0;
- } else {
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- loadSound(0, 0x68895082);
- loadSound(1, 0x689BD0C1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1302Bridge::handleMessage);
-}
-
-uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stLowerBridge();
- break;
- case 0x4809:
- stRaiseBridge();
- break;
- }
- return messageResult;
-}
-
-void AsScene1302Bridge::stLowerBridge() {
- startAnimation(0x88148150, 0, -1);
- playSound(1);
- NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
-}
-
-void AsScene1302Bridge::stRaiseBridge() {
- startAnimation(0x88148150, 7, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0);
-}
-
-void AsScene1302Bridge::cbLowerBridgeEvent() {
- sendMessage(_parentScene, 0x2032, 0);
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
- : StaticSprite(vm, 0x11122122, 200) {
-
- _firstY = _y;
- if (getGlobalVar(V_FLYTRAP_RING_FENCE))
- _y += 152;
- loadSound(0, 0x7A00400C);
- loadSound(1, 0x78184098);
- SetUpdateHandler(&SsScene1302Fence::update);
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void SsScene1302Fence::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- playSound(0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
- break;
- case 0x4809:
- playSound(1);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
- break;
- }
- return messageResult;
-}
-
-void SsScene1302Fence::suMoveDown() {
- if (_y < _firstY + 152)
- _y += 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void SsScene1302Fence::suMoveUp() {
- if (_y > _firstY)
- _y -= 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -459,7 +351,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 +405,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;
@@ -581,56 +473,8 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(200, 128, 315);
- _x = 289;
- _y = 390;
- startAnimation(0x800278D2, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1303Balloon::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x2000:
- stPopBalloon();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x020B0003)
- playSound(0, 0x742B0055);
- break;
- case 0x3002:
- playSound(0, 0x470007EE);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-void AsScene1303Balloon::stPopBalloon() {
- startAnimation(0xAC004CD0, 0, -1);
- SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
-}
-
Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule) {
+ : Scene(vm, parentModule), _asBalloon(NULL) {
SetMessageHandler(&Scene1303::handleMessage);
@@ -643,7 +487,7 @@ Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
_asBalloon = insertSprite<AsScene1303Balloon>(this);
addCollisionSprite(_asBalloon);
}
-
+
_sprite1 = insertStaticSprite(0xA014216B, 1100);
insertKlaymen<KmScene1303>(207, 332);
@@ -668,39 +512,16 @@ uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
-
- // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
- SetMessageHandler(&AsScene1304Needle::handleMessage);
-}
-
-uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_NEEDLE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asNeedle(NULL) {
-
+
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,104 +595,19 @@ Scene1305::Scene1305(NeverhoodEngine *vm, Module *parentModule, int which)
insertKlaymen<KmScene1305>(212, 441);
setMessageList(0x004B6E48);
}
-
+
}
uint32 Scene1305::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
return Scene::handleMessage(messageNum, param, sender);
}
-AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
- _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x043B0270, 100);
- startAnimation(0x043B0270, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(0, 0x1C100E83);
- loadSound(1, 0x1C08CEC5);
- loadSound(2, 0x5D011E87);
- SetMessageHandler(&AsScene1306Elevator::handleMessage);
-}
-
-void AsScene1306Elevator::update() {
- if (_isUp && _countdown != 0 && (--_countdown == 0))
- stGoingDown();
- AnimatedSprite::update();
- if (_currFrameIndex == 7) {
- playSound(1);
- _asElevatorDoor->setVisible(false);
- }
-}
-
-void AsScene1306Elevator::upGoingDown() {
- AnimatedSprite::update();
- if (_currFrameIndex == 5)
- _asElevatorDoor->setVisible(true);
-}
-
-uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isUp)
- _countdown = 144;
- messageResult = _isUp ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (_isDown)
- stGoingUp();
- break;
- }
- return messageResult;
-}
-
-void AsScene1306Elevator::stGoingUp() {
- setVisible(true);
- _isDown = false;
- startAnimation(0x043B0270, 0, -1);
- playSound(0);
- SetUpdateHandler(&AsScene1306Elevator::update);
- NextState(&AsScene1306Elevator::cbGoingUpEvent);
-}
-
-void AsScene1306Elevator::cbGoingUpEvent() {
- sendMessage(_parentScene, 0x4808, 0);
- _isUp = true;
- _countdown = 144;
- stopAnimation();
- setVisible(false);
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
-void AsScene1306Elevator::stGoingDown() {
- _isUp = false;
- setVisible(true);
- startAnimation(0x043B0270, -1, -1);
- _playBackwards = true;
- playSound(1);
- SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
- NextState(&AsScene1306Elevator::cbGoingDownEvent);
-}
-
-void AsScene1306Elevator::cbGoingDownEvent() {
- _isDown = true;
- sendMessage(_parentScene, 0x4809, 0);
- stopAnimation();
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
setGlobalVar(V_KEY3_LOCATION, 4);
-
+
SetMessageHandler(&Scene1306::handleMessage);
setBackground(0x05303114);
@@ -949,7 +685,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
}
}
-
+
Scene1306::~Scene1306() {
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
}
@@ -1039,196 +775,14 @@ uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam &param,
return 0;
}
-static const uint32 kAsScene1307KeyResourceList1[] = {
- 0x0438069C, 0x45B0023C, 0x05700217
-};
-
-static const uint32 kAsScene1307KeyResourceList2[] = {
- 0x04441334, 0x061433F0, 0x06019390
-};
-
-static const uint32 kAsScene1307KeyResourceList3[] = {
- 0x11A80030, 0x178812B1, 0x1488121C
-};
-
-static const uint32 *kAsScene1307KeyResourceLists[] = {
- kAsScene1307KeyResourceList1,
- kAsScene1307KeyResourceList2,
- kAsScene1307KeyResourceList3
-};
-
-static const int kAsScene1307KeySurfacePriorities[] = {
- 700, 500, 300, 100
-};
-
-const uint kAsScene1307KeyPointsCount = 12;
-
-static const NPoint kAsScene1307KeyPoints[] = {
- {-2, 0}, {-5, 0}, { 5, 0},
- {12, 0}, {17, 0}, {25, 0},
- {16, -2}, {10, -6}, { 0, -7},
- {-7, -3}, {-3, 4}, { 2, 2}
-};
-
-const uint kAsScene1307KeyFrameIndicesCount = 20;
-
-static const int16 kAsScene1307KeyFrameIndices[] = {
- 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
- 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
-};
-
-const int kAsScene1307KeyDivValue = 200;
-const int16 kAsScene1307KeyXDelta = 70;
-const int16 kAsScene1307KeyYDelta = -12;
-
-AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
- _isClickable(true) {
-
- NPoint pt;
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
-
- _dataResource.load(0x22102142);
- _pointList = _dataResource.getPointArray(0xAC849240);
- pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x;
- _y = pt.y;
- createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
- startAnimation(fileHashes[0], 0, -1);
- loadSound(0, 0xDC4A1280);
- loadSound(1, 0xCC021233);
- loadSound(2, 0xC4C23844);
- loadSound(3, 0xC4523208);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1307Key::handleMessage);
-}
-
-uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_isClickable) {
- sendMessage(_parentScene, 0x4826, 0);
- stRemoveKey();
- messageResult = 1;
- }
- break;
- case 0x2000:
- _isClickable = param.asInteger() != 0;
- break;
- case 0x2001:
- setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
- stMoveKey();
- break;
- case 0x2003:
- playSound(3);
- stUnlock();
- break;
- case 0x2004:
- playSound(2);
- stInsert();
- break;
- }
- return messageResult;
-}
-
-void AsScene1307Key::suRemoveKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x += kAsScene1307KeyPoints[_pointIndex].x;
- _y += kAsScene1307KeyPoints[_pointIndex].y;
- updateBounds();
- _pointIndex++;
- } else {
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1307Key::suInsertKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
- _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
- updateBounds();
- _pointIndex++;
- if (_pointIndex == 7)
- playSound(0);
- } else {
- SetSpriteUpdate(NULL);
- sendMessage(_parentScene, 0x2002, 0);
- }
-}
-
-void AsScene1307Key::suMoveKey() {
- if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
- _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
- _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
- _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
- updateBounds();
- _pointIndex++;
- } else {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x + kAsScene1307KeyXDelta;
- _y = pt.y + kAsScene1307KeyYDelta;
- stInsertKey();
- }
-}
-
-void AsScene1307Key::stRemoveKey() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- startAnimation(fileHashes[0], 0, -1);
- playSound(1);
- SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
-}
-
-void AsScene1307Key::stInsertKey() {
- _pointIndex = 0;
- sendMessage(_parentScene, 0x1022, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetSpriteUpdate(&AsScene1307Key::suInsertKey);
-}
-
-void AsScene1307Key::stMoveKey() {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- int16 newX = pt.x + kAsScene1307KeyXDelta;
- int16 newY = pt.y + kAsScene1307KeyYDelta;
- sendMessage(_parentScene, 0x1022, 1000);
- setClipRect(0, 0, 640, 480);
- _prevX = _x;
- _prevY = _y;
- if (newX == _x && newY == _y) {
- stInsertKey();
- } else {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- _frameIndex = 0;
- _deltaX = newX - _x;
- _deltaY = newY - _y;
- startAnimation(fileHashes[0], 0, -1);
- SetSpriteUpdate(&AsScene1307Key::suMoveKey);
- }
-}
-
-void AsScene1307Key::stUnlock() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[1], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1307Key::stInsert() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[2], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _asCurrKey(NULL),
_isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) {
Sprite *tempSprite;
-
+
_vm->gameModule()->initKeySlotsPuzzle();
-
+
_dataResource.load(0x22102142);
_keyHolePoints = _dataResource.getPointArray(0xAC849240);
@@ -1279,7 +833,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 +848,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;
}
@@ -1360,171 +914,13 @@ static const uint32 kScene1308NumberFileHashes[] = {
0x00306322
};
-AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
-}
-
-uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308JaggyDoor::stOpenDoor() {
- startAnimation(0xBA0AE050, 0, -1);
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
-}
-
-void AsScene1308JaggyDoor::stOpenDoorDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1308JaggyDoor::stCloseDoor() {
- startAnimation(0xBA0AE050, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
-}
-
-void AsScene1308JaggyDoor::stCloseDoorDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
-}
-
-AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
-
- playSound(0, 0x51456049);
- SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
- NextState(&AsScene1308KeyboardDoor::stFallingKeys);
-}
-
-uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308KeyboardDoor::stFallingKeys() {
- startAnimation(0x6238B191, 0, -1);
- _x = 580;
- _y = 383;
- NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
-}
-
-void AsScene1308KeyboardDoor::stFallingKeysDone() {
- sendMessage(_parentScene, 0x2004, 0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- Entity::_priority = 1200;
- SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
-}
-
-uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- stFadeIn();
- break;
- case 0x2003:
- stFadeOut();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308LightWallSymbols::stFadeIn() {
- startAnimation(0x80180A10, 0, -1);
- setVisible(true);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1308LightWallSymbols::stFadeOut() {
- startAnimation(0x80180A10, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
-}
-
-void AsScene1308LightWallSymbols::stFadeOutDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- setVisible(false);
-}
-
-SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- setVisible(false);
- _x = _spriteResource.getPosition().x + index * 20;
- updatePosition();
-}
-
-AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 286;
- _y = 429;
- createSurface1(0xA282C472, 100);
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1308Mouse::handleMessage);
-}
-
-uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- }
- return messageResult;
-}
-
Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) {
-
+
_vm->gameModule()->initKeySlotsPuzzle();
SetMessageHandler(&Scene1308::handleMessage);
-
+
setBackground(0x41024202);
setPalette(0x41024202);
insertScreenMouse(0x24206418);
@@ -1536,7 +932,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 +942,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 +1094,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());
@@ -1711,6 +1107,7 @@ Scene1317::Scene1317(NeverhoodEngine *vm, Module *parentModule)
void Scene1317::update() {
if (_smackerFileHash) {
_smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame);
+ _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
_smackerFileHash = 0;
}
Scene::update();
@@ -1719,7 +1116,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) {
@@ -1730,14 +1127,15 @@ void Scene1317::upChooseKing() {
if (!_klaymenBlinks && _decisionCountdown != 0 && (--_decisionCountdown == 0))
stNoDecisionYet();
-
+
if (_smackerFileHash) {
_smackerPlayer->open(_smackerFileHash, _keepLastSmackerFrame);
+ _vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
_smackerFileHash = 0;
}
Scene::update();
-
+
}
uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -1749,7 +1147,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/module1300.h b/engines/neverhood/modules/module1300.h
index 501f76304f..2f59ff16c2 100644
--- a/engines/neverhood/modules/module1300.h
+++ b/engines/neverhood/modules/module1300.h
@@ -30,8 +30,6 @@
namespace Neverhood {
-// Module1300
-
class Module1300 : public Module {
public:
Module1300(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -43,28 +41,6 @@ protected:
void updateScene();
};
-class AsScene1302Bridge : public AnimatedSprite {
-public:
- AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLowerBridge();
- void stRaiseBridge();
- void cbLowerBridgeEvent();
-};
-
-class SsScene1302Fence : public StaticSprite {
-public:
- SsScene1302Fence(NeverhoodEngine *vm);
-protected:
- int16 _firstY;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
- void suMoveUp();
-};
-
class Scene1302 : public Scene {
public:
Scene1302(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -84,16 +60,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1303Balloon : public AnimatedSprite {
-public:
- AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
- void stPopBalloon();
-};
-
class Scene1303 : public Scene {
public:
Scene1303(NeverhoodEngine *vm, Module *parentModule);
@@ -103,14 +69,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1304Needle : public AnimatedSprite {
-public:
- AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1304 : public Scene {
public:
Scene1304(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -128,24 +86,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1306Elevator : public AnimatedSprite {
-public:
- AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
-protected:
- Scene *_parentScene;
- AnimatedSprite *_asElevatorDoor;
- bool _isUp;
- bool _isDown;
- int _countdown;
- void update();
- void upGoingDown();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stGoingUp();
- void cbGoingUpEvent();
- void stGoingDown();
- void cbGoingDownEvent();
-};
-
class Scene1306 : public Scene {
public:
Scene1306(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -161,30 +101,6 @@ protected:
uint32 handleMessage416EB0(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1307Key : public AnimatedSprite {
-public:
- AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
-protected:
- Scene *_parentScene;
- NPointArray *_pointList;
- uint _pointIndex;
- int _frameIndex;
- uint _keyIndex;
- NRect *_clipRects;
- bool _isClickable;
- int16 _prevX, _prevY;
- int16 _deltaX, _deltaY;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suRemoveKey();
- void suInsertKey();
- void suMoveKey();
- void stRemoveKey();
- void stInsertKey();
- void stMoveKey();
- void stUnlock();
- void stInsert();
-};
-
class Scene1307 : public Scene {
public:
Scene1307(NeverhoodEngine *vm, Module *parentModule);
@@ -202,51 +118,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1308JaggyDoor : public AnimatedSprite {
-public:
- AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stOpenDoorDone();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1308KeyboardDoor : public AnimatedSprite {
-public:
- AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFallingKeys();
- void stFallingKeysDone();
-};
-
-class AsScene1308LightWallSymbols : public AnimatedSprite {
-public:
- AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFadeIn();
- void stFadeOut();
- void stFadeOutDone();
-};
-
-class SsScene1308Number : public StaticSprite {
-public:
- SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
-class AsScene1308Mouse : public AnimatedSprite {
-public:
- AsScene1308Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1308 : public Scene {
public:
Scene1308(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1300_sprites.cpp b/engines/neverhood/modules/module1300_sprites.cpp
new file mode 100644
index 0000000000..a65f2363a3
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.cpp
@@ -0,0 +1,935 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1300_sprites.h"
+
+namespace Neverhood {
+
+AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x88148150, 500);
+ if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
+ startAnimation(0x88148150, 0, -1);
+ _newStickFrameIndex = 0;
+ } else {
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ loadSound(0, 0x68895082);
+ loadSound(1, 0x689BD0C1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1302Bridge::handleMessage);
+}
+
+uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stLowerBridge();
+ break;
+ case 0x4809:
+ stRaiseBridge();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1302Bridge::stLowerBridge() {
+ startAnimation(0x88148150, 0, -1);
+ playSound(1);
+ NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
+}
+
+void AsScene1302Bridge::stRaiseBridge() {
+ startAnimation(0x88148150, 7, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0);
+}
+
+void AsScene1302Bridge::cbLowerBridgeEvent() {
+ sendMessage(_parentScene, 0x2032, 0);
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
+ : StaticSprite(vm, 0x11122122, 200) {
+
+ _firstY = _y;
+ if (getGlobalVar(V_FLYTRAP_RING_FENCE))
+ _y += 152;
+ loadSound(0, 0x7A00400C);
+ loadSound(1, 0x78184098);
+ SetUpdateHandler(&SsScene1302Fence::update);
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void SsScene1302Fence::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ playSound(0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
+ break;
+ case 0x4809:
+ playSound(1);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1302Fence::suMoveDown() {
+ if (_y < _firstY + 152)
+ _y += 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void SsScene1302Fence::suMoveUp() {
+ if (_y > _firstY)
+ _y -= 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(200, 128, 315);
+ _x = 289;
+ _y = 390;
+ startAnimation(0x800278D2, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1303Balloon::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ stPopBalloon();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x020B0003)
+ playSound(0, 0x742B0055);
+ break;
+ case 0x3002:
+ playSound(0, 0x470007EE);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1303Balloon::stPopBalloon() {
+ startAnimation(0xAC004CD0, 0, -1);
+ SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
+}
+
+AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
+
+ // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
+ SetMessageHandler(&AsScene1304Needle::handleMessage);
+}
+
+uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setGlobalVar(V_HAS_NEEDLE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
+ _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x043B0270, 100);
+ startAnimation(0x043B0270, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(0, 0x1C100E83);
+ loadSound(1, 0x1C08CEC5);
+ loadSound(2, 0x5D011E87);
+ SetMessageHandler(&AsScene1306Elevator::handleMessage);
+}
+
+void AsScene1306Elevator::update() {
+ if (_isUp && _countdown != 0 && (--_countdown == 0))
+ stGoingDown();
+ AnimatedSprite::update();
+ if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
+ playSound(1);
+ _asElevatorDoor->setVisible(false);
+ }
+}
+
+void AsScene1306Elevator::upGoingDown() {
+ AnimatedSprite::update();
+ if (_currFrameIndex == 5)
+ _asElevatorDoor->setVisible(true);
+}
+
+uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isUp)
+ _countdown = 144;
+ messageResult = _isUp ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ if (_isDown)
+ stGoingUp();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1306Elevator::stGoingUp() {
+ setVisible(true);
+ _isDown = false;
+ startAnimation(0x043B0270, 0, -1);
+ playSound(0);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+ NextState(&AsScene1306Elevator::cbGoingUpEvent);
+}
+
+void AsScene1306Elevator::cbGoingUpEvent() {
+ sendMessage(_parentScene, 0x4808, 0);
+ _isUp = true;
+ _countdown = 144;
+ stopAnimation();
+ setVisible(false);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+void AsScene1306Elevator::stGoingDown() {
+ _isUp = false;
+ setVisible(true);
+ startAnimation(0x043B0270, -1, -1);
+ _playBackwards = true;
+ playSound(1);
+ SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
+ NextState(&AsScene1306Elevator::cbGoingDownEvent);
+}
+
+void AsScene1306Elevator::cbGoingDownEvent() {
+ _isDown = true;
+ sendMessage(_parentScene, 0x4809, 0);
+ stopAnimation();
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+static const uint32 kAsScene1307KeyResourceList1[] = {
+ 0x0438069C, 0x45B0023C, 0x05700217
+};
+
+static const uint32 kAsScene1307KeyResourceList2[] = {
+ 0x04441334, 0x061433F0, 0x06019390
+};
+
+static const uint32 kAsScene1307KeyResourceList3[] = {
+ 0x11A80030, 0x178812B1, 0x1488121C
+};
+
+static const uint32 *kAsScene1307KeyResourceLists[] = {
+ kAsScene1307KeyResourceList1,
+ kAsScene1307KeyResourceList2,
+ kAsScene1307KeyResourceList3
+};
+
+static const int kAsScene1307KeySurfacePriorities[] = {
+ 700, 500, 300, 100
+};
+
+const uint kAsScene1307KeyPointsCount = 12;
+
+static const NPoint kAsScene1307KeyPoints[] = {
+ {-2, 0}, {-5, 0}, { 5, 0},
+ {12, 0}, {17, 0}, {25, 0},
+ {16, -2}, {10, -6}, { 0, -7},
+ {-7, -3}, {-3, 4}, { 2, 2}
+};
+
+const uint kAsScene1307KeyFrameIndicesCount = 20;
+
+static const int16 kAsScene1307KeyFrameIndices[] = {
+ 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
+ 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
+};
+
+const int kAsScene1307KeyDivValue = 200;
+const int16 kAsScene1307KeyXDelta = 70;
+const int16 kAsScene1307KeyYDelta = -12;
+
+AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
+ _isClickable(true) {
+
+ NPoint pt;
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+
+ _dataResource.load(0x22102142);
+ _pointList = _dataResource.getPointArray(0xAC849240);
+ pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
+ startAnimation(fileHashes[0], 0, -1);
+ loadSound(0, 0xDC4A1280);
+ loadSound(1, 0xCC021233);
+ loadSound(2, 0xC4C23844);
+ loadSound(3, 0xC4523208);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1307Key::handleMessage);
+}
+
+uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_isClickable) {
+ sendMessage(_parentScene, 0x4826, 0);
+ stRemoveKey();
+ messageResult = 1;
+ }
+ break;
+ case 0x2000:
+ _isClickable = param.asInteger() != 0;
+ break;
+ case 0x2001:
+ setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
+ stMoveKey();
+ break;
+ case 0x2003:
+ playSound(3);
+ stUnlock();
+ break;
+ case 0x2004:
+ playSound(2);
+ stInsert();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1307Key::suRemoveKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x += kAsScene1307KeyPoints[_pointIndex].x;
+ _y += kAsScene1307KeyPoints[_pointIndex].y;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1307Key::suInsertKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
+ _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
+ updateBounds();
+ _pointIndex++;
+ if (_pointIndex == 7)
+ playSound(0);
+ } else {
+ SetSpriteUpdate(NULL);
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+}
+
+void AsScene1307Key::suMoveKey() {
+ if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
+ _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
+ _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
+ _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x + kAsScene1307KeyXDelta;
+ _y = pt.y + kAsScene1307KeyYDelta;
+ stInsertKey();
+ }
+}
+
+void AsScene1307Key::stRemoveKey() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ startAnimation(fileHashes[0], 0, -1);
+ playSound(1);
+ SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
+}
+
+void AsScene1307Key::stInsertKey() {
+ _pointIndex = 0;
+ sendMessage(_parentScene, 0x1022, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetSpriteUpdate(&AsScene1307Key::suInsertKey);
+}
+
+void AsScene1307Key::stMoveKey() {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ int16 newX = pt.x + kAsScene1307KeyXDelta;
+ int16 newY = pt.y + kAsScene1307KeyYDelta;
+ sendMessage(_parentScene, 0x1022, 1000);
+ setClipRect(0, 0, 640, 480);
+ _prevX = _x;
+ _prevY = _y;
+ if (newX == _x && newY == _y) {
+ stInsertKey();
+ } else {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ _frameIndex = 0;
+ _deltaX = newX - _x;
+ _deltaY = newY - _y;
+ startAnimation(fileHashes[0], 0, -1);
+ SetSpriteUpdate(&AsScene1307Key::suMoveKey);
+ }
+}
+
+void AsScene1307Key::stUnlock() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[1], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1307Key::stInsert() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[2], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
+}
+
+uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stOpenDoor();
+ break;
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308JaggyDoor::stOpenDoor() {
+ startAnimation(0xBA0AE050, 0, -1);
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
+}
+
+void AsScene1308JaggyDoor::stOpenDoorDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1308JaggyDoor::stCloseDoor() {
+ startAnimation(0xBA0AE050, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
+}
+
+void AsScene1308JaggyDoor::stCloseDoorDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+}
+
+AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
+
+ playSound(0, 0x51456049);
+ SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
+ NextState(&AsScene1308KeyboardDoor::stFallingKeys);
+}
+
+uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308KeyboardDoor::stFallingKeys() {
+ startAnimation(0x6238B191, 0, -1);
+ _x = 580;
+ _y = 383;
+ NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
+}
+
+void AsScene1308KeyboardDoor::stFallingKeysDone() {
+ sendMessage(_parentScene, 0x2004, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ Entity::_priority = 1200;
+ SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
+}
+
+uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ stFadeIn();
+ break;
+ case 0x2003:
+ stFadeOut();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308LightWallSymbols::stFadeIn() {
+ startAnimation(0x80180A10, 0, -1);
+ setVisible(true);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1308LightWallSymbols::stFadeOut() {
+ startAnimation(0x80180A10, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
+}
+
+void AsScene1308LightWallSymbols::stFadeOutDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ setVisible(false);
+ _x = _spriteResource.getPosition().x + index * 20;
+ updatePosition();
+}
+
+AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 286;
+ _y = 429;
+ createSurface1(0xA282C472, 100);
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1308Mouse::handleMessage);
+}
+
+uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall1);
+ break;
+ case 0x483B:
+ GotoState(&Klaymen::stPeekWallReturn);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekWall2);
+ break;
+ }
+ return 0;
+}
+
+KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ GotoState(&KmScene1305::stCrashDown);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ }
+ return 0;
+}
+
+void KmScene1305::stCrashDown() {
+ playSound(0, 0x41648271);
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimationByHash(0x000BAB02, 0x88003000, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(NULL);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ NextState(&KmScene1305::stCrashDownFinished);
+}
+
+void KmScene1305::stCrashDownFinished() {
+ setDoDeltaX(2);
+ stTryStandIdle();
+}
+
+KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ else
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ else
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xEE084A04);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xB86A4274);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stInsertKey);
+ else
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1300_sprites.h b/engines/neverhood/modules/module1300_sprites.h
new file mode 100644
index 0000000000..e044d3cec8
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.h
@@ -0,0 +1,200 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerplayer.h"
+
+namespace Neverhood {
+
+class AsScene1302Bridge : public AnimatedSprite {
+public:
+ AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLowerBridge();
+ void stRaiseBridge();
+ void cbLowerBridgeEvent();
+};
+
+class SsScene1302Fence : public StaticSprite {
+public:
+ SsScene1302Fence(NeverhoodEngine *vm);
+protected:
+ int16 _firstY;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+ void suMoveUp();
+};
+
+class AsScene1303Balloon : public AnimatedSprite {
+public:
+ AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
+ void stPopBalloon();
+};
+
+class AsScene1304Needle : public AnimatedSprite {
+public:
+ AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1306Elevator : public AnimatedSprite {
+public:
+ AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
+protected:
+ Scene *_parentScene;
+ AnimatedSprite *_asElevatorDoor;
+ bool _isUp;
+ bool _isDown;
+ int _countdown;
+ void update();
+ void upGoingDown();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stGoingUp();
+ void cbGoingUpEvent();
+ void stGoingDown();
+ void cbGoingDownEvent();
+};
+
+class AsScene1307Key : public AnimatedSprite {
+public:
+ AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointList;
+ uint _pointIndex;
+ int _frameIndex;
+ uint _keyIndex;
+ NRect *_clipRects;
+ bool _isClickable;
+ int16 _prevX, _prevY;
+ int16 _deltaX, _deltaY;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suRemoveKey();
+ void suInsertKey();
+ void suMoveKey();
+ void stRemoveKey();
+ void stInsertKey();
+ void stMoveKey();
+ void stUnlock();
+ void stInsert();
+};
+
+class AsScene1308JaggyDoor : public AnimatedSprite {
+public:
+ AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stOpenDoorDone();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1308KeyboardDoor : public AnimatedSprite {
+public:
+ AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFallingKeys();
+ void stFallingKeysDone();
+};
+
+class AsScene1308LightWallSymbols : public AnimatedSprite {
+public:
+ AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFadeIn();
+ void stFadeOut();
+ void stFadeOutDone();
+};
+
+class SsScene1308Number : public StaticSprite {
+public:
+ SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class AsScene1308Mouse : public AnimatedSprite {
+public:
+ AsScene1308Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1303 : public Klaymen {
+public:
+ KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1304 : public Klaymen {
+public:
+ KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1305 : public Klaymen {
+public:
+ KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCrashDown();
+ void stCrashDownFinished();
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1306 : public Klaymen {
+public:
+ KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1308 : public Klaymen {
+public:
+ KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1300_SPRITES_H */
diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp
index 4f69637ee0..2fc1052ab1 100644
--- a/engines/neverhood/modules/module1400.cpp
+++ b/engines/neverhood/modules/module1400.cpp
@@ -20,18 +20,20 @@
*
*/
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
#include "neverhood/diskplayerscene.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1400.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x00AD0012, 0x06333232);
_vm->_soundMan->addMusic(0x00AD0012, 0x624A220E);
@@ -47,7 +49,7 @@ Module1400::~Module1400() {
}
void Module1400::createScene(int sceneNum, int which) {
- debug("Module1400::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1400::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -135,500 +137,9 @@ void Module1400::updateScene() {
}
}
-// Scene1401
-
-AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
-
- createSurface(900, 152, 147);
- _x = 454;
- _y = 217;
- startAnimation(0x4C210500, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::update);
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
-}
-
-AsScene1401Pipe::~AsScene1401Pipe() {
- _vm->_soundMan->deleteSoundGroup(0x01104C08);
-}
-
-void AsScene1401Pipe::update() {
- AnimatedSprite::update();
- if (_countdown1 != 0 && (--_countdown1 == 0))
- stDoneSucking();
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
- _vm->_soundMan->playSoundLooping(0x4A116437);
- }
-}
-
-void AsScene1401Pipe::upSuckInProjector() {
- AnimatedSprite::update();
- if (_countdown1 != 0)
- _countdown1--;
-}
-
-uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0A8A1490)
- playSound(1, 0x6AB6666F);
- break;
- case 0x2000:
- _countdown1 = 70;
- _countdown2 = 8;
- stStartSucking();
- break;
- case 0x483A:
- stSuckInProjector();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- if (_countdown1 != 0)
- stStartSucking();
- else
- stDoneSucking();
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
- SetUpdateHandler(&AsScene1401Pipe::update);
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Pipe::stStartSucking() {
- startAnimation(0x4C240100, 0, -1);
- playSound(0, 0x4A30063F);
-}
-
-void AsScene1401Pipe::stDoneSucking() {
- _vm->_soundMan->deleteSound(0x4A116437);
- playSound(0, 0x4A120435);
- startAnimation(0x4C210500, 0, -1);
-}
-
-void AsScene1401Pipe::stSuckInProjector() {
- startAnimation(0x6C210810, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
- SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
-}
-
-AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 71, 41);
- _x = 478;
- _y = 433;
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Mouse::handleMessage);
-}
-
-uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Mouse::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x0E32247F);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Mouse::stSuckedIn() {
- startAnimation(0x34880040, 0, -1);
- SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
-}
-
-AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(200, 152, 147);
- _x = 427;
- _y = 433;
- startAnimation(0x461A1490, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Cheese::handleMessage);
-}
-
-uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Cheese::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x18020439);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Cheese::stSuckedIn() {
- startAnimation(0x103B8020, 0, -1);
- SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
-}
-
-AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x04551900, 100);
- if (isOpen) {
- startAnimation(0x04551900, -1, -1);
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsScene1401BackDoor::update);
- SetMessageHandler(&AsScene1401BackDoor::handleMessage);
-}
-
-void AsScene1401BackDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-
-uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 168;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401BackDoor::stOpenDoor() {
- _isOpen = true;
- setVisible(true);
- startAnimation(0x04551900, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen24"));
-}
-
-void AsScene1401BackDoor::stCloseDoor() {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x04551900, -1, -1);
- playSound(0, calcHash("fxDoorClose24"));
- _playBackwards = true;
- NextState(&AsScene1401BackDoor::stCloseDoorDone);
-}
-
-void AsScene1401BackDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
- {{154, 453}, 4, 2, 0, 0, 1},
- {{104, 391}, 4, -1, -1, 1, 1},
- {{ 22, 447}, 6, -1, -1, 1, 1},
- {{112, 406}, 2, -1, -1, 1, 0},
- {{262, 433}, 1, 1, 0, 0, 0}
-};
-
-AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
-
- _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
- createSurface(990, 101, 182);
- startAnimation(0x10E3042B, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- _lockedInSlot = true;
- moveProjector();
- setDoDeltaX(1);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStayLockedInSlot();
- loadSound(2, 0xC8C2507C);
-}
-
-AsCommonProjector::~AsCommonProjector() {
- _vm->_soundMan->deleteSoundGroup(0x05331081);
-}
-
-uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStartLockedInSlot();
- else
- stIdle();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stMoving();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- case 0x4839:
- stStartSuckedIn();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
- param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
- sendMessage(_parentScene, 0x4826, 1);
- } else
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- stStopProjecting();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stTurnToFront();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x480F:
- stStartProjecting();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsCommonProjector::suMoving() {
- if (_x <= _klaymen->getX())
- _x = _klaymen->getX() - 100;
- else
- _x = _klaymen->getX() + 100;
- moveProjector();
- if (_beforeMoveX == _x) {
- if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 0);
- incGlobalVar(V_PROJECTOR_LOCATION, -1);
- setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
- } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 1);
- incGlobalVar(V_PROJECTOR_LOCATION, +1);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- }
- }
- Sprite::updateBounds();
-}
-
-void AsCommonProjector::moveProjector() {
-
- bool nowLockedInSlot = false;
-
- _y = _asProjectorItem->point.y;
-
- if (_asProjectorItem->index1 != -1) {
- int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_asProjectorItem->lockSlotIndex != -1) {
- int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_lockedInSlot && !nowLockedInSlot)
- _lockedInSlot = false;
- else if (!_lockedInSlot && nowLockedInSlot) {
- playSound(1, 0x5440E474);
- _lockedInSlot = true;
- }
-
-}
-
-void AsCommonProjector::stSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- sendMessage(_asPipe, 0x483A, 0);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsCommonProjector::stIdle() {
- startAnimation(0x10E3042B, 0, -1);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stMoving() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x14A10137, 0, -1);
- playSound(1, 0xEC008474);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
-}
-
-void AsCommonProjector::stStartLockedInSlot() {
- startAnimation(0x80C32213, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stStayLockedInSlot() {
- startAnimation(0xD23B207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStartProjecting() {
- startAnimation(0x50A80517, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 1);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->addSound(0x05331081, 0xCE428854);
- _vm->_soundMan->playSoundLooping(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stLockedInSlot);
-}
-
-void AsCommonProjector::stLockedInSlot() {
- sendMessage(_parentScene, 0x480F, 0);
- startAnimation(0xD833207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStopProjecting() {
- startAnimation(0x50A94417, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 0);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->deleteSound(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stTurnToFront() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x22CB4A33, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
- NextState(&AsCommonProjector::stMoving);
-}
-
-void AsCommonProjector::stStartSuckedIn() {
- setGlobalVar(V_PROJECTOR_LOCATION, 4);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- startAnimation(0x708D4712, 0, -1);
- playSound(2);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
-}
-
Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
- : Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL),
- _asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL),
+ : 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 +149,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 +203,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 +263,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004B6658);
} else
setMessageList2(0x004B65F0);
- }
+ }
break;
case 0x482A:
_sprite1->setVisible(true);
@@ -768,77 +279,6 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1402
-
-SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
- : StaticSprite(vm, fileHash, surfacePriority) {
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&StaticSprite::updatePosition);
-}
-
-AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(900, 347, 230);
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
- _x = 279;
- _y = 270;
- if (status == 2) {
- // Puzzle box after the puzzle was solved
- startAnimation(0x20060259, 0, -1);
- playSound(0, 0x419014AC);
- loadSound(1, 0x61901C29);
- NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
- } else if (status == 1) {
- // Puzzle box appears
- startAnimation(0x210A0213, 0, -1);
- playSound(0, 0x41809C6C);
- NextState(&AsScene1402PuzzleBox::stMoveUpDone);
- } else {
- // Puzzle box is here
- startAnimation(0x20060259, -1, -1);
- loadSound(1, 0x61901C29);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
-}
-
-uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- playSound(1);
- startAnimation(0x20060259, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1402PuzzleBox::stMoveDownDone);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1402PuzzleBox::stMoveUpDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
-}
-
Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isShaking(false), _asPuzzleBox(NULL), _asProjector(NULL) {
@@ -892,7 +332,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
startShaking();
}
}
-
+
if (_asPuzzleBox)
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
@@ -914,7 +354,7 @@ Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
}
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
-
+
}
void Scene1402::upShaking() {
@@ -988,237 +428,6 @@ void Scene1402::stopShaking() {
_isShaking = false;
}
-// Scene1407
-
-static const int16 kScene1407MouseFloorY[] = {
- 106, 150, 191, 230, 267, 308, 350, 395
-};
-
-static const struct {
- int16 x;
- int16 floorIndex;
- int16 sectionIndex;
- int16 nextHoleIndex;
-} kScene1407MouseHoles[] = {
- {125, 0, 0, 7},
- {452, 7, 21, 0},
- {337, 4, 11, 4},
- {286, 6, 17, 6},
- {348, 6, 17, 39},
- {536, 6, 18, 42},
- {111, 1, 3, 18},
- {203, 1, 3, 38},
- {270, 1, 3, 9},
- {197, 5, 14, 3},
- {252, 5, 14, 35},
- {297, 5, 14, 7},
- {359, 5, 14, 8},
- {422, 4, 12, 26},
- {467, 4, 12, 2},
- {539, 4, 12, 40},
- {111, 5, 13, 17},
- {211, 0, 1, 20},
- {258, 0, 1, 11},
- {322, 0, 1, 16},
- { 99, 6, 16, 31},
- {142, 6, 16, 27},
- {194, 6, 16, 12},
- {205, 2, 6, 45},
- {264, 2, 6, 10},
- { 98, 4, 10, 2},
- {152, 4, 10, 37},
- {199, 4, 10, 13},
- {258, 4, 10, 16},
- {100, 7, 19, 43},
- {168, 7, 19, 23},
- {123, 3, 8, 14},
- {181, 3, 8, 39},
- {230, 3, 8, 28},
- {292, 3, 8, 22},
- {358, 3, 8, 36},
- {505, 3, 9, 44},
- {400, 2, 7, 34},
- {454, 2, 7, 32},
- {532, 2, 7, 46},
- {484, 5, 15, 25},
- {529, 5, 15, 30},
- {251, 7, 20, 48},
- {303, 7, 20, 21},
- {360, 7, 20, 33},
- {503, 0, 2, 5},
- {459, 1, 4, 19},
- {530, 1, 4, 42},
- {111, 2, 5, 47},
- {442, 6, 18, 1}
-};
-
-static const struct {
- int16 x1, x2;
- int16 goodHoleIndex;
-} kScene1407MouseSections[] = {
- {100, 149, 0},
- {182, 351, 17},
- {430, 524, 45},
- { 89, 293, 7},
- {407, 555, 47},
- { 89, 132, 48},
- {178, 303, 23},
- {367, 551, 38},
- {105, 398, 31},
- {480, 537, 36},
- { 84, 275, 27},
- {318, 359, 2},
- {402, 560, 15},
- { 91, 132, 16},
- {179, 400, 10},
- {461, 552, 41},
- { 86, 218, 21},
- {267, 376, 4},
- {420, 560, 49},
- { 77, 188, 30},
- {237, 394, 44},
- {438, 515, 5}
-};
-
-AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
-
- createSurface(100, 117, 45);
- _x = 108;
- _y = 106;
- stIdleLookAtGoodHole();
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene1407Mouse::suWalkTo() {
- int16 xdelta = _walkDestX - _x;
- if (xdelta > _deltaX)
- xdelta = _deltaX;
- else if (xdelta < -_deltaX)
- xdelta = -_deltaX;
- _deltaX = 0;
- if (_walkDestX == _x)
- sendMessage(this, 0x1019, 0);
- else {
- _x += xdelta;
- updateBounds();
- }
-}
-
-void AsScene1407Mouse::upGoThroughHole() {
- if (_countdown != 0 && (--_countdown == 0)) {
- SetUpdateHandler(&AnimatedSprite::update);
- gotoNextState();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x0001:
- {
- int16 mouseX = param.asPoint().x;
- int16 mouseY = param.asPoint().y;
- int holeIndex;
- for (holeIndex = 0; holeIndex < 50; holeIndex++) {
- int16 holeX = kScene1407MouseHoles[holeIndex].x;
- int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
- if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
- break;
- }
- if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
- _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
- _walkDestX = kScene1407MouseHoles[holeIndex].x;
- stWalkToHole();
- } else {
- if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
- else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
- else
- _walkDestX = mouseX;
- stWalkToDest();
- }
- }
- break;
- case 0x1019:
- gotoNextState();
- break;
- case 0x2001:
- {
- // Reset the position
- // Find the nearest hole and go through it, and exit at the first hole
- int16 distance = 640;
- int matchIndex = 50;
- for (int index = 0; index < 50; index++)
- if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
- ABS(kScene1407MouseHoles[index].x - _x) < distance) {
- matchIndex = index;
- distance = ABS(kScene1407MouseHoles[index].x - _x);
- }
- if (matchIndex < 50) {
- _nextHoleIndex = 0;
- _walkDestX = kScene1407MouseHoles[matchIndex].x;
- stWalkToHole();
- }
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene1407Mouse::stIdleLookAtGoodHole() {
- setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
- startAnimation(0x72215194, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1407Mouse::stWalkToDest() {
- if (_walkDestX != _x) {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
- }
-}
-
-void AsScene1407Mouse::stWalkToHole() {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stGoThroughHole);
-}
-
-void AsScene1407Mouse::stGoThroughHole() {
- startAnimation(0x72215194, 0, -1);
- setVisible(false);
- _countdown = 12;
- SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- NextState(&AsScene1407Mouse::stArriveAtHole);
-}
-
-void AsScene1407Mouse::stArriveAtHole() {
- _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
- _x = kScene1407MouseHoles[_nextHoleIndex].x;
- _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
- if (_nextHoleIndex == 1) {
- sendMessage(_parentScene, 0x2000, 0);
- _walkDestX = 512;
- stWalkToDest();
- setVisible(true);
- } else {
- _walkDestX = _x + 14;
- stWalkToDest();
- setVisible(true);
- }
-}
-
Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _puzzleSolvedCountdown(0), _resetButtonCountdown(0) {
@@ -1231,7 +440,7 @@ Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
_asMouse = insertSprite<AsScene1407Mouse>(this);
_ssResetButton = insertStaticSprite(0x12006600, 100);
- _ssResetButton->setVisible(false);
+ _ssResetButton->setVisible(false);
}
@@ -1275,13 +484,11 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1403
-
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _isProjecting(false) {
-
+
SetMessageHandler(&Scene1403::handleMessage);
-
+
setRectList(0x004B1FF8);
setBackground(0x2110A234);
setPalette(0x2110A234);
@@ -1379,14 +586,12 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1404
-
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _asKey(NULL) {
-
+
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
setGlobalVar(V_KEY3_LOCATION, 5);
-
+
SetMessageHandler(&Scene1404::handleMessage);
setRectList(0x004B8D80);
@@ -1480,89 +685,18 @@ uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1405
-
-static const NPoint kAsScene1405TileItemPositions[] = {
- {100, 80}, {162, 78}, {222, 76}, {292, 76},
- {356, 82}, {422, 84}, {488, 86}, {550, 90},
- {102, 134}, {164, 132}, {224, 136}, {294, 136},
- {360, 136}, {422, 138}, {484, 144}, {548, 146},
- { 98, 196}, {160, 200}, {228, 200}, {294, 202},
- {360, 198}, {424, 200}, {482, 202}, {548, 206},
- { 98, 260}, {160, 264}, {226, 260}, {296, 262},
- {358, 260}, {424, 262}, {486, 264}, {550, 266},
- { 94, 322}, {160, 316}, {226, 316}, {296, 320},
- {358, 322}, {422, 324}, {488, 322}, {550, 322},
- { 98, 380}, {160, 376}, {226, 376}, {294, 378},
- {356, 380}, {420, 380}, {490, 378}, {552, 376}
-};
-
-AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
-
- loadSound(0, 0x05308101);
- setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
- _x = kAsScene1405TileItemPositions[_tileIndex].x;
- _y = kAsScene1405TileItemPositions[_tileIndex].y;
- createSurface1(0x844B805C, 1100);
- setVisible(false);
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
- _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
- startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
- _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
- SetUpdateHandler(&AsScene1405Tile::update);
- SetMessageHandler(&AsScene1405Tile::handleMessage);
-}
-
-void AsScene1405Tile::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0))
- show();
-}
-
-uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
- show();
- sendMessage(_parentScene, 0x2000, _tileIndex);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene1405Tile::show() {
- if (!_isShowing) {
- _isShowing = true;
- playSound(0);
- setVisible(true);
- }
-}
-
-void AsScene1405Tile::hide() {
- if (_isShowing) {
- _isShowing = false;
- playSound(0);
- setVisible(false);
- }
-}
-
Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
_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/module1400.h b/engines/neverhood/modules/module1400.h
index 9a592c2952..53ad7125ab 100644
--- a/engines/neverhood/modules/module1400.h
+++ b/engines/neverhood/modules/module1400.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -40,92 +39,9 @@ protected:
void updateScene();
};
-// Scene1401
-
-class AsScene1401Pipe : public AnimatedSprite {
-public:
- AsScene1401Pipe(NeverhoodEngine *vm);
- virtual ~AsScene1401Pipe();
-protected:
- int _countdown1;
- int _countdown2;
- void update();
- void upSuckInProjector();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
- void stStartSucking();
- void stDoneSucking();
- void stSuckInProjector();
-};
-
-class AsScene1401Mouse : public AnimatedSprite {
-public:
- AsScene1401Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401Cheese : public AnimatedSprite {
-public:
- AsScene1401Cheese(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401BackDoor : public AnimatedSprite {
-public:
- AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-struct AsCommonProjectorItem {
- NPoint point;
- int8 maxSlotCount;
- int8 lockSlotIndex;
- int8 index1;
- int8 leftBorderLeaves;
- int8 rightBorderLeaves;
-};
-
-class AsCommonProjector : public AnimatedSprite {
-public:
- AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
- virtual ~AsCommonProjector();
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- Sprite *_asPipe;
- const AsCommonProjectorItem *_asProjectorItem;
- int16 _beforeMoveX;
- bool _lockedInSlot;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void moveProjector();
- void stSuckedIn();
- void stIdle();
- void stMoving();
- void stStartLockedInSlot();
- void stStayLockedInSlot();
- void stStartProjecting();
- void stLockedInSlot();
- void stStopProjecting();
- void stTurnToFront();
- void stStartSuckedIn();
-};
+class AsCommonProjector;
+class AsScene1201Tape;
+class AsScene1405Tile;
class Scene1401 : public Scene {
public:
@@ -146,24 +62,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1402
-
-class SsScene1402BridgePart : public StaticSprite {
-public:
- SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
-};
-
-class AsScene1402PuzzleBox : public AnimatedSprite {
-public:
- AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stMoveUpDone();
- void stMoveDownDone();
- void stMoveDownSolvedDone();
-};
-
class Scene1402 : public Scene {
public:
Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -180,27 +78,6 @@ protected:
void stopShaking();
};
-// Scene1407
-
-class AsScene1407Mouse : public AnimatedSprite {
-public:
- AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int16 _walkDestX;
- int16 _currSectionIndex;
- int16 _nextHoleIndex;
- int _countdown;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suWalkTo();
- void upGoThroughHole();
- void stIdleLookAtGoodHole();
- void stWalkToDest();
- void stWalkToHole();
- void stGoThroughHole();
- void stArriveAtHole();
-};
-
class Scene1407 : public Scene {
public:
Scene1407(NeverhoodEngine *vm, Module *parentModule);
@@ -213,8 +90,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1403
-
class Scene1403 : public Scene {
public:
Scene1403(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -229,8 +104,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1404
-
class Scene1404 : public Scene {
public:
Scene1404(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -243,24 +116,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1405
-
-class Scene1405;
-
-class AsScene1405Tile : public AnimatedSprite {
-public:
- AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
- void show();
- void hide();
-protected:
- Scene1405 *_parentScene;
- bool _isShowing;
- uint32 _tileIndex;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1405 : public Scene {
public:
Scene1405(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1400_sprites.cpp b/engines/neverhood/modules/module1400_sprites.cpp
new file mode 100644
index 0000000000..c0ab73c93d
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.cpp
@@ -0,0 +1,1129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module1400.h"
+
+namespace Neverhood {
+
+AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
+
+ createSurface(900, 152, 147);
+ _x = 454;
+ _y = 217;
+ startAnimation(0x4C210500, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+}
+
+AsScene1401Pipe::~AsScene1401Pipe() {
+ _vm->_soundMan->deleteSoundGroup(0x01104C08);
+}
+
+void AsScene1401Pipe::update() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0 && (--_countdown1 == 0))
+ stDoneSucking();
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
+ _vm->_soundMan->playSoundLooping(0x4A116437);
+ }
+}
+
+void AsScene1401Pipe::upSuckInProjector() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0)
+ _countdown1--;
+}
+
+uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0A8A1490)
+ playSound(1, 0x6AB6666F);
+ break;
+ case 0x2000:
+ _countdown1 = 70;
+ _countdown2 = 8;
+ stStartSucking();
+ break;
+ case 0x483A:
+ stSuckInProjector();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ if (_countdown1 != 0)
+ stStartSucking();
+ else
+ stDoneSucking();
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Pipe::stStartSucking() {
+ startAnimation(0x4C240100, 0, -1);
+ playSound(0, 0x4A30063F);
+}
+
+void AsScene1401Pipe::stDoneSucking() {
+ _vm->_soundMan->deleteSound(0x4A116437);
+ playSound(0, 0x4A120435);
+ startAnimation(0x4C210500, 0, -1);
+}
+
+void AsScene1401Pipe::stSuckInProjector() {
+ startAnimation(0x6C210810, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
+ SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
+}
+
+AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 71, 41);
+ _x = 478;
+ _y = 433;
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Mouse::handleMessage);
+}
+
+uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Mouse::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x0E32247F);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Mouse::stSuckedIn() {
+ startAnimation(0x34880040, 0, -1);
+ SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
+}
+
+AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(200, 152, 147);
+ _x = 427;
+ _y = 433;
+ startAnimation(0x461A1490, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Cheese::handleMessage);
+}
+
+uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Cheese::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x18020439);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Cheese::stSuckedIn() {
+ startAnimation(0x103B8020, 0, -1);
+ SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
+}
+
+AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x04551900, 100);
+ if (isOpen) {
+ startAnimation(0x04551900, -1, -1);
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsScene1401BackDoor::update);
+ SetMessageHandler(&AsScene1401BackDoor::handleMessage);
+}
+
+void AsScene1401BackDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+
+uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 168;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401BackDoor::stOpenDoor() {
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x04551900, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen24"));
+}
+
+void AsScene1401BackDoor::stCloseDoor() {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x04551900, -1, -1);
+ playSound(0, calcHash("fxDoorClose24"));
+ _playBackwards = true;
+ NextState(&AsScene1401BackDoor::stCloseDoorDone);
+}
+
+void AsScene1401BackDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
+ {{154, 453}, 4, 2, 0, 0, 1},
+ {{104, 391}, 4, -1, -1, 1, 1},
+ {{ 22, 447}, 6, -1, -1, 1, 1},
+ {{112, 406}, 2, -1, -1, 1, 0},
+ {{262, 433}, 1, 1, 0, 0, 0}
+};
+
+AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
+
+ _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
+ createSurface(990, 101, 182);
+ startAnimation(0x10E3042B, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ _lockedInSlot = true;
+ moveProjector();
+ setDoDeltaX(1);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStayLockedInSlot();
+ loadSound(2, 0xC8C2507C);
+}
+
+AsCommonProjector::~AsCommonProjector() {
+ _vm->_soundMan->deleteSoundGroup(0x05331081);
+}
+
+uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4807:
+ setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStartLockedInSlot();
+ else
+ stIdle();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stMoving();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ case 0x4839:
+ stStartSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
+ param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
+ sendMessage(_parentScene, 0x4826, 1);
+ } else
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ stStopProjecting();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stTurnToFront();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case 0x480F:
+ stStartProjecting();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsCommonProjector::suMoving() {
+ if (_x <= _klaymen->getX())
+ _x = _klaymen->getX() - 100;
+ else
+ _x = _klaymen->getX() + 100;
+ moveProjector();
+ if (_beforeMoveX == _x) {
+ if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
+ sendMessage(_parentScene, 0x1019, 0);
+ incGlobalVar(V_PROJECTOR_LOCATION, -1);
+ setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
+ } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
+ sendMessage(_parentScene, 0x1019, 1);
+ incGlobalVar(V_PROJECTOR_LOCATION, +1);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ }
+ }
+ Sprite::updateBounds();
+}
+
+void AsCommonProjector::moveProjector() {
+
+ bool nowLockedInSlot = false;
+
+ _y = _asProjectorItem->point.y;
+
+ if (_asProjectorItem->index1 != -1) {
+ int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_asProjectorItem->lockSlotIndex != -1) {
+ int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_lockedInSlot && !nowLockedInSlot)
+ _lockedInSlot = false;
+ else if (!_lockedInSlot && nowLockedInSlot) {
+ playSound(1, 0x5440E474);
+ _lockedInSlot = true;
+ }
+
+}
+
+void AsCommonProjector::stSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ sendMessage(_asPipe, 0x483A, 0);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsCommonProjector::stIdle() {
+ startAnimation(0x10E3042B, 0, -1);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stMoving() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x14A10137, 0, -1);
+ playSound(1, 0xEC008474);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+}
+
+void AsCommonProjector::stStartLockedInSlot() {
+ startAnimation(0x80C32213, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stStayLockedInSlot() {
+ startAnimation(0xD23B207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStartProjecting() {
+ startAnimation(0x50A80517, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 1);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->addSound(0x05331081, 0xCE428854);
+ _vm->_soundMan->playSoundLooping(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stLockedInSlot);
+}
+
+void AsCommonProjector::stLockedInSlot() {
+ sendMessage(_parentScene, 0x480F, 0);
+ startAnimation(0xD833207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStopProjecting() {
+ startAnimation(0x50A94417, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 0);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->deleteSound(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stTurnToFront() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x22CB4A33, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+ NextState(&AsCommonProjector::stMoving);
+}
+
+void AsCommonProjector::stStartSuckedIn() {
+ setGlobalVar(V_PROJECTOR_LOCATION, 4);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ startAnimation(0x708D4712, 0, -1);
+ playSound(2);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
+}
+
+SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
+ : StaticSprite(vm, fileHash, surfacePriority) {
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&StaticSprite::updatePosition);
+}
+
+AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(900, 347, 230);
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
+ _x = 279;
+ _y = 270;
+ if (status == 2) {
+ // Puzzle box after the puzzle was solved
+ startAnimation(0x20060259, 0, -1);
+ playSound(0, 0x419014AC);
+ loadSound(1, 0x61901C29);
+ NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
+ } else if (status == 1) {
+ // Puzzle box appears
+ startAnimation(0x210A0213, 0, -1);
+ playSound(0, 0x41809C6C);
+ NextState(&AsScene1402PuzzleBox::stMoveUpDone);
+ } else {
+ // Puzzle box is here
+ startAnimation(0x20060259, -1, -1);
+ loadSound(1, 0x61901C29);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+}
+
+uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ playSound(1);
+ startAnimation(0x20060259, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1402PuzzleBox::stMoveDownDone);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1402PuzzleBox::stMoveUpDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+}
+
+static const int16 kScene1407MouseFloorY[] = {
+ 106, 150, 191, 230, 267, 308, 350, 395
+};
+
+static const struct {
+ int16 x;
+ int16 floorIndex;
+ int16 sectionIndex;
+ int16 nextHoleIndex;
+} kScene1407MouseHoles[] = {
+ {125, 0, 0, 7},
+ {452, 7, 21, 0},
+ {337, 4, 11, 4},
+ {286, 6, 17, 6},
+ {348, 6, 17, 39},
+ {536, 6, 18, 42},
+ {111, 1, 3, 18},
+ {203, 1, 3, 38},
+ {270, 1, 3, 9},
+ {197, 5, 14, 3},
+ {252, 5, 14, 35},
+ {297, 5, 14, 7},
+ {359, 5, 14, 8},
+ {422, 4, 12, 26},
+ {467, 4, 12, 2},
+ {539, 4, 12, 40},
+ {111, 5, 13, 17},
+ {211, 0, 1, 20},
+ {258, 0, 1, 11},
+ {322, 0, 1, 16},
+ { 99, 6, 16, 31},
+ {142, 6, 16, 27},
+ {194, 6, 16, 12},
+ {205, 2, 6, 45},
+ {264, 2, 6, 10},
+ { 98, 4, 10, 2},
+ {152, 4, 10, 37},
+ {199, 4, 10, 13},
+ {258, 4, 10, 16},
+ {100, 7, 19, 43},
+ {168, 7, 19, 23},
+ {123, 3, 8, 14},
+ {181, 3, 8, 39},
+ {230, 3, 8, 28},
+ {292, 3, 8, 22},
+ {358, 3, 8, 36},
+ {505, 3, 9, 44},
+ {400, 2, 7, 34},
+ {454, 2, 7, 32},
+ {532, 2, 7, 46},
+ {484, 5, 15, 25},
+ {529, 5, 15, 30},
+ {251, 7, 20, 48},
+ {303, 7, 20, 21},
+ {360, 7, 20, 33},
+ {503, 0, 2, 5},
+ {459, 1, 4, 19},
+ {530, 1, 4, 42},
+ {111, 2, 5, 47},
+ {442, 6, 18, 1}
+};
+
+static const struct {
+ int16 x1, x2;
+ int16 goodHoleIndex;
+} kScene1407MouseSections[] = {
+ {100, 149, 0},
+ {182, 351, 17},
+ {430, 524, 45},
+ { 89, 293, 7},
+ {407, 555, 47},
+ { 89, 132, 48},
+ {178, 303, 23},
+ {367, 551, 38},
+ {105, 398, 31},
+ {480, 537, 36},
+ { 84, 275, 27},
+ {318, 359, 2},
+ {402, 560, 15},
+ { 91, 132, 16},
+ {179, 400, 10},
+ {461, 552, 41},
+ { 86, 218, 21},
+ {267, 376, 4},
+ {420, 560, 49},
+ { 77, 188, 30},
+ {237, 394, 44},
+ {438, 515, 5}
+};
+
+AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
+
+ createSurface(100, 117, 45);
+ _x = 108;
+ _y = 106;
+ stIdleLookAtGoodHole();
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene1407Mouse::suWalkTo() {
+ int16 xdelta = _walkDestX - _x;
+ if (xdelta > _deltaX)
+ xdelta = _deltaX;
+ else if (xdelta < -_deltaX)
+ xdelta = -_deltaX;
+ _deltaX = 0;
+ if (_walkDestX == _x)
+ sendMessage(this, 0x1019, 0);
+ else {
+ _x += xdelta;
+ updateBounds();
+ }
+}
+
+void AsScene1407Mouse::upGoThroughHole() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ SetUpdateHandler(&AnimatedSprite::update);
+ gotoNextState();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ {
+ int16 mouseX = param.asPoint().x;
+ int16 mouseY = param.asPoint().y;
+ int holeIndex;
+ for (holeIndex = 0; holeIndex < 50; holeIndex++) {
+ int16 holeX = kScene1407MouseHoles[holeIndex].x;
+ int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
+ if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
+ break;
+ }
+ if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
+ _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
+ _walkDestX = kScene1407MouseHoles[holeIndex].x;
+ stWalkToHole();
+ } else {
+ if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
+ else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
+ else
+ _walkDestX = mouseX;
+ stWalkToDest();
+ }
+ }
+ break;
+ case 0x1019:
+ gotoNextState();
+ break;
+ case 0x2001:
+ {
+ // Reset the position
+ // Find the nearest hole and go through it, and exit at the first hole
+ int16 distance = 640;
+ int matchIndex = 50;
+ for (int index = 0; index < 50; index++)
+ if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
+ ABS(kScene1407MouseHoles[index].x - _x) < distance) {
+ matchIndex = index;
+ distance = ABS(kScene1407MouseHoles[index].x - _x);
+ }
+ if (matchIndex < 50) {
+ _nextHoleIndex = 0;
+ _walkDestX = kScene1407MouseHoles[matchIndex].x;
+ stWalkToHole();
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1407Mouse::stIdleLookAtGoodHole() {
+ setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
+ startAnimation(0x72215194, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1407Mouse::stWalkToDest() {
+ if (_walkDestX != _x) {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
+ }
+}
+
+void AsScene1407Mouse::stWalkToHole() {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stGoThroughHole);
+}
+
+void AsScene1407Mouse::stGoThroughHole() {
+ startAnimation(0x72215194, 0, -1);
+ setVisible(false);
+ _countdown = 12;
+ SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ NextState(&AsScene1407Mouse::stArriveAtHole);
+}
+
+void AsScene1407Mouse::stArriveAtHole() {
+ _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
+ _x = kScene1407MouseHoles[_nextHoleIndex].x;
+ _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
+ if (_nextHoleIndex == 1) {
+ sendMessage(_parentScene, 0x2000, 0);
+ _walkDestX = 512;
+ stWalkToDest();
+ setVisible(true);
+ } else {
+ _walkDestX = _x + 14;
+ stWalkToDest();
+ setVisible(true);
+ }
+}
+
+static const NPoint kAsScene1405TileItemPositions[] = {
+ {100, 80}, {162, 78}, {222, 76}, {292, 76},
+ {356, 82}, {422, 84}, {488, 86}, {550, 90},
+ {102, 134}, {164, 132}, {224, 136}, {294, 136},
+ {360, 136}, {422, 138}, {484, 144}, {548, 146},
+ { 98, 196}, {160, 200}, {228, 200}, {294, 202},
+ {360, 198}, {424, 200}, {482, 202}, {548, 206},
+ { 98, 260}, {160, 264}, {226, 260}, {296, 262},
+ {358, 260}, {424, 262}, {486, 264}, {550, 266},
+ { 94, 322}, {160, 316}, {226, 316}, {296, 320},
+ {358, 322}, {422, 324}, {488, 322}, {550, 322},
+ { 98, 380}, {160, 376}, {226, 376}, {294, 378},
+ {356, 380}, {420, 380}, {490, 378}, {552, 376}
+};
+
+AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
+
+ loadSound(0, 0x05308101);
+ setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
+ _x = kAsScene1405TileItemPositions[_tileIndex].x;
+ _y = kAsScene1405TileItemPositions[_tileIndex].y;
+ createSurface1(0x844B805C, 1100);
+ setVisible(false);
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
+ _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
+ startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
+ _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
+ SetUpdateHandler(&AsScene1405Tile::update);
+ SetMessageHandler(&AsScene1405Tile::handleMessage);
+}
+
+void AsScene1405Tile::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0))
+ show();
+}
+
+uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
+ show();
+ sendMessage(_parentScene, 0x2000, _tileIndex);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1405Tile::show() {
+ if (!_isShowing) {
+ _isShowing = true;
+ playSound(0);
+ setVisible(true);
+ }
+}
+
+void AsScene1405Tile::hide() {
+ if (_isShowing) {
+ _isShowing = false;
+ playSound(0);
+ setVisible(false);
+ }
+}
+
+KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ }
+ return 0;
+}
+
+KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ SetFilterY(&Sprite::defFilterY);
+}
+
+uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1403[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1403, ARRAYSIZE(klaymenIdleTable1403));
+}
+
+uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+// KmScene1404
+
+KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1400_sprites.h b/engines/neverhood/modules/module1400_sprites.h
new file mode 100644
index 0000000000..49b91fe0cf
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.h
@@ -0,0 +1,198 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1401Pipe : public AnimatedSprite {
+public:
+ AsScene1401Pipe(NeverhoodEngine *vm);
+ virtual ~AsScene1401Pipe();
+protected:
+ int _countdown1;
+ int _countdown2;
+ void update();
+ void upSuckInProjector();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartSucking();
+ void stDoneSucking();
+ void stSuckInProjector();
+};
+
+class AsScene1401Mouse : public AnimatedSprite {
+public:
+ AsScene1401Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401Cheese : public AnimatedSprite {
+public:
+ AsScene1401Cheese(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401BackDoor : public AnimatedSprite {
+public:
+ AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+struct AsCommonProjectorItem {
+ NPoint point;
+ int8 maxSlotCount;
+ int8 lockSlotIndex;
+ int8 index1;
+ int8 leftBorderLeaves;
+ int8 rightBorderLeaves;
+};
+
+class AsCommonProjector : public AnimatedSprite {
+public:
+ AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
+ virtual ~AsCommonProjector();
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ Sprite *_asPipe;
+ const AsCommonProjectorItem *_asProjectorItem;
+ int16 _beforeMoveX;
+ bool _lockedInSlot;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void moveProjector();
+ void stSuckedIn();
+ void stIdle();
+ void stMoving();
+ void stStartLockedInSlot();
+ void stStayLockedInSlot();
+ void stStartProjecting();
+ void stLockedInSlot();
+ void stStopProjecting();
+ void stTurnToFront();
+ void stStartSuckedIn();
+};
+
+class SsScene1402BridgePart : public StaticSprite {
+public:
+ SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
+};
+
+class AsScene1402PuzzleBox : public AnimatedSprite {
+public:
+ AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stMoveUpDone();
+ void stMoveDownDone();
+ void stMoveDownSolvedDone();
+};
+
+class AsScene1407Mouse : public AnimatedSprite {
+public:
+ AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int16 _walkDestX;
+ int16 _currSectionIndex;
+ int16 _nextHoleIndex;
+ int _countdown;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suWalkTo();
+ void upGoThroughHole();
+ void stIdleLookAtGoodHole();
+ void stWalkToDest();
+ void stWalkToHole();
+ void stGoThroughHole();
+ void stArriveAtHole();
+};
+
+class Scene1405;
+
+class AsScene1405Tile : public AnimatedSprite {
+public:
+ AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
+ void show();
+ void hide();
+protected:
+ Scene1405 *_parentScene;
+ bool _isShowing;
+ uint32 _tileIndex;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1401 : public Klaymen {
+public:
+ KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1402 : public Klaymen {
+public:
+ KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1403 : public Klaymen {
+public:
+ KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1404 : public Klaymen {
+public:
+ KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1400_SPRITES_H */
diff --git a/engines/neverhood/modules/module1500.cpp b/engines/neverhood/modules/module1500.cpp
index 2a9597b1fd..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
@@ -35,7 +35,7 @@ Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which)
}
void Module1500::createScene(int sceneNum, int which) {
- debug("Module1500::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1500::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -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 f7e3c37d84..0df7dd8925 100644
--- a/engines/neverhood/modules/module1600.cpp
+++ b/engines/neverhood/modules/module1600.cpp
@@ -20,10 +20,12 @@
*
*/
-#include "neverhood/modules/module1600.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -34,7 +36,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)
@@ -59,7 +61,7 @@ Module1600::~Module1600() {
}
void Module1600::createScene(int sceneNum, int which) {
- debug("Module1600::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1600::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -109,7 +111,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);
@@ -183,832 +185,13 @@ void Module1600::updateScene() {
}
}
-AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
-
- createSurface(200, 556, 328);
- _x = x;
- _y = y;
-
- _inMainArea = false;
- _exitDirection = 0;
- _currPointIndex = 0;
- _hasAgainDestPoint = false;
- _stepError = 0;
- _hasAgainDestPointIndex = false;
- _steps = 0;
- _isBraking = false;
- _yMoveTotalSteps = 0;
- _isBusy = false;
- _isIdle = false;
- _isMoving = true;
- _rectFlag = false;
- _newDeltaXType = -1;
- _soundCounter = 0;
- _pathPoints = NULL;
- _currMoveDirection = 0;
-
- startAnimation(0xD4220027, 0, -1);
- setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
-
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-AsCommonCar::~AsCommonCar() {
- if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
- setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
-}
-
-void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
- _pathPoints = pathPoints;
-}
-
-void AsCommonCar::update() {
- if (_newDeltaXType >= 0) {
- setDoDeltaX(_newDeltaXType);
- _newDeltaXType = -1;
- }
- AnimatedSprite::update();
- if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- sendPointMessage(this, 0x2004, _againDestPoint);
- } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPointIndex = false;
- sendMessage(this, 0x2003, _againDestPointIndex);
- }
- updateMovement();
- updateSound();
-}
-
-void AsCommonCar::upIdle() {
- update();
- if (++_idleCounter >= _idleCounterMax)
- stIdleBlink();
- updateSound();
-}
-
-uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1019:
- SetSpriteUpdate(NULL);
- break;
- case 0x2002:
- // Set the current position without moving
- _currPointIndex = param.asInteger();
- _stepError = 0;
- _x = pathPoint(_currPointIndex).x;
- _y = pathPoint(_currPointIndex).y;
- break;
- case 0x2003:
- // Move to a point by its index
- {
- int newPointIndex = param.asInteger();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- _destX = pathPoint(newPointIndex).x;
- _destY = pathPoint(newPointIndex).y;
- if (_currPointIndex < newPointIndex) {
- moveToNextPoint();
- } else if (_currPointIndex == newPointIndex && _stepError == 0) {
- if (_currPointIndex == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2005, 0);
- } else if (_currPointIndex == (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2006, 0);
- }
- } else {
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPointIndex = true;
- _againDestPointIndex = newPointIndex;
- }
- }
- break;
- case 0x2004:
- // Move to the point closest to the parameter point
- {
- int minMatchIndex = -1;
- int minMatchDistance, distance;
- NPoint pt = param.asPoint();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- // Check if we're already exiting (or something)
- if ((pt.x <= 20 && _exitDirection == 1) ||
- (pt.x >= 620 && _exitDirection == 3) ||
- (pt.y <= 20 && _exitDirection == 2) ||
- (pt.y >= 460 && _exitDirection == 4))
- break;
- _destX = pt.x;
- _destY = pt.y;
- minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
- for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- for (int i = _currPointIndex; i >= 0; i--) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- if (minMatchIndex == -1) {
- if (_currPointIndex == 0)
- moveToPrevPoint();
- else
- SetSpriteUpdate(NULL);
- } else {
- if (minMatchIndex > _currPointIndex)
- moveToNextPoint();
- else
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPoint = true;
- _againDestPoint = pt;
- }
- }
- break;
- case 0x2007:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- break;
- case 0x2008:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- break;
- case 0x2009:
- stEnterCar();
- break;
- case 0x200A:
- stLeaveCar();
- break;
- case 0x200E:
- stTurnCar();
- break;
- case 0x200F:
- stCarAtHome();
- _newDeltaXType = param.asInteger();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isBusy && param.asInteger() == 0x025424A2)
- gotoNextState();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x2009:
- stEnterCar();
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x200A, 0);
- SetMessageHandler(&AsCommonCar::handleMessage);
- break;
- }
- return 0;
-}
-
-void AsCommonCar::stCarAtHome() {
- bool doDeltaX = _doDeltaX;
- SetSpriteUpdate(NULL);
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- _isBraking = false;
- _isBusy = false;
- _isIdle = false;
- _isMoving = false;
- _rectFlag = false;
- NextState(&AsCommonCar::stLeanForwardIdle);
- startAnimation(0x35698F78, 0, -1);
- setDoDeltaX(doDeltaX ? 1 : 0);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::updateTurnMovement() {
- if (_turnMoveStatus == 1) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- } else if (_turnMoveStatus == 2) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- }
-}
-
-void AsCommonCar::updateMovement() {
- if (_isBraking && !_isIdle && !_isBusy) {
- gotoNextState();
- _isMoving = false;
- _isIdle = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
- } else if (!_isBraking && _steps && _isIdle) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
- gotoNextState();
- _currMoveDirection = _newMoveDirection;
- stUpdateMoveDirection();
- }
-}
-
-void AsCommonCar::stEnterCar() {
- startAnimation(0xA86A9538, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stLeaveCar() {
- startAnimation(0xA86A9538, -1, -1);
- _playBackwards = true;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmLeaveCar);
-}
-
-void AsCommonCar::stLeanForwardIdle() {
- startAnimation(0x35698F78, 0, -1);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::evIdleDone() {
- SetUpdateHandler(&AsCommonCar::update);
-}
-
-void AsCommonCar::stIdleBlink() {
- startAnimation(0xB579A77C, 0, -1);
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stUpdateMoveDirection() {
- _isMoving = true;
- if (_currMoveDirection == 1)
- startAnimation(0xD4AA03A4, 0, -1);
- else if (_currMoveDirection == 3)
- startAnimation(0xD00A1364, 0, -1);
- else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
- stTurnCar();
- else
- startAnimation(0xD4220027, 0, -1);
- setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
-}
-
-void AsCommonCar::moveToNextPoint() {
- if (_currPointIndex >= (int)_pathPoints->size() - 1) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- } else {
- NPoint nextPt = pathPoint(_currPointIndex + 1);
- NPoint currPt = pathPoint(_currPointIndex);
- if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
- (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToNextPoint();
- else
- stBrakeMoveToNextPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToNextPoint() {
- gotoNextState();
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
-}
-
-void AsCommonCar::stTurnCar() {
- // Turn to left/right #1
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 0;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToNextPoint() {
- // Turn to left/right #2
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 1;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToPrevPoint() {
- // Turn to left/right #3
- FinalizeState(NULL);
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 2;
- updateTurnMovement();
-}
-
-void AsCommonCar::moveToPrevPoint() {
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- } else {
- NPoint prevPt;
- NPoint currPt;
- if (_stepError == 0) {
- prevPt = pathPoint(_currPointIndex - 1);
- currPt = pathPoint(_currPointIndex);
- } else {
- prevPt = pathPoint(_currPointIndex);
- currPt = pathPoint(_currPointIndex + 1);
- }
- if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
- (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToPrevPoint();
- else
- stBrakeMoveToPrevPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToPrevPoint() {
- FinalizeState(NULL);
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
-}
-
-void AsCommonCar::evTurnCarDone() {
- _isBusy = false;
- setDoDeltaX(2);
- _newMoveDirection = 0;
- stUpdateMoveDirection();
-}
-
-void AsCommonCar::suMoveToNextPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex >= (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 2;
- if (pt1.x < pt2.x)
- _newMoveDirection = 4;
- if (stepsCtr + _stepError >= deltaX) {
- stepsCtr -= deltaX;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX += stepsCtr;
- else
- newX -= stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 3;
- if (pt1.y < pt2.y)
- _newMoveDirection = 1;
- if (firstTime) {
- if (pt1.y >= pt2.y)
- stepsCtr += 7;
- else {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- }
- _ySteps = stepsCtr;
- }
- if (stepsCtr + _stepError >= deltaY) {
- stepsCtr -= deltaY;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY += stepsCtr;
- else
- newY -= stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(_pathPoints->size() - 1).x;
- _destY = pathPoint(_pathPoints->size() - 1).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == (int)_pathPoints->size() - 1) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- }
- }
-
-}
-
-void AsCommonCar::suMoveToPrevPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- if (_stepError == 0)
- _currPointIndex--;
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 4;
- if (pt1.x < pt2.x)
- _newMoveDirection = 2;
- if (_stepError == 0)
- _stepError = deltaX;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX -= stepsCtr;
- else
- newX += stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 1;
- if (pt1.y < pt2.y)
- _newMoveDirection = 3;
- if (firstTime) {
- if (pt1.y >= pt2.y) {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- } else {
- stepsCtr += 7;
- }
- _ySteps = stepsCtr;
- }
- if (_stepError == 0)
- _stepError = deltaY;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY -= stepsCtr;
- else
- newY += stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(0).x;
- _destY = pathPoint(0).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == 0 && _stepError == 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- }
- }
-
-}
-
-void AsCommonCar::updateSound() {
- int maxSoundCounter = 0;
- _soundCounter++;
- if (_steps != 0 && !_isIdle) {
- if (_currMoveDirection == 1)
- maxSoundCounter = 18 - _steps;
- else if (_currMoveDirection == 3) {
- maxSoundCounter = 5 - _steps;
- if (maxSoundCounter < 1)
- maxSoundCounter = 1;
- } else
- maxSoundCounter = 14 - _steps;
- } else
- maxSoundCounter = 21;
- if (_soundCounter >= maxSoundCounter) {
- sendMessage(_parentScene, 0x200D, 0);
- _soundCounter = 0;
- }
-}
-
-AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
-
- setDoDeltaX(1);
- startAnimation(0x1209E09F, 1, -1);
- _newStickFrameIndex = 1;
-}
-
-AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
-
- setDoDeltaX(1);
- _newStickFrameIndex = 0;
-}
-
-AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- createSurface1(0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsCommonCarConnector::update);
-}
-
-void AsCommonCarConnector::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
-void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource) {
- const uint trackCount = size();
- minMatchTrackIndex = -1;
- minMatchDistance = 640;
- for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
- NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
- for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
- NPoint testPt = (*pointList)[pointIndex];
- int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
- if (distance < minMatchDistance) {
- minMatchTrackIndex = trackIndex;
- minMatchDistance = distance;
- }
- }
- }
-}
-
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asCar(NULL), _countdown1(0) {
setGlobalVar(V_CAR_DELTA_X, 1);
-
+
SetMessageHandler(&Scene1608::hmLowerFloor);
-
+
_asKey = insertSprite<AsCommonKey>(this, 1, 1100, 198, 220);
addCollisionSprite(_asKey);
@@ -1092,9 +275,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 +317,9 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
_carClipFlag = true;
_carStatus = 0;
}
-
+
_palette->addPalette("paKlayRed", 0, 64, 0);
-
+
}
Scene1608::~Scene1608() {
@@ -1308,7 +491,7 @@ uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam &param, Entity
}
return 0;
}
-
+
void Scene1608::updateKlaymenCliprect() {
if (_kmScene1608->getX() <= 375)
_kmScene1608->setClipRect(_clipRect1);
@@ -1321,17 +504,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 +591,5 @@ bool Scene1609::testVars() {
return true;
}
-
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1600.h b/engines/neverhood/modules/module1600.h
index 0bf44ff7b8..f08eaad8fc 100644
--- a/engines/neverhood/modules/module1600.h
+++ b/engines/neverhood/modules/module1600.h
@@ -26,12 +26,9 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module3000.h"
namespace Neverhood {
-// Module1600
-
class Module1600 : public Module {
public:
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,90 +39,7 @@ protected:
void updateScene();
};
-class AsCommonCar : public AnimatedSprite {
-public:
- AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~AsCommonCar();
- void setPathPoints(NPointArray *pathPoints);
-protected:
- Scene *_parentScene;
- NPointArray *_pathPoints;
- int _newMoveDirection;
- int _currMoveDirection;
- int _exitDirection;
- int _currPointIndex;
- bool _hasAgainDestPoint;
- NPoint _againDestPoint;
- bool _hasAgainDestPointIndex;
- int _againDestPointIndex;
- bool _inMainArea;
- bool _isBraking;
- bool _isBusy;
- bool _isIdle;
- bool _isMoving;
- bool _rectFlag;
- int _idleCounter;
- int _idleCounterMax;
- int _steps;
- int _stepError;
- int _lastDistance;
- int _yMoveTotalSteps;
- int _ySteps;
- int _newDeltaXType;
- int _soundCounter;
- int _turnMoveStatus;
- int16 _destX, _destY;
- NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
- void stCarAtHome();
- void updateTurnMovement();
- void updateMovement();
- void stEnterCar();
- void stLeaveCar();
- void stLeanForwardIdle();
- void evIdleDone();
- void stIdleBlink();
- void stUpdateMoveDirection();
- void stTurnCar();
- void moveToNextPoint();
- void stBrakeMoveToNextPoint();
- void stTurnCarMoveToNextPoint();
- void moveToPrevPoint();
- void stBrakeMoveToPrevPoint();
- void stTurnCarMoveToPrevPoint();
- void evTurnCarDone();
- void suMoveToNextPoint();
- void suMoveToPrevPoint();
- void updateSound();
-};
-
-class AsCommonIdleCarLower : public AnimatedSprite {
-public:
- AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonIdleCarFull : public AnimatedSprite {
-public:
- AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonCarConnector : public AnimatedSprite {
-public:
- AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
-protected:
- AsCommonCar *_asCar;
- void update();
-};
-
-class Tracks : public Common::Array<TrackInfo*> {
-public:
- void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource);
-};
+class AsCommonCar;
class Scene1608 : public Scene {
public:
@@ -161,7 +75,10 @@ protected:
void updateKlaymenCliprect();
};
+class AsScene3011Symbol;
+
class Scene1609 : public Scene {
+ friend class Console;
public:
Scene1609(NeverhoodEngine *vm, Module *parentModule);
protected:
diff --git a/engines/neverhood/modules/module1600_sprites.cpp b/engines/neverhood/modules/module1600_sprites.cpp
new file mode 100644
index 0000000000..06a00c82c0
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.cpp
@@ -0,0 +1,934 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1600_sprites.h"
+
+namespace Neverhood {
+
+AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
+
+ createSurface(200, 556, 328);
+ _x = x;
+ _y = y;
+
+ _inMainArea = false;
+ _exitDirection = 0;
+ _currPointIndex = 0;
+ _hasAgainDestPoint = false;
+ _stepError = 0;
+ _hasAgainDestPointIndex = false;
+ _steps = 0;
+ _isBraking = false;
+ _yMoveTotalSteps = 0;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = true;
+ _rectFlag = false;
+ _newDeltaXType = -1;
+ _soundCounter = 0;
+ _pathPoints = NULL;
+ _currMoveDirection = 0;
+
+ startAnimation(0xD4220027, 0, -1);
+ setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
+
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+AsCommonCar::~AsCommonCar() {
+ if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
+ setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
+}
+
+void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
+ _pathPoints = pathPoints;
+}
+
+void AsCommonCar::update() {
+ if (_newDeltaXType >= 0) {
+ setDoDeltaX(_newDeltaXType);
+ _newDeltaXType = -1;
+ }
+ AnimatedSprite::update();
+ if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ sendPointMessage(this, 0x2004, _againDestPoint);
+ } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPointIndex = false;
+ sendMessage(this, 0x2003, _againDestPointIndex);
+ }
+ updateMovement();
+ updateSound();
+}
+
+void AsCommonCar::upIdle() {
+ update();
+ if (++_idleCounter >= _idleCounterMax)
+ stIdleBlink();
+ updateSound();
+}
+
+uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1019:
+ SetSpriteUpdate(NULL);
+ break;
+ case 0x2002:
+ // Set the current position without moving
+ _currPointIndex = param.asInteger();
+ _stepError = 0;
+ _x = pathPoint(_currPointIndex).x;
+ _y = pathPoint(_currPointIndex).y;
+ break;
+ case 0x2003:
+ // Move to a point by its index
+ {
+ int newPointIndex = param.asInteger();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ _destX = pathPoint(newPointIndex).x;
+ _destY = pathPoint(newPointIndex).y;
+ if (_currPointIndex < newPointIndex) {
+ moveToNextPoint();
+ } else if (_currPointIndex == newPointIndex && _stepError == 0) {
+ if (_currPointIndex == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2005, 0);
+ } else if (_currPointIndex == (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ } else {
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPointIndex = true;
+ _againDestPointIndex = newPointIndex;
+ }
+ }
+ break;
+ case 0x2004:
+ // Move to the point closest to the parameter point
+ {
+ int minMatchIndex = -1;
+ int minMatchDistance, distance;
+ NPoint pt = param.asPoint();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ // Check if we're already exiting (or something)
+ if ((pt.x <= 20 && _exitDirection == 1) ||
+ (pt.x >= 620 && _exitDirection == 3) ||
+ (pt.y <= 20 && _exitDirection == 2) ||
+ (pt.y >= 460 && _exitDirection == 4))
+ break;
+ _destX = pt.x;
+ _destY = pt.y;
+ minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
+ for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ for (int i = _currPointIndex; i >= 0; i--) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ if (minMatchIndex == -1) {
+ if (_currPointIndex == 0)
+ moveToPrevPoint();
+ else
+ SetSpriteUpdate(NULL);
+ } else {
+ if (minMatchIndex > _currPointIndex)
+ moveToNextPoint();
+ else
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPoint = true;
+ _againDestPoint = pt;
+ }
+ }
+ break;
+ case 0x2007:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ break;
+ case 0x2008:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ break;
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x200A:
+ stLeaveCar();
+ break;
+ case 0x200E:
+ stTurnCar();
+ break;
+ case 0x200F:
+ stCarAtHome();
+ _newDeltaXType = param.asInteger();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_isBusy && param.asInteger() == 0x025424A2)
+ gotoNextState();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x3002:
+ sendMessage(_parentScene, 0x200A, 0);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ break;
+ }
+ return 0;
+}
+
+void AsCommonCar::stCarAtHome() {
+ bool doDeltaX = _doDeltaX;
+ SetSpriteUpdate(NULL);
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ _isBraking = false;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = false;
+ _rectFlag = false;
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ startAnimation(0x35698F78, 0, -1);
+ setDoDeltaX(doDeltaX ? 1 : 0);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::updateTurnMovement() {
+ if (_turnMoveStatus == 1) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ } else if (_turnMoveStatus == 2) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ }
+}
+
+void AsCommonCar::updateMovement() {
+ if (_isBraking && !_isIdle && !_isBusy) {
+ gotoNextState();
+ _isMoving = false;
+ _isIdle = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ } else if (!_isBraking && _steps && _isIdle) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
+ gotoNextState();
+ _currMoveDirection = _newMoveDirection;
+ stUpdateMoveDirection();
+ }
+}
+
+void AsCommonCar::stEnterCar() {
+ startAnimation(0xA86A9538, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stLeaveCar() {
+ startAnimation(0xA86A9538, -1, -1);
+ _playBackwards = true;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmLeaveCar);
+}
+
+void AsCommonCar::stLeanForwardIdle() {
+ startAnimation(0x35698F78, 0, -1);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::evIdleDone() {
+ SetUpdateHandler(&AsCommonCar::update);
+}
+
+void AsCommonCar::stIdleBlink() {
+ startAnimation(0xB579A77C, 0, -1);
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stUpdateMoveDirection() {
+ _isMoving = true;
+ if (_currMoveDirection == 1)
+ startAnimation(0xD4AA03A4, 0, -1);
+ else if (_currMoveDirection == 3)
+ startAnimation(0xD00A1364, 0, -1);
+ else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
+ stTurnCar();
+ else
+ startAnimation(0xD4220027, 0, -1);
+ setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
+}
+
+void AsCommonCar::moveToNextPoint() {
+ if (_currPointIndex >= (int)_pathPoints->size() - 1) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ } else {
+ NPoint nextPt = pathPoint(_currPointIndex + 1);
+ NPoint currPt = pathPoint(_currPointIndex);
+ if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToNextPoint();
+ else
+ stBrakeMoveToNextPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToNextPoint() {
+ gotoNextState();
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
+}
+
+void AsCommonCar::stTurnCar() {
+ // Turn to left/right #1
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 0;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToNextPoint() {
+ // Turn to left/right #2
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 1;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToPrevPoint() {
+ // Turn to left/right #3
+ FinalizeState(NULL);
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 2;
+ updateTurnMovement();
+}
+
+void AsCommonCar::moveToPrevPoint() {
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ } else {
+ NPoint prevPt;
+ NPoint currPt;
+ if (_stepError == 0) {
+ prevPt = pathPoint(_currPointIndex - 1);
+ currPt = pathPoint(_currPointIndex);
+ } else {
+ prevPt = pathPoint(_currPointIndex);
+ currPt = pathPoint(_currPointIndex + 1);
+ }
+ if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToPrevPoint();
+ else
+ stBrakeMoveToPrevPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToPrevPoint() {
+ FinalizeState(NULL);
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
+}
+
+void AsCommonCar::evTurnCarDone() {
+ _isBusy = false;
+ setDoDeltaX(2);
+ _newMoveDirection = 0;
+ stUpdateMoveDirection();
+}
+
+void AsCommonCar::suMoveToNextPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex >= (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 2;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 4;
+ if (stepsCtr + _stepError >= deltaX) {
+ stepsCtr -= deltaX;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX += stepsCtr;
+ else
+ newX -= stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 3;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 1;
+ if (firstTime) {
+ if (pt1.y >= pt2.y)
+ stepsCtr += 7;
+ else {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (stepsCtr + _stepError >= deltaY) {
+ stepsCtr -= deltaY;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY += stepsCtr;
+ else
+ newY -= stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(_pathPoints->size() - 1).x;
+ _destY = pathPoint(_pathPoints->size() - 1).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == (int)_pathPoints->size() - 1) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::suMoveToPrevPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ if (_stepError == 0)
+ _currPointIndex--;
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 4;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 2;
+ if (_stepError == 0)
+ _stepError = deltaX;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX -= stepsCtr;
+ else
+ newX += stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 1;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 3;
+ if (firstTime) {
+ if (pt1.y >= pt2.y) {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ } else {
+ stepsCtr += 7;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (_stepError == 0)
+ _stepError = deltaY;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY -= stepsCtr;
+ else
+ newY += stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(0).x;
+ _destY = pathPoint(0).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::updateSound() {
+ int maxSoundCounter = 0;
+ _soundCounter++;
+ if (_steps != 0 && !_isIdle) {
+ if (_currMoveDirection == 1)
+ maxSoundCounter = 18 - _steps;
+ else if (_currMoveDirection == 3) {
+ maxSoundCounter = 5 - _steps;
+ if (maxSoundCounter < 1)
+ maxSoundCounter = 1;
+ } else
+ maxSoundCounter = 14 - _steps;
+ } else
+ maxSoundCounter = 21;
+ if (_soundCounter >= maxSoundCounter) {
+ sendMessage(_parentScene, 0x200D, 0);
+ _soundCounter = 0;
+ }
+}
+
+AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
+
+ setDoDeltaX(1);
+ startAnimation(0x1209E09F, 1, -1);
+ _newStickFrameIndex = 1;
+}
+
+AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
+
+ setDoDeltaX(1);
+ _newStickFrameIndex = 0;
+}
+
+AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ createSurface1(0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsCommonCarConnector::update);
+}
+
+void AsCommonCarConnector::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource) {
+ const uint trackCount = size();
+ minMatchTrackIndex = -1;
+ minMatchDistance = 640;
+ for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
+ NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
+ for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
+ NPoint testPt = (*pointList)[pointIndex];
+ int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
+ if (distance < minMatchDistance) {
+ minMatchTrackIndex = trackIndex;
+ minMatchDistance = distance;
+ }
+ }
+ }
+}
+
+KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2032:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2032, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2032, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1600_sprites.h b/engines/neverhood/modules/module1600_sprites.h
new file mode 100644
index 0000000000..fa59475dad
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.h
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsCommonCar : public AnimatedSprite {
+public:
+ AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~AsCommonCar();
+ void setPathPoints(NPointArray *pathPoints);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pathPoints;
+ int _newMoveDirection;
+ int _currMoveDirection;
+ int _exitDirection;
+ int _currPointIndex;
+ bool _hasAgainDestPoint;
+ NPoint _againDestPoint;
+ bool _hasAgainDestPointIndex;
+ int _againDestPointIndex;
+ bool _inMainArea;
+ bool _isBraking;
+ bool _isBusy;
+ bool _isIdle;
+ bool _isMoving;
+ bool _rectFlag;
+ int _idleCounter;
+ int _idleCounterMax;
+ int _steps;
+ int _stepError;
+ int _lastDistance;
+ int _yMoveTotalSteps;
+ int _ySteps;
+ int _newDeltaXType;
+ int _soundCounter;
+ int _turnMoveStatus;
+ int16 _destX, _destY;
+ NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
+ void stCarAtHome();
+ void updateTurnMovement();
+ void updateMovement();
+ void stEnterCar();
+ void stLeaveCar();
+ void stLeanForwardIdle();
+ void evIdleDone();
+ void stIdleBlink();
+ void stUpdateMoveDirection();
+ void stTurnCar();
+ void moveToNextPoint();
+ void stBrakeMoveToNextPoint();
+ void stTurnCarMoveToNextPoint();
+ void moveToPrevPoint();
+ void stBrakeMoveToPrevPoint();
+ void stTurnCarMoveToPrevPoint();
+ void evTurnCarDone();
+ void suMoveToNextPoint();
+ void suMoveToPrevPoint();
+ void updateSound();
+};
+
+class AsCommonIdleCarLower : public AnimatedSprite {
+public:
+ AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonIdleCarFull : public AnimatedSprite {
+public:
+ AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonCarConnector : public AnimatedSprite {
+public:
+ AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
+protected:
+ AsCommonCar *_asCar;
+ void update();
+};
+
+class Tracks : public Common::Array<TrackInfo*> {
+public:
+ void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource);
+};
+
+class KmScene1608 : public Klaymen {
+public:
+ KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp
index 3a6d1f80cb..e3a5fc3663 100644
--- a/engines/neverhood/modules/module1700.cpp
+++ b/engines/neverhood/modules/module1700.cpp
@@ -20,8 +20,9 @@
*
*/
-#include "neverhood/modules/module1700.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1700.h"
+#include "neverhood/modules/module1700_sprites.h"
namespace Neverhood {
@@ -36,7 +37,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);
@@ -58,7 +59,7 @@ Module1700::~Module1700() {
}
void Module1700::createScene(int sceneNum, int which) {
- debug("Module1700::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1700::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -125,8 +126,6 @@ void Module1700::updateScene() {
}
}
}
-
-// Scene1705
static const uint32 kScene1705FileHashes[] = {
0x910EA801, 0x920EA801, 0x940EA801,
@@ -135,52 +134,11 @@ static const uint32 kScene1705FileHashes[] = {
0xD10EA801, 0x110EA801, 0x910EA800
};
-SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = _spriteResource.getPosition().x + symbolIndex * 30;
- _y = _spriteResource.getPosition().y + 160;
- updatePosition();
-}
-
-SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
-
- if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
- SetMessageHandler(&SsScene1705Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
- _collisionBoundsOffset = _drawOffset;
- _collisionBoundsOffset.x -= 4;
- _collisionBoundsOffset.y -= 8;
- _collisionBoundsOffset.width += 8;
- _collisionBoundsOffset.height += 16;
- Sprite::updateBounds();
-}
-
-uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(1) {
Sprite *tempSprite;
-
+
setGlobalVar(V_FELL_DOWN_HOLE, 1);
_vm->gameModule()->initCannonSymbolsPuzzle();
@@ -271,7 +229,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..09daff2acf 100644
--- a/engines/neverhood/modules/module1700.h
+++ b/engines/neverhood/modules/module1700.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/smackerscene.h"
namespace Neverhood {
@@ -40,22 +39,6 @@ protected:
void updateScene();
};
-// Scene1705
-
-class SsScene1705WallSymbol : public StaticSprite {
-public:
- SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
-};
-
-class SsScene1705Tape : public StaticSprite {
-public:
- SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _tapeIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1705 : public Scene {
public:
Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1700_sprites.cpp b/engines/neverhood/modules/module1700_sprites.cpp
new file mode 100644
index 0000000000..6274e5a8cc
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1700_sprites.h"
+
+namespace Neverhood {
+
+SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = _spriteResource.getPosition().x + symbolIndex * 30;
+ _y = _spriteResource.getPosition().y + 160;
+ updatePosition();
+}
+
+SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
+
+ if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
+ SetMessageHandler(&SsScene1705Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ _collisionBoundsOffset = _drawOffset;
+ _collisionBoundsOffset.x -= 4;
+ _collisionBoundsOffset.y -= 8;
+ _collisionBoundsOffset.width += 8;
+ _collisionBoundsOffset.height += 16;
+ Sprite::updateBounds();
+}
+
+uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&Klaymen::stFallSkipJump);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter) {
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ }
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x5E0A4905);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD86E4477);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1700_sprites.h b/engines/neverhood/modules/module1700_sprites.h
new file mode 100644
index 0000000000..4117de01d9
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1705WallSymbol : public StaticSprite {
+public:
+ SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
+};
+
+class SsScene1705Tape : public StaticSprite {
+public:
+ SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _tapeIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1705 : public Klaymen {
+public:
+ KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1700_SPRITES_H */
diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp
index 2a6057f9c8..282292a516 100644
--- a/engines/neverhood/modules/module1800.cpp
+++ b/engines/neverhood/modules/module1800.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1800.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/diskplayerscene.h"
#include "neverhood/menumodule.h"
+#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1800.h"
namespace Neverhood {
@@ -38,7 +39,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);
@@ -61,7 +62,7 @@ Module1800::~Module1800() {
void Module1800::createScene(int sceneNum, int which) {
static const byte kNavigationTypes00[] = {1, 0, 2, 0};
static const byte kNavigationTypes01[] = {5};
- debug("Module1800::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1800::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -177,5 +178,5 @@ void Module1800::updateScene() {
}
}
}
-
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp
index 1a9ffa127b..a920893755 100644
--- a/engines/neverhood/modules/module1900.cpp
+++ b/engines/neverhood/modules/module1900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module1900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1900_sprites.h"
namespace Neverhood {
@@ -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
@@ -52,7 +52,7 @@ Module1900::~Module1900() {
}
void Module1900::createScene(int sceneNum, int which) {
- debug("Module1900::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module1900::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -84,11 +84,9 @@ void Module1900::updateScene() {
}
}
-// Scene1901
-
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
setRectList(0x004B34C8);
@@ -98,7 +96,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)) {
@@ -126,399 +124,10 @@ Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
}
-static const NPoint kAsScene1907SymbolGroundPositions[] = {
- {160, 310}, { 90, 340}, {210, 335},
- {210, 380}, {310, 340}, {290, 400},
- {400, 375}, {370, 435}, {475, 415}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
- {275, 125}, {244, 125}, {238, 131},
- {221, 135}, {199, 136}, {168, 149},
- {145, 152}, {123, 154}, {103, 157}
-};
-
-static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
- {275, 299}, {244, 299}, {238, 305},
- {221, 309}, {199, 310}, {168, 323},
- {145, 326}, {123, 328}, {103, 331}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
- {275, 136}, {244, 156}, {238, 183},
- {221, 207}, {199, 228}, {168, 262},
- {145, 285}, {123, 307}, {103, 331}
-};
-
-static const uint32 kAsScene1907SymbolFileHashes[] = {
- 0x006A1034, 0x006A1010, 0x006A1814,
- 0x006A1016, 0x006A0014, 0x002A1014,
- 0x00EA1014, 0x206A1014, 0x046A1414
-};
-
-bool AsScene1907Symbol::_plugInFailed = false;
-int AsScene1907Symbol::_plugInTryCount = 0;
-
-AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
- : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
-
- _plugInFailed = false;
- _plugInTryCount = 0;
-
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- _isPluggedIn = true;
- _currPositionIndex = elementIndex;
- if (!getGlobalVar(V_STAIRS_DOWN)) {
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- } else {
- _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
- }
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- _isPluggedIn = false;
- _currPositionIndex = positionIndex;
- loadSound(0, 0x74231924);
- loadSound(1, 0x36691914);
- loadSound(2, 0x5421D806);
- _parentScene->setPositionFree(_currPositionIndex, false);
- _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
- _collisionBoundsOffset.set(0, 0, 80, 80);
- Sprite::updateBounds();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
-
-}
-
-void AsScene1907Symbol::update() {
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
- if (_plugInFailed && _plugInTryCount == 0)
- _plugInFailed = false;
-}
-
-uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isPluggedIn && !_plugInFailed) {
- tryToPlugIn();
- messageResult = 1;
- } else
- messageResult = 0;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907Symbol::suTryToPlugIn() {
- _currStep++;
- _x -= _deltaX;
- _y -= _deltaY;
- if (_currStep == 16) {
- _x -= _smallDeltaX;
- _y -= _smallDeltaY;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suFallOff() {
- if (_fallOffDelay != 0) {
- _fallOffDelay--;
- } else {
- _y += _yAccel;
- _yAccel += 8;
- if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
- stFallOffHitGround();
- }
- }
-}
-
-void AsScene1907Symbol::suFallOffHitGround() {
-
- if (_x == _someX - _xBreak)
- _x -= _smallDeltaX;
- else
- _x -= _deltaX;
-
- if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y -= _someY;
- }
-
- if (_currStep < 8) {
- _y -= _yAccel;
- _yAccel -= 4;
- if (_yAccel < 0)
- _yAccel = 0;
- } else if (_currStep < 15) {
- _y += _yAccel;
- _yAccel += 4;
- } else {
- _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
- cbFallOffHitGroundEvent();
- }
-
- _currStep++;
-}
-
-void AsScene1907Symbol::suMoveDown() {
- _y += _yIncr;
- if (_yIncr < 11)
- _yIncr++;
- if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suMoveUp() {
- _y -= _yIncr;
- if (getGlobalVar(V_WALL_BROKEN)) {
- if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
- _yIncr--;
- else
- _yIncr++;
- } else
- _yIncr = 2;
- if (_yIncr > 9)
- _yIncr = 9;
- else if (_yIncr < 1)
- _yIncr = 1;
- if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::tryToPlugIn() {
- _isPluggedIn = true;
- _plugInTryCount++;
- _newPositionIndex = _parentScene->getNextPosition();
- _parentScene->setPositionFree(_currPositionIndex, true);
- sendMessage(_parentScene, 0x1022, 1100 + _newPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
- SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
- _currStep = 0;
- _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
- _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
- _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
- _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
- if (_elementIndex == _newPositionIndex) {
- NextState(&AsScene1907Symbol::stPlugIn);
- } else {
- _plugInFailed = true;
- NextState(&AsScene1907Symbol::stPlugInFail);
- }
-}
-
-void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
- _isPluggedIn = false;
- _newPositionIndex = newPositionIndex;
- _fallOffDelay = fallOffDelay;
- _parentScene->setPositionFree(_newPositionIndex, false);
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- _someX = _x;
- _someY = _y;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
- _playBackwards = true;
- _newStickFrameIndex = STICK_LAST_FRAME;
- _currStep = 0;
- _yAccel = 1;
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
-}
-
-void AsScene1907Symbol::stFallOffHitGround() {
- playSound(1);
- sendMessage(_parentScene, 0x1022, 1000 + _newPositionIndex);
- Entity::_priority = 1000 - _newPositionIndex;
- _parentScene->removeCollisionSprite(this);
- _parentScene->addCollisionSprite(this);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
- NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
- _newStickFrameIndex = 0;
- _currStep = 0;
- _yAccel = 30;
- _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
- _xBreak = _deltaX * 15;
- _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
- _someY = 0;
- if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
- _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
-}
-
-void AsScene1907Symbol::cbFallOffHitGroundEvent() {
- _currPositionIndex = _newPositionIndex;
- if (_plugInTryCount > 0)
- _plugInTryCount--;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- updateBounds();
- playSound(2);
-}
-
-void AsScene1907Symbol::stPlugIn() {
- playSound(0);
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- if (_elementIndex == 8)
- sendMessage(_parentScene, 0x2001, 0);
-}
-
-void AsScene1907Symbol::stPlugInFail() {
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- _parentScene->plugInFailed();
-}
-
-void AsScene1907Symbol::moveUp() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
- _yIncr = 1;
- _isMoving = true;
-}
-
-void AsScene1907Symbol::moveDown() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
- _yIncr = 4;
- _isMoving = true;
-}
-
-SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
- _countdown1(0) {
-
- loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene1907UpDownButton::update);
- SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- if (getGlobalVar(V_STAIRS_DOWN))
- setToDownPosition();
- else
- setToUpPosition();
- }
-}
-
-void SsScene1907UpDownButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- setVisible(true);
- _countdown1 = 4;
- updatePosition();
- playSound(0);
- }
- messageResult = 1;
- }
- return messageResult;
-}
-
-void SsScene1907UpDownButton::setToUpPosition() {
- _y = _spriteResource.getPosition().y;
- updateBounds();
- updatePosition();
-}
-
-void SsScene1907UpDownButton::setToDownPosition() {
- _y = _spriteResource.getPosition().y + 174;
- updateBounds();
- updatePosition();
-}
-
-AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface1(0x110A1061, 1500);
- _x = 320;
- _y = 240;
- startAnimation(0x110A1061, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
- SetUpdateHandler(&AsScene1907WaterHint::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1907WaterHint::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907WaterHint::show() {
- setVisible(true);
- startAnimation(0x110A1061, 0, -1);
- SetMessageHandler(&AsScene1907WaterHint::hmShowing);
- NextState(&AsScene1907WaterHint::hide);
-}
-
-void AsScene1907WaterHint::hide() {
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
+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 +138,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 +151,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 +161,7 @@ Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
void Scene1907::update() {
Scene::update();
-
+
if (_hasPlugInFailed) {
int fallOffDelay = 0;
_hasPlugInFailed = false;
@@ -619,7 +228,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/module1900.h b/engines/neverhood/modules/module1900.h
index abb5eb1d87..d785c6f506 100644
--- a/engines/neverhood/modules/module1900.h
+++ b/engines/neverhood/modules/module1900.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,80 +40,14 @@ protected:
void updateScene();
};
-// Scene1901
-
class Scene1901 : public Scene {
public:
Scene1901(NeverhoodEngine *vm, Module *parentModule, int which);
};
-// Scene1907
-
-class Scene1907;
-
-class AsScene1907Symbol : public AnimatedSprite {
-public:
- AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
- void moveUp();
- void moveDown();
- void fallOff(int newPositionIndex, int fallOffDelay);
- bool isPluggedIn() { return _isPluggedIn; }
- bool isMoving() { return _isMoving; }
-protected:
- Scene1907 *_parentScene;
- int _elementIndex;
- int _currPositionIndex;
- int _newPositionIndex;
- bool _isPluggedIn;
- bool _isMoving;
- int _someX, _someY;
- int _xBreak;
- int _currStep;
- int _yAccel;
- int _yIncr;
- int _fallOffDelay;
- int _deltaX, _smallDeltaX;
- int _deltaY, _smallDeltaY;
- // Dumb, change if possible
- static bool _plugInFailed;
- static int _plugInTryCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
- void suTryToPlugIn();
- void suFallOff();
- void suFallOffHitGround();
- void suMoveDown();
- void suMoveUp();
- void tryToPlugIn();
- void stFallOffHitGround();
- void cbFallOffHitGroundEvent();
- void stPlugIn();
- void stPlugInFail();
-};
-
-class AsScene1907WaterHint : public AnimatedSprite {
-public:
- AsScene1907WaterHint(NeverhoodEngine *vm);
- void show();
-protected:
- void update();
- uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
- void hide();
-};
-
-class SsScene1907UpDownButton : public StaticSprite {
-public:
- SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
- void setToUpPosition();
- void setToDownPosition();
-protected:
- Scene1907 *_parentScene;
- AsScene1907Symbol *_asScene1907Symbol;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1907Symbol;
+class SsScene1907UpDownButton;
+class AsScene1907WaterHint;
class Scene1907 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1900_sprites.cpp b/engines/neverhood/modules/module1900_sprites.cpp
new file mode 100644
index 0000000000..09c0b132d5
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.cpp
@@ -0,0 +1,456 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1900.h"
+#include "neverhood/modules/module1900_sprites.h"
+
+namespace Neverhood {
+
+static const NPoint kAsScene1907SymbolGroundPositions[] = {
+ {160, 310}, { 90, 340}, {210, 335},
+ {210, 380}, {310, 340}, {290, 400},
+ {400, 375}, {370, 435}, {475, 415}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
+ {275, 125}, {244, 125}, {238, 131},
+ {221, 135}, {199, 136}, {168, 149},
+ {145, 152}, {123, 154}, {103, 157}
+};
+
+static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
+ {275, 299}, {244, 299}, {238, 305},
+ {221, 309}, {199, 310}, {168, 323},
+ {145, 326}, {123, 328}, {103, 331}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
+ {275, 136}, {244, 156}, {238, 183},
+ {221, 207}, {199, 228}, {168, 262},
+ {145, 285}, {123, 307}, {103, 331}
+};
+
+static const uint32 kAsScene1907SymbolFileHashes[] = {
+ 0x006A1034, 0x006A1010, 0x006A1814,
+ 0x006A1016, 0x006A0014, 0x002A1014,
+ 0x00EA1014, 0x206A1014, 0x046A1414
+};
+
+bool AsScene1907Symbol::_plugInFailed = false;
+int AsScene1907Symbol::_plugInTryCount = 0;
+
+AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
+ : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
+
+ _plugInFailed = false;
+ _plugInTryCount = 0;
+
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ _isPluggedIn = true;
+ _currPositionIndex = elementIndex;
+ if (!getGlobalVar(V_STAIRS_DOWN)) {
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ } else {
+ _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
+ }
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ _isPluggedIn = false;
+ _currPositionIndex = positionIndex;
+ loadSound(0, 0x74231924);
+ loadSound(1, 0x36691914);
+ loadSound(2, 0x5421D806);
+ _parentScene->setPositionFree(_currPositionIndex, false);
+ _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ _collisionBoundsOffset.set(0, 0, 80, 80);
+ Sprite::updateBounds();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+
+}
+
+void AsScene1907Symbol::update() {
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+ if (_plugInFailed && _plugInTryCount == 0)
+ _plugInFailed = false;
+}
+
+uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isPluggedIn && !_plugInFailed) {
+ tryToPlugIn();
+ messageResult = 1;
+ } else
+ messageResult = 0;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907Symbol::suTryToPlugIn() {
+ _currStep++;
+ _x -= _deltaX;
+ _y -= _deltaY;
+ if (_currStep == 16) {
+ _x -= _smallDeltaX;
+ _y -= _smallDeltaY;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suFallOff() {
+ if (_fallOffDelay != 0) {
+ _fallOffDelay--;
+ } else {
+ _y += _yAccel;
+ _yAccel += 8;
+ if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
+ stFallOffHitGround();
+ }
+ }
+}
+
+void AsScene1907Symbol::suFallOffHitGround() {
+
+ if (_x == _someX - _xBreak)
+ _x -= _smallDeltaX;
+ else
+ _x -= _deltaX;
+
+ if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y -= _someY;
+ }
+
+ if (_currStep < 8) {
+ _y -= _yAccel;
+ _yAccel -= 4;
+ if (_yAccel < 0)
+ _yAccel = 0;
+ } else if (_currStep < 15) {
+ _y += _yAccel;
+ _yAccel += 4;
+ } else {
+ _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+ cbFallOffHitGroundEvent();
+ }
+
+ _currStep++;
+}
+
+void AsScene1907Symbol::suMoveDown() {
+ _y += _yIncr;
+ if (_yIncr < 11)
+ _yIncr++;
+ if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suMoveUp() {
+ _y -= _yIncr;
+ if (getGlobalVar(V_WALL_BROKEN)) {
+ if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
+ _yIncr--;
+ else
+ _yIncr++;
+ } else
+ _yIncr = 2;
+ if (_yIncr > 9)
+ _yIncr = 9;
+ else if (_yIncr < 1)
+ _yIncr = 1;
+ if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::tryToPlugIn() {
+ _isPluggedIn = true;
+ _plugInTryCount++;
+ _newPositionIndex = _parentScene->getNextPosition();
+ _parentScene->setPositionFree(_currPositionIndex, true);
+ sendMessage(_parentScene, 0x1022, 1100 + _newPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
+ SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
+ _currStep = 0;
+ _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
+ _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
+ _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
+ _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
+ if (_elementIndex == _newPositionIndex) {
+ NextState(&AsScene1907Symbol::stPlugIn);
+ } else {
+ _plugInFailed = true;
+ NextState(&AsScene1907Symbol::stPlugInFail);
+ }
+}
+
+void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
+ _isPluggedIn = false;
+ _newPositionIndex = newPositionIndex;
+ _fallOffDelay = fallOffDelay;
+ _parentScene->setPositionFree(_newPositionIndex, false);
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ _someX = _x;
+ _someY = _y;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
+ _playBackwards = true;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _currStep = 0;
+ _yAccel = 1;
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
+}
+
+void AsScene1907Symbol::stFallOffHitGround() {
+ playSound(1);
+ sendMessage(_parentScene, 0x1022, 1000 + _newPositionIndex);
+ Entity::_priority = 1000 - _newPositionIndex;
+ _parentScene->removeCollisionSprite(this);
+ _parentScene->addCollisionSprite(this);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
+ NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
+ _newStickFrameIndex = 0;
+ _currStep = 0;
+ _yAccel = 30;
+ _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
+ _xBreak = _deltaX * 15;
+ _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
+ _someY = 0;
+ if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
+ _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+}
+
+void AsScene1907Symbol::cbFallOffHitGroundEvent() {
+ _currPositionIndex = _newPositionIndex;
+ if (_plugInTryCount > 0)
+ _plugInTryCount--;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ updateBounds();
+ playSound(2);
+}
+
+void AsScene1907Symbol::stPlugIn() {
+ playSound(0);
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ if (_elementIndex == 8)
+ sendMessage(_parentScene, 0x2001, 0);
+}
+
+void AsScene1907Symbol::stPlugInFail() {
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ _parentScene->plugInFailed();
+}
+
+void AsScene1907Symbol::moveUp() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
+ _yIncr = 1;
+ _isMoving = true;
+}
+
+void AsScene1907Symbol::moveDown() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
+ _yIncr = 4;
+ _isMoving = true;
+}
+
+SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
+ _countdown1(0) {
+
+ loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene1907UpDownButton::update);
+ SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ if (getGlobalVar(V_STAIRS_DOWN))
+ setToDownPosition();
+ else
+ setToUpPosition();
+ }
+}
+
+void SsScene1907UpDownButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ setVisible(true);
+ _countdown1 = 4;
+ updatePosition();
+ playSound(0);
+ }
+ messageResult = 1;
+ }
+ return messageResult;
+}
+
+void SsScene1907UpDownButton::setToUpPosition() {
+ _y = _spriteResource.getPosition().y;
+ updateBounds();
+ updatePosition();
+}
+
+void SsScene1907UpDownButton::setToDownPosition() {
+ _y = _spriteResource.getPosition().y + 174;
+ updateBounds();
+ updatePosition();
+}
+
+AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface1(0x110A1061, 1500);
+ _x = 320;
+ _y = 240;
+ startAnimation(0x110A1061, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+ SetUpdateHandler(&AsScene1907WaterHint::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1907WaterHint::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907WaterHint::show() {
+ setVisible(true);
+ startAnimation(0x110A1061, 0, -1);
+ SetMessageHandler(&AsScene1907WaterHint::hmShowing);
+ NextState(&AsScene1907WaterHint::hide);
+}
+
+void AsScene1907WaterHint::hide() {
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1900_sprites.h b/engines/neverhood/modules/module1900_sprites.h
new file mode 100644
index 0000000000..7e57b11618
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.h
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class Scene1907;
+
+class AsScene1907Symbol : public AnimatedSprite {
+public:
+ AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
+ void moveUp();
+ void moveDown();
+ void fallOff(int newPositionIndex, int fallOffDelay);
+ bool isPluggedIn() { return _isPluggedIn; }
+ bool isMoving() { return _isMoving; }
+protected:
+ Scene1907 *_parentScene;
+ int _elementIndex;
+ int _currPositionIndex;
+ int _newPositionIndex;
+ bool _isPluggedIn;
+ bool _isMoving;
+ int _someX, _someY;
+ int _xBreak;
+ int _currStep;
+ int _yAccel;
+ int _yIncr;
+ int _fallOffDelay;
+ int _deltaX, _smallDeltaX;
+ int _deltaY, _smallDeltaY;
+ // Dumb, change if possible
+ static bool _plugInFailed;
+ static int _plugInTryCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
+ void suTryToPlugIn();
+ void suFallOff();
+ void suFallOffHitGround();
+ void suMoveDown();
+ void suMoveUp();
+ void tryToPlugIn();
+ void stFallOffHitGround();
+ void cbFallOffHitGroundEvent();
+ void stPlugIn();
+ void stPlugInFail();
+};
+
+class AsScene1907WaterHint : public AnimatedSprite {
+public:
+ AsScene1907WaterHint(NeverhoodEngine *vm);
+ void show();
+protected:
+ void update();
+ uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
+ void hide();
+};
+
+class SsScene1907UpDownButton : public StaticSprite {
+public:
+ SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
+ void setToUpPosition();
+ void setToDownPosition();
+protected:
+ Scene1907 *_parentScene;
+ AsScene1907Symbol *_asScene1907Symbol;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1901 : public Klaymen {
+public:
+ KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1900_SPRITES_H */
diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp
index 5039da1b01..3364f60f8b 100644
--- a/engines/neverhood/modules/module2000.cpp
+++ b/engines/neverhood/modules/module2000.cpp
@@ -21,14 +21,13 @@
*/
#include "neverhood/modules/module2000.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2000_sprites.h"
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)
@@ -43,7 +42,7 @@ Module2000::~Module2000() {
}
void Module2000::createScene(int sceneNum, int which) {
- debug("Module2000::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2000::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -137,9 +136,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 +152,7 @@ uint32 Scene2001::handleMessage(int messageNum, const MessageParam &param, Entit
setRectList(0x004B3670);
_klaymen->setKlaymenIdleTable1();
}
- }
+ }
return 0;
}
diff --git a/engines/neverhood/modules/module2000.h b/engines/neverhood/modules/module2000.h
index fa62f9a70e..8dc72c57dc 100644
--- a/engines/neverhood/modules/module2000.h
+++ b/engines/neverhood/modules/module2000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,8 +40,6 @@ protected:
void updateScene();
};
-// Scene2001
-
class Scene2001 : public Scene {
public:
Scene2001(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2000_sprites.cpp b/engines/neverhood/modules/module2000_sprites.cpp
new file mode 100644
index 0000000000..c9c1481aa7
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2000_sprites.h"
+
+namespace Neverhood {
+
+KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xBE68CC54);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x18AB4ED4);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2000_sprites.h b/engines/neverhood/modules/module2000_sprites.h
new file mode 100644
index 0000000000..ca84aa73ca
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class KmScene2001 : public Klaymen {
+public:
+ KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2000_SPRITES_H */
diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp
index 0d7f3dd22a..db7258b066 100644
--- a/engines/neverhood/modules/module2100.cpp
+++ b/engines/neverhood/modules/module2100.cpp
@@ -20,9 +20,9 @@
*
*/
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2100.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module2100_sprites.h"
namespace Neverhood {
@@ -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)
@@ -47,7 +47,7 @@ Module2100::~Module2100() {
}
void Module2100::createScene(int sceneNum, int which) {
- debug("Module2100::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2100::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -74,133 +74,14 @@ void Module2100::updateScene() {
}
}
-// Scene2101
-
-AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 328, 347);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101Door::handleMessage);
- if (isOpen) {
- startAnimation(0x0C202B9C, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
-}
-
-uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2101Door::stOpenDoor() {
- startAnimation(0x0C202B9C, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen32"));
-}
-
-void AsScene2101Door::stCloseDoor() {
- startAnimation(0xC222A8D4, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose32"));
- NextState(&AsScene2101Door::stCloseDoorDone);
-}
-
-void AsScene2101Door::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
- createSurface(1200, 88, 165);
- setVisible(false);
-}
-
-uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- _x = _klaymen->getX();
- _y = _klaymen->getY() - 132;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
- _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
-
- SetUpdateHandler(&SsCommonFloorButton::update);
- SetMessageHandler(&SsCommonFloorButton::handleMessage);
- if (_soundFileHash == 0)
- _soundFileHash = 0x44141000;
- createSurface(1010, 61, 30);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
-}
-
-void SsCommonFloorButton::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x1022, 1010);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
- }
-}
-
-uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- sendMessage(_parentScene, 0x1022, 990);
- loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 16;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
-
+
SetMessageHandler(&Scene2101::handleMessage);
SetUpdateHandler(&Scene2101::update);
-
+
setBackground(0x44242305);
setPalette(0x44242305);
insertScreenMouse(0x4230144A);
@@ -210,9 +91,9 @@ Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x72427010, 0x32423010, 200, 0);
_asTape1 = insertSprite<AsScene1201Tape>(this, 18, 1100, 412, 443, 0x9148A011);
addCollisionSprite(_asTape1);
- _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9148A011);
+ _asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093);
addCollisionSprite(_asTape2);
-
+
if (which < 0) {
insertKlaymen<KmScene2101>(380, 438);
setMessageList(0x004B8E48);
@@ -256,10 +137,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..c5256434d9 100644
--- a/engines/neverhood/modules/module2100.h
+++ b/engines/neverhood/modules/module2100.h
@@ -40,38 +40,6 @@ protected:
void updateScene();
};
-// Scene1901
-
-class AsScene2101Door : public AnimatedSprite {
-public:
- AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene2101HitByDoorEffect : public AnimatedSprite {
-public:
- AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonFloorButton : public StaticSprite {
-public:
- SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHash1, _fileHash2;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2101 : public Scene {
public:
Scene2101(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2100_sprites.cpp b/engines/neverhood/modules/module2100_sprites.cpp
new file mode 100644
index 0000000000..707ebe342f
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.cpp
@@ -0,0 +1,260 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2100_sprites.h"
+
+namespace Neverhood {
+
+AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 328, 347);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101Door::handleMessage);
+ if (isOpen) {
+ startAnimation(0x0C202B9C, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+}
+
+uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stOpenDoor();
+ break;
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2101Door::stOpenDoor() {
+ startAnimation(0x0C202B9C, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen32"));
+}
+
+void AsScene2101Door::stCloseDoor() {
+ startAnimation(0xC222A8D4, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose32"));
+ NextState(&AsScene2101Door::stCloseDoorDone);
+}
+
+void AsScene2101Door::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
+ createSurface(1200, 88, 165);
+ setVisible(false);
+}
+
+uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ _x = _klaymen->getX();
+ _y = _klaymen->getY() - 132;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
+ _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
+
+ SetUpdateHandler(&SsCommonFloorButton::update);
+ SetMessageHandler(&SsCommonFloorButton::handleMessage);
+ if (_soundFileHash == 0)
+ _soundFileHash = 0x44141000;
+ createSurface(1010, 61, 30);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+}
+
+void SsCommonFloorButton::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, 0x1022, 1010);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+ }
+}
+
+uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ sendMessage(_parentScene, 0x1022, 990);
+ loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 16;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4811:
+ GotoState(&KmScene2101::stHitByDoor);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xFF290E30);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x9A28CA1C);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2101::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ int16 speedUpFrameIndex;
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 438;
+ }
+ messageResult = 0;
+ break;
+ case 0x100D:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2101::stHitByDoor() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2101::hmHitByDoor);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ playSound(0, 0x402E82D4);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2100_sprites.h b/engines/neverhood/modules/module2100_sprites.h
new file mode 100644
index 0000000000..85a6b9f27d
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene2101Door : public AnimatedSprite {
+public:
+ AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene2101HitByDoorEffect : public AnimatedSprite {
+public:
+ AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonFloorButton : public StaticSprite {
+public:
+ SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHash1, _fileHash2;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2101 : public Klaymen {
+public:
+ KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+
+ void stHitByDoor();
+ uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
+
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2100_SPRITES_H */
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index b8da0f64ff..eecddf904c 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -20,20 +20,21 @@
*
*/
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/gamemodule.h"
+#include "common/config-manager.h"
+
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
Module2200::Module2200(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
- debug("Create Module2200(%d)", which);
- _vm->_soundMan->addMusic(0x11391412, 0x601C908C);
+ _vm->_soundMan->addMusic(0x11391412, 0x601C908C);
if (which < 0)
createScene(_vm->gameState().sceneNum, -1);
@@ -47,11 +48,24 @@ Module2200::~Module2200() {
}
void Module2200::createScene(int sceneNum, int which) {
- debug("Module2200::createScene(%d, %d)", sceneNum, which);
+ if (sceneNum == 46 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport to the last scene
+ sceneNum = 41;
+ }
+
+ if (sceneNum == 40 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport back to the first scene
+ sceneNum = 5;
+ }
+
+ debug(1, "Module2200::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
_vm->gameState().sceneNum = 0;
+ _vm->_soundMan->startMusic(0x601C908C, 0, 2);
_childObject = new Scene2201(_vm, this, which);
break;
case 1:
@@ -441,100 +455,11 @@ void Module2200::updateScene() {
}
#undef HallOfRecordsSceneLink
-
+
void Module2200::createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId) {
_childObject = new HallOfRecordsScene(_vm, this, which, hallOfRecordsInfoId);
}
-// Scene2201
-
-AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 403;
- _y = 259;
- createSurface(100, 233, 96);
- startAnimation(0x8600866, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
-
- _x = 408;
- _y = 290;
- createSurface(900, 63, 266);
- SetUpdateHandler(&AsScene2201Door::update);
- SetMessageHandler(&AsScene2201Door::handleMessage);
- if (_isOpen) {
- startAnimation(0xE2CB0412, -1, -1);
- _countdown = 48;
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = 0;
- _ssDoorLight->setVisible(false);
- }
-}
-
-void AsScene2201Door::update() {
- if (_countdown != 0 && _isOpen && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x11001090) {
- if (_isOpen)
- _ssDoorLight->setVisible(true);
- } else if (param.asInteger() == 0x11283090) {
- if (!_isOpen)
- _ssDoorLight->setVisible(false);
- }
- break;
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2201Door::stOpenDoor() {
- _isOpen = true;
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen33"));
-}
-
-void AsScene2201Door::stCloseDoor() {
- _isOpen = false;
- startAnimation(0xE2CB0412, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0, calcHash("fxDoorClose33"));
-}
-
-SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
- : StaticSprite(vm, 900) {
-
- createSurface(100, 16, 16);
- loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
- kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
-}
-
Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSoundPlaying(false) {
@@ -544,7 +469,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene2201::handleMessage);
SetUpdateHandler(&Scene2201::update);
-
+
loadDataResource(0x04104242);
loadHitRectList();
setBackground(0x40008208);
@@ -552,9 +477,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));
@@ -563,10 +488,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);
@@ -603,7 +528,7 @@ Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
setMessageList(0x004B8120);
_asDoor = insertSprite<AsScene2201Door>(_klaymen, _ssDoorLight, true);
}
-
+
insertSprite<AsScene2201CeilingFan>();
_vm->_soundMan->addSound(0x04106220, 0x81212040);
@@ -662,214 +587,6 @@ uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-static const NPoint kSsScene2202PuzzleCubePoints[] = {
- {196, 105}, {323, 102}, {445, 106},
- {192, 216}, {319, 220}, {446, 216},
- {188, 320}, {319, 319}, {443, 322}
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
- 0xA500800C, 0x2182910C, 0x2323980C,
- 0x23049084, 0x21008080, 0x2303900C,
- 0x6120980C, 0x2504D808
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
- 0x0AAD8080, 0x0A290291, 0x0A2BA398,
- 0x822B8490, 0x86298080, 0x0A2B8390,
- 0x0A69A098, 0x0E2D84D8
-};
-
-SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
- : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
-
- int surfacePriority;
-
- SetUpdateHandler(&SsScene2202PuzzleCube::update);
- SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
- if (_cubePosition >= 0 && _cubePosition <= 2)
- surfacePriority = 100;
- else if (_cubePosition >= 3 && _cubePosition <= 5)
- surfacePriority = 300;
- else
- surfacePriority = 500;
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
- kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
- loadSound(0, 0x40958621);
- loadSound(1, 0x51108241);
-}
-
-void SsScene2202PuzzleCube::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
- sendMessage(_parentScene, 0x2000, _cubePosition);
- messageResult = 1;
- break;
- case 0x2001:
- _isMoving = true;
- moveCube(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void SsScene2202PuzzleCube::suMoveCubeX() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _x += _xIncr;
- _errValue += _yDelta;
- if (_errValue >= _xDelta) {
- _errValue -= _xDelta;
- _y += _yIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::suMoveCubeY() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _y += _yIncr;
- _errValue += _xDelta;
- if (_errValue >= _yDelta) {
- _errValue -= _yDelta;
- _x += _xIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
-
- loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
-
- setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
- setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
-
- _cubePosition = newCubePosition;
- _errValue = 0;
- _counterDirection = false;
- _counter = 0;
- _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
- _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
-
- if (_x == _newX && _y == _newY)
- return;
-
- if (_x <= _newX) {
- if (_y <= _newY) {
- _xDelta = _newX - _x;
- _yDelta = _newY - _y;
- _xIncr = 1;
- _yIncr = 1;
- } else {
- _xDelta = _newX - _x;
- _yDelta = _y - _newY;
- _xIncr = 1;
- _yIncr = -1;
- }
- } else {
- if (_y <= _newY) {
- _xDelta = _x - _newX;
- _yDelta = _newY - _y;
- _xIncr = -1;
- _yIncr = 1;
- } else {
- _xDelta = _x - _newX;
- _yDelta = _y - _newY;
- _xIncr = -1;
- _yIncr = -1;
- }
- }
-
- if (_xDelta > _yDelta) {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
- if (_xIncr > 0) {
- if (_newX - _x >= 180)
- _xFlagPos = _newX - 90;
- else
- _xFlagPos = _x + _newX / 2;
- } else {
- if (_x - _newX >= 180)
- _xFlagPos = _x + 90;
- else
- _xFlagPos = _x / 2 + _newX;
- }
- playSound(0);
- } else {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
- if (_yIncr > 0) {
- if (_newY - _y >= 180)
- _xFlagPos = _newY - 90;
- else
- _xFlagPos = _y + _newY / 2;
- } else {
- if (_y - _newY >= 180)
- _xFlagPos = _y + 90;
- else
- _xFlagPos = _y / 2 + _newY;
- }
- playSound(1);
- }
-
-}
-
-void SsScene2202PuzzleCube::stopMoving() {
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
- SetSpriteUpdate(NULL);
- _isMoving = false;
- sendMessage(_parentScene, 0x2002, _cubePosition);
-}
-
Scene2202::Scene2202(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSolved(false), _leaveScene(false), _isCubeMoving(false),
_ssMovingCube(NULL), _ssDoneMovingCube(NULL) {
@@ -939,7 +656,7 @@ void Scene2202::update() {
_isSolved = true;
}
}
-
+
}
uint32 Scene2202::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
@@ -981,7 +698,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 &&
@@ -991,100 +708,6 @@ bool Scene2202::testIsSolved() {
getSubVar(VA_CUBE_POSITIONS, 8) == 7;
}
-static const uint32 kAsCommonKeyFileHashes[] = {
- 0x2450D850, 0x0C9CE8D0, 0x2C58A152
-};
-
-AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
-
- if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
- SetMessageHandler(&AsCommonKey::handleMessage);
- } else {
- // If Klaymen already has the key or it's already inserted then don't show it
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_KEY, _keyIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- }
- return messageResult;
-}
-
-static const uint32 kAsScene2203DoorFileHashes[] = {
- 0x7868AE10, 0x1A488110
-};
-
-AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2203Door::handleMessage);
- _x = 320;
- _y = 240;
- createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
- if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x2002, 0);
- else
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x2000:
- _otherDoor = (Sprite*)param.asEntity();
- break;
- case 0x3002:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x4808, 0);
- stopAnimation();
- break;
- case 0x4808:
- setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
- sendMessage(_otherDoor, 0x4809, 0);
- openDoor();
- break;
- case 0x4809:
- closeDoor();
- sendMessage(_parentScene, 0x2003, 0);
- break;
- }
- return messageResult;
-}
-
-void AsScene2203Door::openDoor() {
- playSound(0, 0x341014C4);
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
-}
-
-void AsScene2203Door::closeDoor() {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1146,7 +769,7 @@ Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
_ssSmallRightDoor->setVisible(false);
_klaymen->setClipRect(_leftDoorClipRect);
}
-
+
}
Scene2203::~Scene2203() {
@@ -1197,30 +820,12 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
- createSurface(1100, 45, 206);
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
- break;
- }
- return messageResult;
-}
-
Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
SetMessageHandler(&Scene2205::handleMessage);
SetUpdateHandler(&Scene2205::update);
-
+
setHitRects(0x004B0620);
if (getGlobalVar(V_LIGHTS_ON)) {
_isLightOn = true;
@@ -1263,11 +868,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)) {
@@ -1325,142 +930,14 @@ static const int16 kScene2206XPositions[] = {
384, 480, 572
};
-static const uint32 kScene2206MessageIds1[] = {
- 0x004B8998, 0x004B89B8, 0x004B89D8
-};
-
-static const uint32 kScene2206MessageIds2[] = {
- 0x004B89F8, 0x004B8A20, 0x004B8A48
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
- -24, -28, -18, 6, 9, -8
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
- -8, 7, 11, 26, 13, 14
-};
-
-AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 200) {
-
- if (getGlobalVar(V_SPIKES_RETRACTED))
- _x -= 63;
- SetUpdateHandler(&AsScene2206DoorSpikes::update);
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206DoorSpikes::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- _deltaIndex = 0;
- playSound(0, 0x032746E0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
- break;
- case 0x4809:
- _deltaIndex = 0;
- playSound(0, 0x002642C0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206DoorSpikes::suOpen() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene2206DoorSpikes::suClose() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 50) {
-
- SetUpdateHandler(&AsScene2206Platform::update);
- SetMessageHandler(&AsScene2206Platform::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206Platform::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4803:
- _yDelta = 0;
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206Platform::suMoveDown() {
- _yDelta++;
- _y += _yDelta;
-}
-
-SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
-
- if (getGlobalVar(V_HAS_TEST_TUBE)) {
- setVisible(false);
- SetMessageHandler(NULL);
- } else
- SetMessageHandler(&SsScene2206TestTube::handleMessage);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
-}
-
-uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_TEST_TUBE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
uint32 fileHash;
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene2206::handleMessage);
-
+
if (getGlobalVar(V_LIGHTS_ON)) {
fileHash = 0x41983216;
_sprite1 = insertStaticSprite(0x2201266A, 100);
@@ -1495,7 +972,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);
@@ -1586,7 +1063,7 @@ void Scene2206::klaymenInFrontSpikes() {
}
void Scene2206::klaymenBehindSpikes() {
- if (!getGlobalVar(V_LIGHTS_ON)) {
+ if (getGlobalVar(V_LIGHTS_ON)) {
_palette->addBasePalette(0xB103B604, 0, 65, 0);
_palette->startFadeToPalette(12);
}
@@ -1597,6 +1074,14 @@ void Scene2206::klaymenBehindSpikes() {
_klaymen->setClipRect(_sprite2->getDrawRect().x, 0, _sprite3->getDrawRect().x2(), _sprite1->getDrawRect().y2());
}
+static const uint32 kScene2206MessageIds1[] = {
+ 0x004B8998, 0x004B89B8, 0x004B89D8
+};
+
+static const uint32 kScene2206MessageIds2[] = {
+ 0x004B89F8, 0x004B8A20, 0x004B8A48
+};
+
void Scene2206::readClickedColumn() {
setGlobalVar(V_CLICKED_COLUMN_INDEX, (_mouseClickPos.x - 354) / 96);
if (getGlobalVar(V_CLICKED_COLUMN_INDEX) > 2)
@@ -1617,317 +1102,6 @@ static const uint32 kScene2207FileHashes[] = {
0x3BB1E12E, 0x23B1E12E, 0x13B1E12E
};
-AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
-
- NPoint pt;
-
- _dataResource.load(0x00524846);
- _pointArray = _dataResource.getPointArray(0x005B02B7);
- pt = _dataResource.getPoint(0x403A82B1);
- _x = pt.x;
- _y = pt.y;
- createSurface(1100, 129, 103);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2207Elevator::update);
- SetMessageHandler(&AsScene2207Elevator::handleMessage);
- SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
-}
-
-AsScene2207Elevator::~AsScene2207Elevator() {
- _vm->_soundMan->deleteSoundGroup(0x02700413);
-}
-
-void AsScene2207Elevator::update() {
-
- if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
- _pointIndex++;
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
- _pointIndex--;
- if (_pointIndex == 0)
- sendMessage(_parentScene, 0x2003, 0);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_pointIndex > 20 && _surface->getPriority() != 900)
- sendMessage(_parentScene, 0x2002, 900);
- else if (_pointIndex < 20 && _surface->getPriority() != 1100)
- sendMessage(_parentScene, 0x2002, 1100);
-
- AnimatedSprite::update();
-
- if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
- sendMessage(_parentScene, 0x2004, 0);
- _isMoving = false;
- }
-
-}
-
-void AsScene2207Elevator::suSetPosition() {
- _x = (*_pointArray)[_pointIndex].x;
- _y = (*_pointArray)[_pointIndex].y - 60;
- updateBounds();
-}
-
-uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- moveToY(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Elevator::moveToY(int16 y) {
- int16 minDistance = 480;
-
- if (!_pointArray || _pointArray->size() == 0)
- return;
-
- for (uint i = 0; i < _pointArray->size(); i++) {
- int16 distance = ABS(y - (*_pointArray)[i].y);
- if (distance < minDistance) {
- minDistance = distance;
- _destPointIndex = i;
- }
- }
-
- if (_destPointIndex != _pointIndex) {
- if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
- _destPointIndexDelta = 0;
- else if (_destPointIndex < _pointIndex)
- _destPointIndexDelta = -2;
- else
- _destPointIndexDelta = 2;
- _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-
- _isMoving = true;
-
-}
-
-AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = x;
- _y = y;
- createSurface(1010, 71, 73);
- setDoDeltaX(doDeltaX);
- startAnimation(0x80880090, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207Lever::handleMessage);
-}
-
-uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- gotoNextState();
- stopAnimation();
- break;
- case 0x4807:
- stLeverUp();
- break;
- case 0x480F:
- stLeverDown();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Lever::stLeverDown() {
- startAnimation(0x80880090, 1, -1);
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverDownEvent);
-}
-
-void AsScene2207Lever::stLeverDownEvent() {
- sendMessage(_parentScene, 0x480F, 0);
-}
-
-void AsScene2207Lever::stLeverUp() {
- startAnimation(0x80880090, 6, -1);
- _playBackwards = true;
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverUpEvent);
-}
-
-void AsScene2207Lever::stLeverUpEvent() {
- sendMessage(_parentScene, 0x4807, 0);
-}
-
-AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0xCCFD6090, 100);
- startAnimation(0xCCFD6090, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(1, 0x40330872);
- loadSound(2, 0x72A2914A);
- loadSound(3, 0xD4226080);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
-}
-
-AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
- _vm->_soundMan->deleteSoundGroup(0x80D00820);
-}
-
-uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (!_idle) {
- if (param.asInteger() == 0x3423093) {
- _vm->_soundMan->addSound(0x80D00820, 0x12121943);
- _vm->_soundMan->playSoundLooping(0x12121943);
- } else if (param.asInteger() == 0x834AB011) {
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- } else if (param.asInteger() == 0x3A980501)
- playSound(1);
- else if (param.asInteger() == 0x2A2AD498)
- playSound(2);
- else if (param.asInteger() == 0xC4980008)
- playSound(3);
- else if (param.asInteger() == 0x06B84228)
- playSound(0, 0xE0702146);
- }
- break;
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallRobotAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- startAnimation(0xCCFD6090, 0, -1);
- _idle = false;
- setVisible(true);
- }
-}
-
-void AsScene2207WallRobotAnimation::stStopAnimation() {
- NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallRobotAnimation::cbStopAnimation() {
- stopAnimation();
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- _idle = true;
- setVisible(false);
-}
-
-AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0x8CAA0099, 100);
- startAnimation(0x8CAA0099, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
-}
-
-uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallCannonAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- setVisible(true);
- startAnimation(0x8CAA0099, 0, -1);
- _idle = false;
- }
-}
-
-void AsScene2207WallCannonAnimation::stStopAnimation() {
- NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallCannonAnimation::cbStopAnimation() {
- stopAnimation();
- setVisible(false);
- _idle = true;
-}
-
-SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = 330;
- _y = 246 + index * 50;
- updatePosition();
-}
-
Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _klaymenAtElevator(true), _elevatorSurfacePriority(0) {
@@ -1943,7 +1117,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 +1126,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 +1280,7 @@ static const uint32 kScene2208FileHashes1[] = {
0x041023CB, 0x041020CB, 0x041026CB, 0x04102ACB,
0x041032CB, 0x041002CB
};
-
+
static const uint32 kScene2208FileHashes2[] = {
0x091206C9, 0x091406C9, 0x091806C9, 0x090006C9,
0x093006C9, 0x095006C9
@@ -2122,13 +1296,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);
@@ -2141,20 +1315,20 @@ Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which)
_fontSurface = FontSurface::createFontSurface(_vm, 0x0800090C);
- _backgroundSurface = new BaseSurface(_vm, 0, 640, 480);
+ _backgroundSurface = new BaseSurface(_vm, 0, 640, 480, "background");
spriteResource.load(0x08100289, true);
_backgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
- _topBackgroundSurface = new BaseSurface(_vm, 0, 640, 192);
+ _topBackgroundSurface = new BaseSurface(_vm, 0, 640, 192, "top background");
spriteResource.load(!getGlobalVar(V_COLUMN_BACK_NAME)
? kScene2208FileHashes1[getGlobalVar(V_CLICKED_COLUMN_INDEX) % 6]
: getGlobalVar(V_COLUMN_BACK_NAME), true);
_topBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
- _bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192);
+ _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 +1339,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 +1359,7 @@ Scene2208::~Scene2208() {
void Scene2208::update() {
int16 mouseY = _vm->getMouseY();
-
+
if (mouseY < 48) {
if (_currRowIndex > 0)
_newRowIndex = _currRowIndex - 1;
@@ -2235,7 +1409,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 +1454,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 +1471,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 +1554,7 @@ void Scene2242::readClickedColumn() {
}
static const int16 kHallOfRecordsKlaymenXPos[] = {
- 68, 157, 246, 335,
+ 68, 157, 246, 335,
424, 513, 602
};
@@ -2396,7 +1570,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 +1661,7 @@ static const uint32 kScene2247MessageListIds1[] = {
Scene2247::Scene2247(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene2247::handleMessage);
SetUpdateHandler(&Scene::update);
@@ -2524,7 +1698,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..6b414304ae 100644
--- a/engines/neverhood/modules/module2200.h
+++ b/engines/neverhood/modules/module2200.h
@@ -31,8 +31,6 @@
namespace Neverhood {
-// Module2200
-
class Module2200 : public Module {
public:
Module2200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -44,43 +42,6 @@ protected:
void createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId);
};
-// Scene2201
-
-static const NPoint kSsScene2201PuzzleCubePoints[] = {
- {305, 305}, {321, 305}, {336, 305}, {305, 319},
- {321, 319}, {336, 319}, {305, 332}, {321, 332},
- {336, 333}
-};
-
-static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
- 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
- 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
-};
-
-class AsScene2201CeilingFan : public AnimatedSprite {
-public:
- AsScene2201CeilingFan(NeverhoodEngine *vm);
-};
-
-class AsScene2201Door : public AnimatedSprite {
-public:
- AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
-protected:
- Klaymen *_klaymen;
- Sprite *_ssDoorLight;
- bool _isOpen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
-};
-
-class SsScene2201PuzzleCube : public StaticSprite {
-public:
- SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
-};
-
class Scene2201 : public Scene {
public:
Scene2201(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -96,30 +57,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2202PuzzleCube : public StaticSprite {
-public:
- SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
-protected:
- Scene *_parentScene;
- int16 _cubeSymbol;
- int16 _cubePosition;
- int16 _newX, _newY;
- int16 _xDelta, _yDelta;
- int16 _xIncr;
- int16 _yIncr;
- int16 _errValue;
- int16 _counter;
- int16 _xFlagPos;
- bool _counterDirection;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveCubeX();
- void suMoveCubeY();
- void moveCube(int16 newCubePosition);
- void stopMoving();
-};
-
class Scene2202 : public Scene {
public:
Scene2202(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -135,28 +72,7 @@ protected:
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
int16 getFreeCubePosition(int16 index);
- bool testIsSolved();
-};
-
-class AsCommonKey : public AnimatedSprite {
-public:
- AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- int _keyIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2203Door : public AnimatedSprite {
-public:
- AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
-protected:
- Scene *_parentScene;
- Sprite *_otherDoor;
- uint _doorIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void openDoor();
- void closeDoor();
+ bool testIsSolved();
};
class Scene2203 : public Scene {
@@ -175,12 +91,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2205DoorFrame : public StaticSprite {
-public:
- SsScene2205DoorFrame(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsCommonPressButton;
class Scene2205 : public Scene {
public:
@@ -194,35 +105,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2206DoorSpikes : public StaticSprite {
-public:
- AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int _deltaIndex;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpen();
- void suClose();
-};
-
-class AsScene2206Platform : public StaticSprite {
-public:
- AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int16 _yDelta;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
-};
-
-class SsScene2206TestTube : public StaticSprite {
-public:
- SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2206 : public Scene {
public:
Scene2206(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -241,62 +123,6 @@ protected:
void readClickedColumn();
};
-class AsScene2207Elevator : public AnimatedSprite {
-public:
- AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207Elevator();
-protected:
- Scene *_parentScene;
- NPointArray *_pointArray;
- int16 _pointIndex;
- int16 _destPointIndex, _destPointIndexDelta;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSetPosition();
- void moveToY(int16 y);
-};
-
-class AsScene2207Lever : public AnimatedSprite {
-public:
- AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLeverDown();
- void stLeverDownEvent();
- void stLeverUp();
- void stLeverUpEvent();
-};
-
-class AsScene2207WallRobotAnimation : public AnimatedSprite {
-public:
- AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207WallRobotAnimation();
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class AsScene2207WallCannonAnimation : public AnimatedSprite {
-public:
- AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class SsScene2207Symbol : public StaticSprite {
-public:
- SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
class Scene2207 : public Scene {
public:
Scene2207(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module2200_sprites.cpp b/engines/neverhood/modules/module2200_sprites.cpp
new file mode 100644
index 0000000000..30f0404cf1
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.cpp
@@ -0,0 +1,1429 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2200_sprites.h"
+
+namespace Neverhood {
+
+AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 403;
+ _y = 259;
+ createSurface(100, 233, 96);
+ startAnimation(0x8600866, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
+
+ _x = 408;
+ _y = 290;
+ createSurface(900, 63, 266);
+ SetUpdateHandler(&AsScene2201Door::update);
+ SetMessageHandler(&AsScene2201Door::handleMessage);
+ if (_isOpen) {
+ startAnimation(0xE2CB0412, -1, -1);
+ _countdown = 48;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = 0;
+ _ssDoorLight->setVisible(false);
+ }
+}
+
+void AsScene2201Door::update() {
+ if (_countdown != 0 && _isOpen && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x11001090) {
+ if (_isOpen)
+ _ssDoorLight->setVisible(true);
+ } else if (param.asInteger() == 0x11283090) {
+ if (!_isOpen)
+ _ssDoorLight->setVisible(false);
+ }
+ break;
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2201Door::stOpenDoor() {
+ _isOpen = true;
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen33"));
+}
+
+void AsScene2201Door::stCloseDoor() {
+ _isOpen = false;
+ startAnimation(0xE2CB0412, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0, calcHash("fxDoorClose33"));
+}
+
+SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
+ : StaticSprite(vm, 900) {
+
+ createSurface(100, 16, 16);
+ loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
+ kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
+}
+
+static const NPoint kSsScene2202PuzzleCubePoints[] = {
+ {196, 105}, {323, 102}, {445, 106},
+ {192, 216}, {319, 220}, {446, 216},
+ {188, 320}, {319, 319}, {443, 322}
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
+ 0xA500800C, 0x2182910C, 0x2323980C,
+ 0x23049084, 0x21008080, 0x2303900C,
+ 0x6120980C, 0x2504D808
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
+ 0x0AAD8080, 0x0A290291, 0x0A2BA398,
+ 0x822B8490, 0x86298080, 0x0A2B8390,
+ 0x0A69A098, 0x0E2D84D8
+};
+
+SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
+
+ int surfacePriority;
+
+ SetUpdateHandler(&SsScene2202PuzzleCube::update);
+ SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
+ if (_cubePosition >= 0 && _cubePosition <= 2)
+ surfacePriority = 100;
+ else if (_cubePosition >= 3 && _cubePosition <= 5)
+ surfacePriority = 300;
+ else
+ surfacePriority = 500;
+ debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
+ kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
+ loadSound(0, 0x40958621);
+ loadSound(1, 0x51108241);
+}
+
+void SsScene2202PuzzleCube::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
+ sendMessage(_parentScene, 0x2000, _cubePosition);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _isMoving = true;
+ moveCube(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2202PuzzleCube::suMoveCubeX() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _x += _xIncr;
+ _errValue += _yDelta;
+ if (_errValue >= _xDelta) {
+ _errValue -= _xDelta;
+ _y += _yIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::suMoveCubeY() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _y += _yIncr;
+ _errValue += _xDelta;
+ if (_errValue >= _yDelta) {
+ _errValue -= _yDelta;
+ _x += _xIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
+
+ loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
+
+ setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
+ setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
+
+ _cubePosition = newCubePosition;
+ _errValue = 0;
+ _counterDirection = false;
+ _counter = 0;
+ _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
+ _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
+
+ if (_x == _newX && _y == _newY)
+ return;
+
+ if (_x <= _newX) {
+ if (_y <= _newY) {
+ _xDelta = _newX - _x;
+ _yDelta = _newY - _y;
+ _xIncr = 1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _newX - _x;
+ _yDelta = _y - _newY;
+ _xIncr = 1;
+ _yIncr = -1;
+ }
+ } else {
+ if (_y <= _newY) {
+ _xDelta = _x - _newX;
+ _yDelta = _newY - _y;
+ _xIncr = -1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _x - _newX;
+ _yDelta = _y - _newY;
+ _xIncr = -1;
+ _yIncr = -1;
+ }
+ }
+
+ if (_xDelta > _yDelta) {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
+ if (_xIncr > 0) {
+ if (_newX - _x >= 180)
+ _xFlagPos = _newX - 90;
+ else
+ _xFlagPos = _x + _newX / 2;
+ } else {
+ if (_x - _newX >= 180)
+ _xFlagPos = _x + 90;
+ else
+ _xFlagPos = _x / 2 + _newX;
+ }
+ playSound(0);
+ } else {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
+ if (_yIncr > 0) {
+ if (_newY - _y >= 180)
+ _xFlagPos = _newY - 90;
+ else
+ _xFlagPos = _y + _newY / 2;
+ } else {
+ if (_y - _newY >= 180)
+ _xFlagPos = _y + 90;
+ else
+ _xFlagPos = _y / 2 + _newY;
+ }
+ playSound(1);
+ }
+
+}
+
+void SsScene2202PuzzleCube::stopMoving() {
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
+ SetSpriteUpdate(NULL);
+ _isMoving = false;
+ sendMessage(_parentScene, 0x2002, _cubePosition);
+}
+
+static const uint32 kAsCommonKeyFileHashes[] = {
+ 0x2450D850, 0x0C9CE8D0, 0x2C58A152
+};
+
+AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
+
+ if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
+ SetMessageHandler(&AsCommonKey::handleMessage);
+ } else {
+ // If Klaymen already has the key or it's already inserted then don't show it
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_KEY, _keyIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ return messageResult;
+}
+
+static const uint32 kAsScene2203DoorFileHashes[] = {
+ 0x7868AE10, 0x1A488110
+};
+
+AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2203Door::handleMessage);
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
+ if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x2002, 0);
+ else
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case 0x3002:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x4808, 0);
+ stopAnimation();
+ break;
+ case 0x4808:
+ setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
+ sendMessage(_otherDoor, 0x4809, 0);
+ openDoor();
+ break;
+ case 0x4809:
+ closeDoor();
+ sendMessage(_parentScene, 0x2003, 0);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2203Door::openDoor() {
+ playSound(0, 0x341014C4);
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
+}
+
+void AsScene2203Door::closeDoor() {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
+ createSurface(1100, 45, 206);
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+ break;
+ }
+ return messageResult;
+}
+
+static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
+ -24, -28, -18, 6, 9, -8
+};
+
+static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
+ -8, 7, 11, 26, 13, 14
+};
+
+AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 200) {
+
+ if (getGlobalVar(V_SPIKES_RETRACTED))
+ _x -= 63;
+ SetUpdateHandler(&AsScene2206DoorSpikes::update);
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206DoorSpikes::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ _deltaIndex = 0;
+ playSound(0, 0x032746E0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
+ break;
+ case 0x4809:
+ _deltaIndex = 0;
+ playSound(0, 0x002642C0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206DoorSpikes::suOpen() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene2206DoorSpikes::suClose() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 50) {
+
+ SetUpdateHandler(&AsScene2206Platform::update);
+ SetMessageHandler(&AsScene2206Platform::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206Platform::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4803:
+ _yDelta = 0;
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206Platform::suMoveDown() {
+ _yDelta++;
+ _y += _yDelta;
+}
+
+SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
+
+ if (getGlobalVar(V_HAS_TEST_TUBE)) {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ } else
+ SetMessageHandler(&SsScene2206TestTube::handleMessage);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+}
+
+uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setGlobalVar(V_HAS_TEST_TUBE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
+
+ NPoint pt;
+
+ _dataResource.load(0x00524846);
+ _pointArray = _dataResource.getPointArray(0x005B02B7);
+ pt = _dataResource.getPoint(0x403A82B1);
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(1100, 129, 103);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2207Elevator::update);
+ SetMessageHandler(&AsScene2207Elevator::handleMessage);
+ SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
+}
+
+AsScene2207Elevator::~AsScene2207Elevator() {
+ _vm->_soundMan->deleteSoundGroup(0x02700413);
+}
+
+void AsScene2207Elevator::update() {
+
+ if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
+ _pointIndex++;
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
+ _pointIndex--;
+ if (_pointIndex == 0)
+ sendMessage(_parentScene, 0x2003, 0);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_pointIndex > 20 && _surface->getPriority() != 900)
+ sendMessage(_parentScene, 0x2002, 900);
+ else if (_pointIndex < 20 && _surface->getPriority() != 1100)
+ sendMessage(_parentScene, 0x2002, 1100);
+
+ AnimatedSprite::update();
+
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
+ sendMessage(_parentScene, 0x2004, 0);
+ _isMoving = false;
+ }
+
+}
+
+void AsScene2207Elevator::suSetPosition() {
+ _x = (*_pointArray)[_pointIndex].x;
+ _y = (*_pointArray)[_pointIndex].y - 60;
+ updateBounds();
+}
+
+uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ moveToY(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Elevator::moveToY(int16 y) {
+ int16 minDistance = 480;
+
+ if (!_pointArray || _pointArray->size() == 0)
+ return;
+
+ for (uint i = 0; i < _pointArray->size(); i++) {
+ int16 distance = ABS(y - (*_pointArray)[i].y);
+ if (distance < minDistance) {
+ minDistance = distance;
+ _destPointIndex = i;
+ }
+ }
+
+ if (_destPointIndex != _pointIndex) {
+ if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
+ _destPointIndexDelta = 0;
+ else if (_destPointIndex < _pointIndex)
+ _destPointIndexDelta = -2;
+ else
+ _destPointIndexDelta = 2;
+ _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+
+ _isMoving = true;
+
+}
+
+AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = x;
+ _y = y;
+ createSurface(1010, 71, 73);
+ setDoDeltaX(doDeltaX);
+ startAnimation(0x80880090, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207Lever::handleMessage);
+}
+
+uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x3002:
+ gotoNextState();
+ stopAnimation();
+ break;
+ case 0x4807:
+ stLeverUp();
+ break;
+ case 0x480F:
+ stLeverDown();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Lever::stLeverDown() {
+ startAnimation(0x80880090, 1, -1);
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverDownEvent);
+}
+
+void AsScene2207Lever::stLeverDownEvent() {
+ sendMessage(_parentScene, 0x480F, 0);
+}
+
+void AsScene2207Lever::stLeverUp() {
+ startAnimation(0x80880090, 6, -1);
+ _playBackwards = true;
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverUpEvent);
+}
+
+void AsScene2207Lever::stLeverUpEvent() {
+ sendMessage(_parentScene, 0x4807, 0);
+}
+
+AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0xCCFD6090, 100);
+ startAnimation(0xCCFD6090, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(1, 0x40330872);
+ loadSound(2, 0x72A2914A);
+ loadSound(3, 0xD4226080);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
+}
+
+AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
+ _vm->_soundMan->deleteSoundGroup(0x80D00820);
+}
+
+uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (!_idle) {
+ if (param.asInteger() == 0x3423093) {
+ _vm->_soundMan->addSound(0x80D00820, 0x12121943);
+ _vm->_soundMan->playSoundLooping(0x12121943);
+ } else if (param.asInteger() == 0x834AB011) {
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ } else if (param.asInteger() == 0x3A980501)
+ playSound(1);
+ else if (param.asInteger() == 0x2A2AD498)
+ playSound(2);
+ else if (param.asInteger() == 0xC4980008)
+ playSound(3);
+ else if (param.asInteger() == 0x06B84228)
+ playSound(0, 0xE0702146);
+ }
+ break;
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallRobotAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ startAnimation(0xCCFD6090, 0, -1);
+ _idle = false;
+ setVisible(true);
+ }
+}
+
+void AsScene2207WallRobotAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallRobotAnimation::cbStopAnimation() {
+ stopAnimation();
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ _idle = true;
+ setVisible(false);
+}
+
+AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0x8CAA0099, 100);
+ startAnimation(0x8CAA0099, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
+}
+
+uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallCannonAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ setVisible(true);
+ startAnimation(0x8CAA0099, 0, -1);
+ _idle = false;
+ }
+}
+
+void AsScene2207WallCannonAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallCannonAnimation::cbStopAnimation() {
+ stopAnimation();
+ setVisible(false);
+ _idle = true;
+}
+
+SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = 330;
+ _y = 246 + index * 50;
+ updatePosition();
+}
+
+KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x04104242);
+}
+
+uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4819:
+ GotoState(&KmScene2203::stClayDoorOpen);
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2203::stClayDoorOpen() {
+ if (!stStartAction(AnimationCallback(&KmScene2203::stClayDoorOpen))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x5CCCB330, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2203::hmClayDoorOpen);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ }
+}
+
+uint32 KmScene2203::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x040D4186) {
+ sendMessage(_attachedSprite, 0x4808, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2205::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _walkResumeFrameIncr = 1;
+ _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
+}
+
+KmScene2206::~KmScene2206() {
+ _vm->_soundMan->deleteSoundGroup(0x80101800);
+}
+
+void KmScene2206::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&KmScene2206::stRidePlatformDown);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2206::suRidePlatformDown() {
+ _platformDeltaY++;
+ _y += _platformDeltaY;
+ if (_y > 600)
+ sendMessage(this, 0x1019, 0);
+}
+
+void KmScene2206::stRidePlatformDown() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene2206::stRidePlatformDown))) {
+ _busyStatus = 1;
+ sendMessage(_parentScene, 0x4803, 0);
+ _acceptInput = false;
+ _platformDeltaY = 0;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&KmScene2206::suRidePlatformDown);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+}
+
+KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stRidePlatform);
+ break;
+ case 0x2005:
+ suRidePlatform();
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stInteractLever);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2242::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+ // Empty
+}
+
+void KmHallOfRecords::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2247::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2200_sprites.h b/engines/neverhood/modules/module2200_sprites.h
new file mode 100644
index 0000000000..9aaf3b6aae
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.h
@@ -0,0 +1,275 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/graphics.h"
+
+namespace Neverhood {
+
+static const NPoint kSsScene2201PuzzleCubePoints[] = {
+ {305, 305}, {321, 305}, {336, 305}, {305, 319},
+ {321, 319}, {336, 319}, {305, 332}, {321, 332},
+ {336, 333}
+};
+
+static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
+ 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
+ 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
+};
+
+class AsScene2201CeilingFan : public AnimatedSprite {
+public:
+ AsScene2201CeilingFan(NeverhoodEngine *vm);
+};
+
+class AsScene2201Door : public AnimatedSprite {
+public:
+ AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
+protected:
+ Klaymen *_klaymen;
+ Sprite *_ssDoorLight;
+ bool _isOpen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+};
+
+class SsScene2201PuzzleCube : public StaticSprite {
+public:
+ SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
+};
+
+class SsScene2202PuzzleCube : public StaticSprite {
+public:
+ SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
+protected:
+ Scene *_parentScene;
+ int16 _cubeSymbol;
+ int16 _cubePosition;
+ int16 _newX, _newY;
+ int16 _xDelta, _yDelta;
+ int16 _xIncr;
+ int16 _yIncr;
+ int16 _errValue;
+ int16 _counter;
+ int16 _xFlagPos;
+ bool _counterDirection;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveCubeX();
+ void suMoveCubeY();
+ void moveCube(int16 newCubePosition);
+ void stopMoving();
+};
+
+class AsCommonKey : public AnimatedSprite {
+public:
+ AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ int _keyIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2203Door : public AnimatedSprite {
+public:
+ AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
+protected:
+ Scene *_parentScene;
+ Sprite *_otherDoor;
+ uint _doorIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void openDoor();
+ void closeDoor();
+};
+
+class SsScene2205DoorFrame : public StaticSprite {
+public:
+ SsScene2205DoorFrame(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2206DoorSpikes : public StaticSprite {
+public:
+ AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int _deltaIndex;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpen();
+ void suClose();
+};
+
+class AsScene2206Platform : public StaticSprite {
+public:
+ AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int16 _yDelta;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+};
+
+class SsScene2206TestTube : public StaticSprite {
+public:
+ SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2207Elevator : public AnimatedSprite {
+public:
+ AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207Elevator();
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointArray;
+ int16 _pointIndex;
+ int16 _destPointIndex, _destPointIndexDelta;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSetPosition();
+ void moveToY(int16 y);
+};
+
+class AsScene2207Lever : public AnimatedSprite {
+public:
+ AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLeverDown();
+ void stLeverDownEvent();
+ void stLeverUp();
+ void stLeverUpEvent();
+};
+
+class AsScene2207WallRobotAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207WallRobotAnimation();
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class AsScene2207WallCannonAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class SsScene2207Symbol : public StaticSprite {
+public:
+ SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class KmScene2201 : public Klaymen {
+public:
+ KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2203 : public Klaymen {
+public:
+ KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stClayDoorOpen();
+ uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2205 : public Klaymen {
+public:
+ KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2206 : public Klaymen {
+public:
+ KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~KmScene2206();
+protected:
+ void stRidePlatformDown();
+ void suRidePlatformDown();
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2207 : public Klaymen {
+public:
+ KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2242 : public Klaymen {
+public:
+ KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmHallOfRecords : public Klaymen {
+public:
+ KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2247 : public Klaymen {
+public:
+ KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2200_SPRITES_H */
diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp
index 34eca14bea..689d53570f 100644
--- a/engines/neverhood/modules/module2300.cpp
+++ b/engines/neverhood/modules/module2300.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "neverhood/modules/module2300.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2300.h"
namespace Neverhood {
@@ -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);
@@ -68,7 +68,7 @@ Module2300::~Module2300() {
}
void Module2300::createScene(int sceneNum, int which) {
- debug("Module2300::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2300::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -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 450812a5f3..dab39b24f6 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -20,17 +20,23 @@
*
*/
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2400.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2400_sprites.h"
+#include "neverhood/modules/module2800_sprites.h"
namespace Neverhood {
Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which)
: Module(vm, parentModule) {
-
+
_vm->_soundMan->addMusic(0x202D1010, 0xB110382D);
if (which < 0)
- createScene(_vm->gameState().sceneNum, _vm->gameState().which);
+ createScene(_vm->gameState().sceneNum, -1);
else
createScene(0, 0);
@@ -41,7 +47,7 @@ Module2400::~Module2400() {
}
void Module2400::createScene(int sceneNum, int which) {
- debug("Module2400::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2400::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -168,205 +174,13 @@ 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)
-};
-
-static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
- 0x5C044690, 0x5C644690, 0x5CA44690,
- 0x5D244690, 0x5E244690
-};
-
-static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
- 0xF4418408, 0xF4418808, 0xF4419008,
- 0xF441A008, 0xCD4F8411
+ { 369, 331, 394, 389 },
+ { 395, 331, 419, 389 },
+ { 420, 331, 441, 389 },
+ { 442, 331, 464, 389 },
+ { 465, 331, 491, 389 }
};
-AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 240;
- _y = 447;
- createSurface(100, 146, 74);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x120A0013)
- playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
- break;
- case 0x2000:
- _x = 240;
- _y = 447;
- _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
- startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
- setVisible(true);
- playSound(0, 0x48640244);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
-
- _x = 88;
- _y = 421;
- createSurface1(0x10203116, 100);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
-}
-
-AsScene2401FlowingWater::~AsScene2401FlowingWater() {
- _vm->_soundMan->deleteSoundGroup(0x40F11C09);
-}
-
-uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isWaterFlowing && param.asInteger() == 0x02421405)
- startAnimationByHash(0x10203116, 0x01084280, 0);
- break;
- case 0x2002:
- if (!_isWaterFlowing) {
- _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
- _vm->_soundMan->playSoundLooping(0x980C1420);
- startAnimation(0x10203116, 0, -1);
- setVisible(true);
- _isWaterFlowing = true;
- }
- break;
- case 0x2003:
- _vm->_soundMan->deleteSound(0x980C1420);
- _isWaterFlowing = false;
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
-
- _x = x;
- _y = y;
- createSurface1(0xB8596884, 100);
- setVisible(false);
- SetUpdateHandler(&AsScene2401WaterFlushing::update);
- SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
-}
-
-void AsScene2401WaterFlushing::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0xB8596884, 0, -1);
- setVisible(true);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
- startAnimationByHash(0xB8596884, 0x01084280, 0);
- _flushLoopCount--;
- }
- break;
- case 0x2002:
- if (param.asInteger() > 0) {
- _flushLoopCount = param.asInteger() - 1;
- _countdown = _vm->_rnd->getRandomNumber(3) + 1;
- }
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x44687810, 100);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (_isOpen) {
- stopAnimation();
- setVisible(false);
- _countdown = 48;
- } else {
- startAnimation(0x44687810, 0, -1);
- _newStickFrameIndex = 0;
- }
- SetUpdateHandler(&AsScene2401Door::update);
- SetMessageHandler(&AsScene2401Door::handleMessage);
-}
-
-void AsScene2401Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x44687810, -1, -1);
- _newStickFrameIndex = 0;
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (!_isOpen) {
- _countdown = 168;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x44687810, 0, -1);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene2401Door::stDoorOpenFinished);
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene2401Door::stDoorOpenFinished() {
- stopAnimation();
- setVisible(false);
-}
-
Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _unkFlag(false),
_soundToggle(false), _asWaterSpitIndex(0) {
@@ -398,7 +212,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 +275,7 @@ void Scene2401::update() {
if (_countdown2 != 0 && (--_countdown2) == 0)
sendMessage(_asFlowingWater, 0x2003, 0);
-
+
Scene::update();
}
@@ -546,143 +360,6 @@ static const uint32 kScene2402FileHashes[] = {
0xD0910068, 0xD09100A8
};
-AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x80495831, 100);
- if (_isOpen) {
- startAnimation(0x80495831, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- SetUpdateHandler(&AsScene2402Door::update);
- SetMessageHandler(&AsScene2402Door::handleMessage);
-}
-
-void AsScene2402Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x80495831, -1, -1);
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene2402Door::stDoorClosingFinished);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x80495831, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen38"));
- break;
- }
- return messageResult;
-}
-
-void AsScene2402Door::stDoorClosingFinished() {
- sendMessage(_parentScene, 0x2001, 0);
- setVisible(false);
-}
-
-AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
-
- _x = 260;
- _y = 210;
- createSurface(100, 127, 90);
- setDoDeltaX(1);
- SetMessageHandler(&Sprite::handleMessage);
- if (!getGlobalVar(V_TV_JOKE_TOLD)) {
- loadSound(0, 0x58208810);
- _countdown1 = 48;
- startAnimation(0x4919397A, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upWait);
- } else {
- int16 frameIndex;
- if (_klaymen->getX() > 320)
- _currFrameIndex = 29;
- frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- startAnimation(0x050A0103, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
- _countdown1 = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
- }
-}
-
-AsScene2402TV::~AsScene2402TV() {
- _vm->_soundMan->deleteSoundGroup(0x01520123);
-}
-
-void AsScene2402TV::upWait() {
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- startAnimation(0x4919397A, 0, -1);
- SetMessageHandler(&AsScene2402TV::hmJoke);
- NextState(&AsScene2402TV::stJokeFinished);
- }
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::upFocusKlaymen() {
- int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- if (frameIndex != _currFrameIndex) {
- if (frameIndex > _currFrameIndex)
- _currFrameIndex++;
- else if (frameIndex < _currFrameIndex)
- _currFrameIndex--;
- startAnimation(0x050A0103, _currFrameIndex, -1);
- _newStickFrameIndex = _currFrameIndex;
- if (_countdown2 == 0) {
- _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
- _vm->_soundMan->playSoundLooping(0xC42D4528);
- }
- _countdown2 = 5;
- } else if (_countdown2 != 0 && (--_countdown2 == 0))
- _vm->_soundMan->deleteSound(0xC42D4528);
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::stJokeFinished() {
- setGlobalVar(V_TV_JOKE_TOLD, 1);
- startAnimation(0x050A0103, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
-}
-
-uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x431EA0B0)
- playSound(0);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _soundToggle(false) {
@@ -698,7 +375,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 +456,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 +464,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 +476,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 +505,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 +564,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
setGlobalVar(V_KEY3_LOCATION, 2);
SetMessageHandler(&Scene2406::handleMessage);
-
+
setRectList(0x004B78C8);
insertScreenMouse(0xB03001A8);
@@ -913,7 +590,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/module2400.h b/engines/neverhood/modules/module2400.h
index b50fff91c4..61603f3e00 100644
--- a/engines/neverhood/modules/module2400.h
+++ b/engines/neverhood/modules/module2400.h
@@ -27,12 +27,6 @@
#include "neverhood/module.h"
#include "neverhood/scene.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1100.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module2800.h"
#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -50,44 +44,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2401WaterSpit : public AnimatedSprite {
-public:
- AsScene2401WaterSpit(NeverhoodEngine *vm);
-protected:
- int _soundIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401FlowingWater : public AnimatedSprite {
-public:
- AsScene2401FlowingWater(NeverhoodEngine *vm);
- virtual ~AsScene2401FlowingWater();
-protected:
- bool _isWaterFlowing;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401WaterFlushing : public AnimatedSprite {
-public:
- AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
-protected:
- int _countdown;
- int _flushLoopCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401Door : public AnimatedSprite {
-public:
- AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorOpenFinished();
-};
-
class Scene2401 : public Scene {
public:
Scene2401(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -111,32 +67,6 @@ protected:
void playPipeSound(uint32 fileHash);
};
-class AsScene2402Door : public AnimatedSprite {
-public:
- AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorClosingFinished();
-};
-
-class AsScene2402TV : public AnimatedSprite {
-public:
- AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
- virtual ~AsScene2402TV();
-protected:
- Klaymen *_klaymen;
- int _countdown1;
- int _countdown2;
- void upWait();
- void upFocusKlaymen();
- void stJokeFinished();
- uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2402 : public Scene {
public:
Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2400_sprites.cpp b/engines/neverhood/modules/module2400_sprites.cpp
new file mode 100644
index 0000000000..bf85b0dc37
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.cpp
@@ -0,0 +1,741 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2400_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
+ 0x5C044690, 0x5C644690, 0x5CA44690,
+ 0x5D244690, 0x5E244690
+};
+
+static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
+ 0xF4418408, 0xF4418808, 0xF4419008,
+ 0xF441A008, 0xCD4F8411
+};
+
+AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 240;
+ _y = 447;
+ createSurface(100, 146, 74);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x120A0013)
+ playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
+ break;
+ case 0x2000:
+ _x = 240;
+ _y = 447;
+ _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
+ startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
+ setVisible(true);
+ playSound(0, 0x48640244);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
+
+ _x = 88;
+ _y = 421;
+ createSurface1(0x10203116, 100);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
+}
+
+AsScene2401FlowingWater::~AsScene2401FlowingWater() {
+ _vm->_soundMan->deleteSoundGroup(0x40F11C09);
+}
+
+uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_isWaterFlowing && param.asInteger() == 0x02421405)
+ startAnimationByHash(0x10203116, 0x01084280, 0);
+ break;
+ case 0x2002:
+ if (!_isWaterFlowing) {
+ _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
+ _vm->_soundMan->playSoundLooping(0x980C1420);
+ startAnimation(0x10203116, 0, -1);
+ setVisible(true);
+ _isWaterFlowing = true;
+ }
+ break;
+ case 0x2003:
+ _vm->_soundMan->deleteSound(0x980C1420);
+ _isWaterFlowing = false;
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
+
+ _x = x;
+ _y = y;
+ createSurface1(0xB8596884, 100);
+ setVisible(false);
+ SetUpdateHandler(&AsScene2401WaterFlushing::update);
+ SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
+}
+
+void AsScene2401WaterFlushing::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0xB8596884, 0, -1);
+ setVisible(true);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
+ startAnimationByHash(0xB8596884, 0x01084280, 0);
+ _flushLoopCount--;
+ }
+ break;
+ case 0x2002:
+ if (param.asInteger() > 0) {
+ _flushLoopCount = param.asInteger() - 1;
+ _countdown = _vm->_rnd->getRandomNumber(3) + 1;
+ }
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x44687810, 100);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (_isOpen) {
+ stopAnimation();
+ setVisible(false);
+ _countdown = 48;
+ } else {
+ startAnimation(0x44687810, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ SetUpdateHandler(&AsScene2401Door::update);
+ SetMessageHandler(&AsScene2401Door::handleMessage);
+}
+
+void AsScene2401Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x44687810, -1, -1);
+ _newStickFrameIndex = 0;
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ if (!_isOpen) {
+ _countdown = 168;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x44687810, 0, -1);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene2401Door::stDoorOpenFinished);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2401Door::stDoorOpenFinished() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x80495831, 100);
+ if (_isOpen) {
+ startAnimation(0x80495831, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ SetUpdateHandler(&AsScene2402Door::update);
+ SetMessageHandler(&AsScene2402Door::handleMessage);
+}
+
+void AsScene2402Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x80495831, -1, -1);
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene2402Door::stDoorClosingFinished);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x80495831, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen38"));
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2402Door::stDoorClosingFinished() {
+ sendMessage(_parentScene, 0x2001, 0);
+ setVisible(false);
+}
+
+AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
+
+ _x = 260;
+ _y = 210;
+ createSurface(100, 127, 90);
+ setDoDeltaX(1);
+ SetMessageHandler(&Sprite::handleMessage);
+ if (!getGlobalVar(V_TV_JOKE_TOLD)) {
+ loadSound(0, 0x58208810);
+ _countdown1 = 48;
+ startAnimation(0x4919397A, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upWait);
+ } else {
+ int16 frameIndex;
+ if (_klaymen->getX() > 320)
+ _currFrameIndex = 29;
+ frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ startAnimation(0x050A0103, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+ _countdown1 = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+ }
+}
+
+AsScene2402TV::~AsScene2402TV() {
+ _vm->_soundMan->deleteSoundGroup(0x01520123);
+}
+
+void AsScene2402TV::upWait() {
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ startAnimation(0x4919397A, 0, -1);
+ SetMessageHandler(&AsScene2402TV::hmJoke);
+ NextState(&AsScene2402TV::stJokeFinished);
+ }
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::upFocusKlaymen() {
+ int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ if (frameIndex != _currFrameIndex) {
+ if (frameIndex > _currFrameIndex)
+ _currFrameIndex++;
+ else if (frameIndex < _currFrameIndex)
+ _currFrameIndex--;
+ startAnimation(0x050A0103, _currFrameIndex, -1);
+ _newStickFrameIndex = _currFrameIndex;
+ if (_countdown2 == 0) {
+ _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
+ _vm->_soundMan->playSoundLooping(0xC42D4528);
+ }
+ _countdown2 = 5;
+ } else if (_countdown2 != 0 && (--_countdown2 == 0))
+ _vm->_soundMan->deleteSound(0xC42D4528);
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::stJokeFinished() {
+ setGlobalVar(V_TV_JOKE_TOLD, 1);
+ startAnimation(0x050A0103, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+}
+
+uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x431EA0B0)
+ playSound(0);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y),
+ _canSpitPipe(false), _contSpitPipe(false), _readyToSpit(false),
+ _spitPipeIndex(0), _spitDestPipeIndex(0), _spitContDestPipeIndex(0) {
+
+ // Empty
+}
+
+uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4832:
+ GotoState(&Klaymen::stUseTube);
+ break;
+ case 0x4833:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAbout);
+ else {
+ _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&KmScene2401::stTrySpitIntoPipe);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2401::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x16401CA6) {
+ _canSpitPipe = true;
+ if (_contSpitPipe)
+ spitIntoPipe();
+ } else if (param.asInteger() == 0xC11C0008) {
+ _canSpitPipe = false;
+ _acceptInput = false;
+ _readyToSpit = false;
+ } else if (param.asInteger() == 0x018A0001) {
+ sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2401::stTrySpitIntoPipe() {
+ if (_readyToSpit) {
+ _contSpitPipe = true;
+ _spitContDestPipeIndex = _spitPipeIndex;
+ if (_canSpitPipe)
+ spitIntoPipe();
+ } else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) {
+ _busyStatus = 2;
+ _acceptInput = true;
+ _spitDestPipeIndex = _spitPipeIndex;
+ _readyToSpit = true;
+ _canSpitPipe = false;
+ _contSpitPipe = false;
+ startAnimation(0x1808B150, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void KmScene2401::spitIntoPipe() {
+ _contSpitPipe = false;
+ _spitDestPipeIndex = _spitContDestPipeIndex;
+ _canSpitPipe = false;
+ _acceptInput = false;
+ startAnimation(0x1B08B553, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene2401::stContSpitIntoPipe);
+}
+
+void KmScene2401::stContSpitIntoPipe() {
+ _canSpitPipe = true;
+ _acceptInput = true;
+ startAnimationByHash(0x1808B150, 0x16401CA6, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+}
+
+KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (!getGlobalVar(V_TV_JOKE_TOLD))
+ GotoState(&Klaymen::stStandWonderAbout);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2400_sprites.h b/engines/neverhood/modules/module2400_sprites.h
new file mode 100644
index 0000000000..a901eb101c
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.h
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/gamemodule.h"
+
+namespace Neverhood {
+
+class AsScene2401WaterSpit : public AnimatedSprite {
+public:
+ AsScene2401WaterSpit(NeverhoodEngine *vm);
+protected:
+ int _soundIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401FlowingWater : public AnimatedSprite {
+public:
+ AsScene2401FlowingWater(NeverhoodEngine *vm);
+ virtual ~AsScene2401FlowingWater();
+protected:
+ bool _isWaterFlowing;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401WaterFlushing : public AnimatedSprite {
+public:
+ AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
+protected:
+ int _countdown;
+ int _flushLoopCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401Door : public AnimatedSprite {
+public:
+ AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorOpenFinished();
+};
+
+class AsScene2402Door : public AnimatedSprite {
+public:
+ AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorClosingFinished();
+};
+
+class AsScene2402TV : public AnimatedSprite {
+public:
+ AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
+ virtual ~AsScene2402TV();
+protected:
+ Klaymen *_klaymen;
+ int _countdown1;
+ int _countdown2;
+ void upWait();
+ void upFocusKlaymen();
+ void stJokeFinished();
+ uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2401 : public Klaymen {
+public:
+ KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ bool _canSpitPipe;
+ bool _contSpitPipe;
+ bool _readyToSpit;
+ uint32 _spitPipeIndex;
+ uint32 _spitDestPipeIndex;
+ uint32 _spitContDestPipeIndex;
+
+ void spitIntoPipe();
+ void stTrySpitIntoPipe();
+ void stContSpitIntoPipe();
+ uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2402 : public Klaymen {
+public:
+ KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2403 : public Klaymen {
+public:
+ KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2406 : public Klaymen {
+public:
+ KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2400_SPRITES_H */
diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp
index a997b5aab1..d0e60adf65 100644
--- a/engines/neverhood/modules/module2500.cpp
+++ b/engines/neverhood/modules/module2500.cpp
@@ -20,8 +20,12 @@
*
*/
+#include "neverhood/modules/module1600.h" // for Scene1608
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2500.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module2500_sprites.h"
+#include "neverhood/modules/module2700.h" // for Scene2704
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
@@ -29,29 +33,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);
@@ -73,7 +77,7 @@ Module2500::~Module2500() {
}
void Module2500::createScene(int sceneNum, int which) {
- debug("Module2500::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2500::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -212,14 +216,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 +286,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 +304,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 +395,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 +438,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);
@@ -470,59 +474,11 @@ void Scene2501::updateKlaymenClipRect() {
_kmScene2501->setClipRect(0, 0, 640, 388);
}
-SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
- : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
-
- loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x4600204C);
- loadSound(1, 0x408C0034);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
- SetMessageHandler(&SsScene2504Button::handleMessage);
- SetUpdateHandler(&SsScene2504Button::update);
-}
-
-void SsScene2504Button::update() {
- updatePosition();
- if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
- playSound(3);
- setVisible(false);
- _isSoundPlaying = false;
- }
- if (_countdown != 0 && (--_countdown) == 0) {
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- playSound(0);
- else
- playSound(1);
- _isSoundPlaying = true;
- }
-}
-
-uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isSoundPlaying) {
- setVisible(true);
- _countdown = 2;
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
- else
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
- playSound(2);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
Sprite *ssButton;
-
+
setBackground(0x90791B80);
setPalette(0x90791B80);
ssButton = insertSprite<SsScene2504Button>();
diff --git a/engines/neverhood/modules/module2500.h b/engines/neverhood/modules/module2500.h
index 07db7907d5..de6226ef0c 100644
--- a/engines/neverhood/modules/module2500.h
+++ b/engines/neverhood/modules/module2500.h
@@ -26,14 +26,10 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1600.h"
-#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
-// Module2500
-
class Module2500 : public Module {
public:
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -47,6 +43,8 @@ protected:
void createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
+class AsCommonCar;
+
class Scene2501 : public Scene {
public:
Scene2501(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -79,16 +77,6 @@ protected:
void updateKlaymenClipRect();
};
-class SsScene2504Button : public StaticSprite {
-public:
- SsScene2504Button(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isSoundPlaying;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2504 : public Scene {
public:
Scene2504(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2500_sprites.cpp b/engines/neverhood/modules/module2500_sprites.cpp
new file mode 100644
index 0000000000..ab6b3dcfbe
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2500_sprites.h"
+
+namespace Neverhood {
+
+SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
+ : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
+
+ loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x4600204C);
+ loadSound(1, 0x408C0034);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+ SetMessageHandler(&SsScene2504Button::handleMessage);
+ SetUpdateHandler(&SsScene2504Button::update);
+}
+
+void SsScene2504Button::update() {
+ updatePosition();
+ if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
+ playSound(3);
+ setVisible(false);
+ _isSoundPlaying = false;
+ }
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ playSound(0);
+ else
+ playSound(1);
+ _isSoundPlaying = true;
+ }
+}
+
+uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isSoundPlaying) {
+ setVisible(true);
+ _countdown = 2;
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
+ else
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
+ playSound(2);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2500_sprites.h b/engines/neverhood/modules/module2500_sprites.h
new file mode 100644
index 0000000000..e7f7b05702
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene2504Button : public StaticSprite {
+public:
+ SsScene2504Button(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isSoundPlaying;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2501 : public Klaymen {
+public:
+ KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2500_SPRITES_H */
diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp
index b8dbf7bff1..a6484a4926 100644
--- a/engines/neverhood/modules/module2600.cpp
+++ b/engines/neverhood/modules/module2600.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module2600.h"
+#include "neverhood/modules/module2600_sprites.h"
namespace Neverhood {
@@ -35,7 +36,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)
@@ -54,7 +55,7 @@ Module2600::~Module2600() {
}
void Module2600::createScene(int sceneNum, int which) {
- debug("Module2600::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2600::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -218,98 +219,10 @@ void Module2600::updateScene() {
}
}
}
-
-SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- SetUpdateHandler(&SsScene2609Button::update);
- SetMessageHandler(&SsScene2609Button::handleMessage);
-
- loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- if (!getGlobalVar(V_WATER_RUNNING))
- setVisible(false);
- loadSound(0, 0x10267160);
- loadSound(1, 0x7027FD64);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
-}
-
-void SsScene2609Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- if (getGlobalVar(V_WATER_RUNNING)) {
- setGlobalVar(V_WATER_RUNNING, 0);
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- setGlobalVar(V_WATER_RUNNING, 1);
- sendMessage(_parentScene, 0x2002, 0);
- }
- }
-}
-
-uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x2000, 0);
- if (getGlobalVar(V_WATER_RUNNING)) {
- setVisible(false);
- playSound(3);
- playSound(1);
- _countdown = 12;
- } else {
- setVisible(true);
- playSound(2);
- playSound(0);
- _countdown = 96;
- }
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1000) {
-
- _x = 240;
- _y = 420;
- setDoDeltaX(1);
- createSurface1(0x9C210C90, 1200);
- setClipRect(260, 260, 400, 368);
- _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2609Water::handleMessage);
- if (getGlobalVar(V_WATER_RUNNING))
- sendMessage(this, 0x2002, 0);
-}
-
-AsScene2609Water::~AsScene2609Water() {
- _vm->_soundMan->deleteSoundGroup(0x08526C36);
-}
-
-uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- stopAnimation();
- setVisible(false);
- _vm->_soundMan->stopSound(0xDC2769B0);
- break;
- case 0x2002:
- startAnimation(0x9C210C90, 0, -1);
- setVisible(true);
- _vm->_soundMan->playSoundLooping(0xDC2769B0);
- break;
- }
- return messageResult;
-}
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isBusy(false) {
-
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene2609::handleMessage);
diff --git a/engines/neverhood/modules/module2600.h b/engines/neverhood/modules/module2600.h
index d972e0fb0d..99ec3a34ca 100644
--- a/engines/neverhood/modules/module2600.h
+++ b/engines/neverhood/modules/module2600.h
@@ -41,24 +41,6 @@ protected:
void updateScene();
};
-class SsScene2609Button : public StaticSprite {
-public:
- SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2609Water : public AnimatedSprite {
-public:
- AsScene2609Water(NeverhoodEngine *vm);
- virtual ~AsScene2609Water();
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2609 : public Scene {
public:
Scene2609(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2600_sprites.cpp b/engines/neverhood/modules/module2600_sprites.cpp
new file mode 100644
index 0000000000..2c24b533f3
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.cpp
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2600_sprites.h"
+
+namespace Neverhood {
+
+SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ SetUpdateHandler(&SsScene2609Button::update);
+ SetMessageHandler(&SsScene2609Button::handleMessage);
+
+ loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ if (!getGlobalVar(V_WATER_RUNNING))
+ setVisible(false);
+ loadSound(0, 0x10267160);
+ loadSound(1, 0x7027FD64);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+}
+
+void SsScene2609Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setGlobalVar(V_WATER_RUNNING, 0);
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ setGlobalVar(V_WATER_RUNNING, 1);
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ }
+}
+
+uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x2000, 0);
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setVisible(false);
+ playSound(3);
+ playSound(1);
+ _countdown = 12;
+ } else {
+ setVisible(true);
+ playSound(2);
+ playSound(0);
+ _countdown = 96;
+ }
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1000) {
+
+ _x = 240;
+ _y = 420;
+ setDoDeltaX(1);
+ createSurface1(0x9C210C90, 1200);
+ setClipRect(260, 260, 400, 368);
+ _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2609Water::handleMessage);
+ if (getGlobalVar(V_WATER_RUNNING))
+ sendMessage(this, 0x2002, 0);
+}
+
+AsScene2609Water::~AsScene2609Water() {
+ _vm->_soundMan->deleteSoundGroup(0x08526C36);
+}
+
+uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ stopAnimation();
+ setVisible(false);
+ _vm->_soundMan->stopSound(0xDC2769B0);
+ break;
+ case 0x2002:
+ startAnimation(0x9C210C90, 0, -1);
+ setVisible(true);
+ _vm->_soundMan->playSoundLooping(0xDC2769B0);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2600_sprites.h b/engines/neverhood/modules/module2600_sprites.h
new file mode 100644
index 0000000000..c36e72cae8
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2600
+
+class SsScene2609Button : public StaticSprite {
+public:
+ SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2609Water : public AnimatedSprite {
+public:
+ AsScene2609Water(NeverhoodEngine *vm);
+ virtual ~AsScene2609Water();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2600_SPRITES_H */
diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp
index 8b69bc050e..1b78615fdb 100644
--- a/engines/neverhood/modules/module2700.cpp
+++ b/engines/neverhood/modules/module2700.cpp
@@ -20,20 +20,21 @@
*
*/
-#include "neverhood/modules/module2700.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
-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 +69,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,
@@ -83,8 +84,8 @@ static const uint32 kScene2725StaticSprites[] = {
};
Module2700::Module2700(NeverhoodEngine *vm, Module *parentModule, int which)
- : Module(vm, parentModule), _soundIndex(0), _raidoMusicInitialized(false) {
-
+ : Module(vm, parentModule), _soundIndex(0), _radioMusicInitialized(false) {
+
_vm->_soundMan->addMusic(0x42212411, 0x04020210);
_vm->_soundMan->startMusic(0x04020210, 24, 2);
SetMessageHandler(&Module2700::handleMessage);
@@ -111,7 +112,7 @@ Module2700::~Module2700() {
}
void Module2700::createScene(int sceneNum, int which) {
- debug("Module2700::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2700::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -500,7 +501,7 @@ void Module2700::updateScene() {
} else {
switch (_sceneNum) {
case 21:
- if (!_raidoMusicInitialized) {
+ if (!_radioMusicInitialized) {
_vm->_soundMan->stopMusic(0x04020210, 0, 1);
_vm->gameModule()->initRadioPuzzle();
_musicFileHash = getGlobalVar(V_GOOD_RADIO_MUSIC_NAME);
@@ -508,7 +509,7 @@ void Module2700::updateScene() {
_vm->_soundMan->startMusic(_musicFileHash, 0, 2);
_vm->_soundMan->addSound(0x42212411, 0x44014282);
_vm->_soundMan->setSoundParams(0x44014282, true, 120, 360, 72, 0);
- _raidoMusicInitialized = true;
+ _radioMusicInitialized = true;
}
break;
}
@@ -527,7 +528,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);
}
@@ -536,98 +537,21 @@ void Module2700::createScene2704(int which, uint32 trackInfoId, int16 value, con
_childObject = new Scene2704(_vm, this, which, trackInfoId, value, staticSprites, clipRect);
}
-static const NPoint kCarShadowOffsets[] = {
- {-63, 3}, {-48, 40}, {-33, 58},
- { 0, 65}, { 40, 53}, { 56, 27},
- { 63, 0}, {-30, 26}, { 0, 30},
- { 26, 25}
-};
-
-SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
-}
-
-AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
-
- SetUpdateHandler(&AsCommonCarShadow::update);
- createShadowSurface(shadowSurface, 211, 147, 100);
- updateShadow();
-}
-
-void AsCommonCarShadow::update() {
- updateShadow();
- AnimatedSprite::update();
-}
-
-void AsCommonCarShadow::updateShadow() {
- if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
- uint32 fileHash = _asCar->getCurrAnimFileHash();
- if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
- fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
- fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
- fileHash == 0xF46A0324) {
- startAnimation(fileHash, _asCar->getFrameIndex(), -1);
- _newStickFrameIndex = _asCar->getFrameIndex();
- }
- _animFileHash = fileHash;
- }
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- if (!_asCar->getVisible()) {
- startAnimation(0x1209E09F, 0, -1);
- _newStickFrameIndex = 0;
- }
- setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
-}
-
-AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
-
- SetUpdateHandler(&AsCommonCarConnectorShadow::update);
- createShadowSurface1(shadowSurface, 0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsCommonCarConnectorShadow::update() {
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- AnimatedSprite::update();
-}
-
-AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- SetUpdateHandler(&AsCommonCarTrackShadow::update);
- createShadowSurface1(shadowSurface, 0x0759129C, 100);
- startAnimation(0x0759129C, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
-}
-
-void AsCommonCarTrackShadow::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
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 +585,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 +639,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 +658,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 +689,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 +797,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 +829,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 +845,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 +855,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 +905,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 +923,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 +948,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 +964,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 +1007,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 +1032,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 +1047,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 +1116,7 @@ void Scene2706::changeTrack() {
Scene2732::Scene2732(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule) {
-
+
Sprite *tempSprite;
setBackground(0x0220C041);
diff --git a/engines/neverhood/modules/module2700.h b/engines/neverhood/modules/module2700.h
index 003666bb7f..97b4f1cbea 100644
--- a/engines/neverhood/modules/module2700.h
+++ b/engines/neverhood/modules/module2700.h
@@ -26,7 +26,7 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
@@ -39,7 +39,7 @@ public:
protected:
int _sceneNum;
int _soundIndex;
- bool _raidoMusicInitialized;
+ bool _radioMusicInitialized;
uint32 _scene2711StaticSprites[6];
uint32 _musicFileHash;
void createScene(int sceneNum, int which);
@@ -49,38 +49,7 @@ protected:
void createScene2704(int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
-class SsCommonTrackShadowBackground : public StaticSprite {
-public:
- SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
-};
-
-class AsCommonCarShadow : public AnimatedSprite {
-public:
- AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- AnimatedSprite *_asCar;
- uint32 _animFileHash;
- void update();
- void updateShadow();
-};
-
-class AsCommonCarConnectorShadow : public AnimatedSprite {
-public:
- AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- Sprite *_asCar;
- void update();
-};
-
-class AsCommonCarTrackShadow : public AnimatedSprite {
-public:
- AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
-protected:
- Sprite *_asCar;
- void update();
-};
+class AsCommonCar;
class Scene2701 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2700_sprites.cpp b/engines/neverhood/modules/module2700_sprites.cpp
new file mode 100644
index 0000000000..8dd2fa3461
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2700_sprites.h"
+
+namespace Neverhood {
+
+static const NRect kScene2710ClipRect = { 0, 0, 626, 480 };
+
+static const uint32 kScene2710StaticSprites[] = {
+ 0x0D2016C0,
+ 0
+};
+
+static const NRect kScene2711ClipRect = { 0, 0, 521, 480 };
+
+static const uint32 kScene2711FileHashes1[] = {
+ 0,
+ 0x100801A1,
+ 0x201081A0,
+ 0x006800A4,
+ 0x40390120,
+ 0x000001B1,
+ 0x001000A1,
+ 0
+};
+
+static const uint32 kScene2711FileHashes2[] = {
+ 0,
+ 0x40403308,
+ 0x71403168,
+ 0x80423928,
+ 0x224131A8,
+ 0x50401328,
+ 0x70423328,
+ 0
+};
+
+static const uint32 kScene2711FileHashes3[] = {
+ 0,
+ 0x1088A021,
+ 0x108120E5,
+ 0x18A02321,
+ 0x148221A9,
+ 0x10082061,
+ 0x188820E1,
+ 0
+};
+
+static const NRect kScene2724ClipRect = { 0, 141, 640, 480 };
+
+static const uint32 kScene2724StaticSprites[] = {
+ 0xC20D00A5,
+ 0
+};
+
+static const NRect kScene2725ClipRect = { 0, 0, 640, 413 };
+
+static const uint32 kScene2725StaticSprites[] = {
+ 0xC20E00A5,
+ 0
+};
+
+static const NPoint kCarShadowOffsets[] = {
+ {-63, 3}, {-48, 40}, {-33, 58},
+ { 0, 65}, { 40, 53}, { 56, 27},
+ { 63, 0}, {-30, 26}, { 0, 30},
+ { 26, 25}
+};
+
+SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
+}
+
+AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
+
+ SetUpdateHandler(&AsCommonCarShadow::update);
+ createShadowSurface(shadowSurface, 211, 147, 100);
+ updateShadow();
+}
+
+void AsCommonCarShadow::update() {
+ updateShadow();
+ AnimatedSprite::update();
+}
+
+void AsCommonCarShadow::updateShadow() {
+ if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
+ uint32 fileHash = _asCar->getCurrAnimFileHash();
+ if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
+ fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
+ fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
+ fileHash == 0xF46A0324) {
+ startAnimation(fileHash, _asCar->getFrameIndex(), -1);
+ _newStickFrameIndex = _asCar->getFrameIndex();
+ }
+ _animFileHash = fileHash;
+ }
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ if (!_asCar->getVisible()) {
+ startAnimation(0x1209E09F, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
+}
+
+AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
+
+ SetUpdateHandler(&AsCommonCarConnectorShadow::update);
+ createShadowSurface1(shadowSurface, 0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsCommonCarConnectorShadow::update() {
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ AnimatedSprite::update();
+}
+
+AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ SetUpdateHandler(&AsCommonCarTrackShadow::update);
+ createShadowSurface1(shadowSurface, 0x0759129C, 100);
+ startAnimation(0x0759129C, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+}
+
+void AsCommonCarTrackShadow::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekInside);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekInsideReturn);
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2700_sprites.h b/engines/neverhood/modules/module2700_sprites.h
new file mode 100644
index 0000000000..394ba896a1
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsCommonTrackShadowBackground : public StaticSprite {
+public:
+ SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
+};
+
+class AsCommonCarShadow : public AnimatedSprite {
+public:
+ AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ AnimatedSprite *_asCar;
+ uint32 _animFileHash;
+ void update();
+ void updateShadow();
+};
+
+class AsCommonCarConnectorShadow : public AnimatedSprite {
+public:
+ AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ Sprite *_asCar;
+ void update();
+};
+
+class AsCommonCarTrackShadow : public AnimatedSprite {
+public:
+ AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
+protected:
+ Sprite *_asCar;
+ void update();
+};
+
+class KmScene2732 : public Klaymen {
+public:
+ KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2700_SPRITES_H */
diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp
index 183de8e6b2..d51515ce81 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -20,13 +20,15 @@
*
*/
-#include "neverhood/modules/module2800.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1700.h"
-#include "neverhood/modules/module2200.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1700_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2800.h"
+#include "neverhood/modules/module2800_sprites.h"
namespace Neverhood {
@@ -36,7 +38,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) {
@@ -58,7 +60,7 @@ Module2800::~Module2800() {
}
void Module2800::createScene(int sceneNum, int which) {
- debug("Module2800::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2800::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -206,6 +208,8 @@ void Module2800::createScene(int sceneNum, int which) {
break;
case 1001:
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
+ _musicResource->stop(0);
+ _currentMusicFileHash = 0;
createSmackerScene(0x00800801, true, true, false);
break;
}
@@ -224,7 +228,7 @@ void Module2800::updateScene() {
_musicResource = NULL;
}
_currentMusicFileHash = 0;
- }
+ }
if (_moduleResult == 1) {
createScene(2, 0);
} else if (_moduleResult == 2) {
@@ -251,7 +255,7 @@ void Module2800::updateScene() {
createScene(9, 0);
else if (_moduleResult == 5)
createScene(25, 0);
- else
+ else
createScene(0, 1);
break;
case 3:
@@ -294,31 +298,9 @@ void Module2800::updateScene() {
createScene(8, 0);
else if (_moduleResult == 6)
createScene(2, 6);
- else if (_moduleResult == 11)
- createScene(12, 0);
- else if (_moduleResult == 12)
- createScene(13, 0);
- else if (_moduleResult == 13)
- createScene(14, 0);
- else if (_moduleResult == 14)
- createScene(15, 0);
- else if (_moduleResult == 15)
- createScene(16, 0);
- else if (_moduleResult == 16)
- createScene(17, 0);
- else if (_moduleResult == 17)
- createScene(18, 0);
- else if (_moduleResult == 18)
- createScene(19, 0);
- else if (_moduleResult == 19)
- createScene(20, 0);
- else if (_moduleResult == 20)
- createScene(21, 0);
- else if (_moduleResult == 21)
- createScene(22, 0);
- else if (_moduleResult == 22)
- createScene(23, 0);
- else
+ else if (_moduleResult >= 11 && _moduleResult <= 22)
+ createScene(_moduleResult + 1, 0);
+ else
createScene(2, 4);
break;
case 10:
@@ -331,44 +313,22 @@ void Module2800::updateScene() {
createScene(26, 0);
else if (_moduleResult == 3)
createScene(9, 5);
- else
+ else
createScene(9, 1);
break;
case 12:
- createScene(9, 11);
- break;
case 13:
- createScene(9, 12);
- break;
case 14:
- createScene(9, 13);
- break;
case 15:
- createScene(9, 14);
- break;
case 16:
- createScene(9, 15);
- break;
case 17:
- createScene(9, 16);
- break;
case 18:
- createScene(9, 17);
- break;
case 19:
- createScene(9, 18);
- break;
case 20:
- createScene(9, 19);
- break;
case 21:
- createScene(9, 20);
- break;
case 22:
- createScene(9, 21);
- break;
case 23:
- createScene(9, 22);
+ createScene(9, _sceneNum - 1);
break;
case 24:
createScene(9, 3);
@@ -396,12 +356,11 @@ void Module2800::updateScene() {
}
void Module2800::updateMusic(bool halfVolume) {
-
uint32 newMusicFileHash = _vm->_gameModule->getCurrRadioMusicFileHash();
if (!_musicResource)
_musicResource = new MusicResource(_vm);
-
+
if (newMusicFileHash != _currentMusicFileHash) {
_currentMusicFileHash = newMusicFileHash;
if (_currentMusicFileHash != 0) {
@@ -469,7 +428,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 +439,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 +450,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 +462,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 +524,7 @@ Scene2802::~Scene2802() {
}
setGlobalVar(V_CURR_RADIO_MUSIC_INDEX, _currRadioMusicIndex);
}
-
+
void Scene2802::update() {
int prevTuneStatus = _currTuneStatus;
uint prevRadioMusicIndex = _currRadioMusicIndex;
@@ -577,7 +536,7 @@ void Scene2802::update() {
_currTuneStatus = 3;
else if (_currTuneStatus == 4)
_currTuneStatus = 6;
-
+
switch (_currTuneStatus) {
case 2:
if (_currRadioMusicIndex < 90)
@@ -607,24 +566,20 @@ void Scene2802::update() {
} else
_currTuneStatus = 0;
break;
-
+
}
if (prevRadioMusicIndex != _currRadioMusicIndex)
_smackerPlayer->gotoFrame(_currRadioMusicIndex);
-
+
if (prevTuneStatus != _currTuneStatus)
changeTuneStatus(prevTuneStatus, _currTuneStatus);
-
- //DEBUG>>>
- //debug("_currRadioMusicIndex = %d; V_GOOD_RADIO_MUSIC_INDEX = %d", _currRadioMusicIndex, getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX));
- //DEBUG<<<
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) {
@@ -691,157 +646,9 @@ void Scene2802::changeTuneStatus(int prevTuneStatus, int newTuneStatus) {
}
-AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2),
- _isPulled(false), _isBusy(false) {
-
- createSurface(1010, 28, 379);
- SetUpdateHandler(&AnimatedSprite::update);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- _x = x;
- _y = y;
- stIdle();
-}
-
-uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
- sendMessage(_parentScene, 0x480F, 0);
- playSound(0, 0x4E1CA4A0);
- }
- break;
- case 0x480F:
- stPulled();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2803LightCord::stPulled() {
- _isBusy = false;
- _isPulled = true;
- startAnimation(_fileHash2, 0, -1);
- SetMessageHandler(&AsScene2803LightCord::hmPulled);
- NextState(&AsScene2803LightCord::stIdle);
-}
-
-void AsScene2803LightCord::stIdle() {
- _isPulled = false;
- startAnimation(_fileHash1, 0, -1);
- SetMessageHandler(&AsScene2803LightCord::handleMessage);
-}
-
-void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
- _fileHash1 = fileHash1;
- _fileHash2 = fileHash2;
- if (_isPulled) {
- startAnimation(_fileHash2, _currFrameIndex, -1);
- _isBusy = true;
- } else {
- startAnimation(_fileHash1, 0, -1);
- }
-}
-
-AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2)
- : AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) {
-
- createSurface1(fileHash1, 100);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2803TestTubeOne::handleMessage);
- _x = 529;
- _y = 326;
-}
-
-uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- if (param.asInteger())
- startAnimation(_fileHash2, 0, -1);
- else
- startAnimation(_fileHash1, 0, -1);
- break;
- }
- return messageResult;
-}
-
-AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- SetMessageHandler(&AsScene2803Rope::handleMessage);
- startAnimation(0x9D098C23, 35, 53);
- NextState(&AsScene2803Rope::stReleased);
- _x = x;
- _y = -276;
-}
-
-uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x9D098C23, 50, -1);
- SetMessageHandler(&AsScene2803Rope::hmReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-void AsScene2803Rope::stReleased() {
- startAnimation(0x8258A030, 0, 1);
- NextState(&AsScene2803Rope::stHide);
-}
-
-void AsScene2803Rope::stHide() {
- stopAnimation();
- setVisible(false);
-}
-
Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(0) {
-
+
static const uint32 kScene2803FileHashes1[] = {
0,
0x081000F1,
@@ -858,20 +665,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 {
@@ -879,13 +686,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);
@@ -900,7 +707,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;
@@ -910,12 +717,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();
@@ -1116,7 +923,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh
static const uint32 kScene2803SmallFileHashes2[] = {
0, 0x286800D4, 0x286806D4, 0x28680AD4
};
-
+
SetMessageHandler(&Scene2803Small::handleMessage);
loadDataResource(0x81120132);
@@ -1164,7 +971,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);
@@ -1354,379 +1161,6 @@ void Scene2803Small::updatePaletteArea(bool instantly) {
_palette->startFadeToPalette(instantly ? 0 : 12);
}
-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);
- SetMessageHandler(&SsScene2804RedButton::handleMessage);
- loadSound(0, 0x44241240);
-}
-
-void SsScene2804RedButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_parentScene->isWorking()) {
- playSound(0);
- setVisible(true);
- _countdown = 4;
- sendMessage(_parentScene, 0x2000, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- SetMessageHandler(&SsScene2804LightCoil::handleMessage);
-}
-
-uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- setVisible(true);
- updatePosition();
- messageResult = 1;
- break;
- case 0x2003:
- setVisible(false);
- updatePosition();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- SetMessageHandler(&SsScene2804LightTarget::handleMessage);
-}
-
-uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- setVisible(true);
- updatePosition();
- messageResult = 1;
- break;
- case 0x2005:
- setVisible(false);
- updatePosition();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- loadSound(0, 0xCB36BA54);
-}
-
-void SsScene2804Flash::show() {
- setVisible(true);
- updatePosition();
- playSound(0);
-}
-
-SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
-}
-
-AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex)
- : AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) {
-
- static const NPoint kAsScene2804CrystalWavesPoints[] = {
- {323, 245},
- {387, 76},
- {454, 260},
- {527, 70}
- };
-
- _x = kAsScene2804CrystalWavesPoints[crystalIndex].x;
- _y = kAsScene2804CrystalWavesPoints[crystalIndex].y;
- createSurface1(0x840C41F0, 1200);
- if (crystalIndex & 1)
- setDoDeltaY(1);
- setVisible(false);
- _needRefresh = true;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene2804CrystalWaves::show() {
- setVisible(true);
- startAnimation(0x840C41F0, 0, -1);
-}
-
-void AsScene2804CrystalWaves::hide() {
- setVisible(false);
- stopAnimation();
-}
-
-static const int16 kAsScene2804CrystalFrameNums[] = {
- 0, 6, 2, 8, 1, 10, 0, 0
-};
-
-static const uint32 kAsScene2804CrystalFileHashes[] = {
- 0x000540B0,
- 0x001280D0,
- 0x003D0010,
- 0x00620190,
- 0x00DC0290
-};
-
-AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex)
- : AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) {
-
- static const NPoint kAsScene2804CrystalPoints[] = {
- {204, 196},
- {272, 316},
- {334, 206},
- {410, 334},
- {470, 180}
- };
-
- _colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex);
- _isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0;
- if (_isLightOn) {
- _x = kAsScene2804CrystalPoints[crystalIndex].x;
- _y = kAsScene2804CrystalPoints[crystalIndex].y;
- createSurface1(0x108DFB12, 1200);
- startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1);
- _needRefresh = true;
- _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
- } else {
- _x = 320;
- _y = 240;
- createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200);
- startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1);
- setVisible(false);
- _needRefresh = true;
- _newStickFrameIndex = _colorNum;
- }
- loadSound(0, 0x725294D4);
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene2804Crystal::show() {
- if (!_isLightOn) {
- setVisible(true);
- _isShowing = true;
- if (_asCrystalWaves)
- _asCrystalWaves->show();
- playSound(0);
- }
-}
-
-void AsScene2804Crystal::hide() {
- if (!_isLightOn) {
- setVisible(false);
- _isShowing = false;
- if (_asCrystalWaves)
- _asCrystalWaves->hide();
- }
-}
-
-void AsScene2804Crystal::activate() {
- if (!_isShowing) {
- int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum];
- _colorNum++;
- if (_colorNum >= 6)
- _colorNum = 0;
- if (_isLightOn) {
- startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]);
- _playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum;
- _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
- } else {
- startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1);
- _newStickFrameIndex = _colorNum;
- }
- setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum);
- }
-}
-
-SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex)
- : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) {
-
- static const uint32 kSsScene2804CrystalButtonFileHashes1[] = {
- 0x911101B0,
- 0x22226001,
- 0x4444A362,
- 0x888925A4,
- 0x11122829
- };
-
- static const uint32 kSsScene2804CrystalButtonFileHashes2[] = {
- 0xB500A1A0,
- 0x6A012021,
- 0xD4022322,
- 0xA8042525,
- 0x5008292B
- };
-
- loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex],
- kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44045140);
- SetUpdateHandler(&SsScene2804CrystalButton::update);
- SetMessageHandler(&SsScene2804CrystalButton::handleMessage);
-}
-
-void SsScene2804CrystalButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_parentScene->isWorking()) {
- playSound(0);
- setVisible(true);
- _countdown = 4;
- _asCrystal->activate();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody)
- : AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) {
-
- createSurface1(0x00494891, 1000);
- _x = 125;
- _y = 184;
- setVisible(false);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
- loadSound(0, 0x6352F051);
- _vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094);
- SetUpdateHandler(&AsScene2804BeamCoil::update);
- SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
-}
-
-AsScene2804BeamCoil::~AsScene2804BeamCoil() {
- _vm->_soundMan->deleteSoundGroup(0xC5EA0B28);
-}
-
-void AsScene2804BeamCoil::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- sendMessage(_parentScene, 0x2001, 0);
- }
-}
-
-uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- show();
- _countdown = 92;
- messageResult = 1;
- break;
- case 0x2003:
- hide();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene2804BeamCoil::show() {
- _ssBeamCoilBody->setVisible(true);
- setVisible(true);
- startAnimation(0x00494891, 0, -1);
- playSound(0);
- SetMessageHandler(&AsScene2804BeamCoil::hmBeaming);
- NextState(&AsScene2804BeamCoil::stBeaming);
-}
-
-void AsScene2804BeamCoil::hide() {
- stopAnimation();
- SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
- setVisible(false);
- _ssBeamCoilBody->setVisible(false);
- _vm->_soundMan->stopSound(0xEF56B094);
-}
-
-void AsScene2804BeamCoil::stBeaming() {
- startAnimation(0x00494891, 93, -1);
- NextState(&AsScene2804BeamCoil::stBeaming);
- _vm->_soundMan->playSoundLooping(0xEF56B094);
-}
-
-uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface1(0x03842000, 1000);
- _x = 475;
- _y = 278;
- setVisible(false);
- _needRefresh = true;
- updatePosition();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2804BeamTarget::handleMessage);
-}
-
-uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- setVisible(true);
- startAnimation(0x03842000, 0, -1);
- messageResult = 1;
- break;
- case 0x2005:
- setVisible(false);
- stopAnimation();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _countdown3(0),
_beamStatus(0), _isSolved(false), _isWorking(false) {
@@ -1754,7 +1188,7 @@ Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
_asTarget = insertSprite<AsScene2804BeamTarget>();
_ssFlash = insertSprite<SsScene2804Flash>();
}
-
+
_ssRedButton = insertSprite<SsScene2804RedButton>(this);
addCollisionSprite(_ssRedButton);
@@ -1801,7 +1235,7 @@ uint32 Scene2804::handleMessage(int messageNum, const MessageParam &param, Entit
void Scene2804::update() {
Scene::update();
-
+
if (_countdown1 != 0 && (--_countdown1) == 0) {
leaveScene(0);
}
@@ -1840,7 +1274,7 @@ void Scene2804::update() {
Scene2805::Scene2805(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
-
+
SetMessageHandler(&Scene2805::handleMessage);
setBackground(0x08021E04);
@@ -1896,53 +1330,23 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- createSurface1(0x04211490, 1200);
- _x = 378;
- _y = 423;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2806Spew::handleMessage);
- setDoDeltaX(1);
- setVisible(false);
-}
-
-uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- playSound(0, 0x48640244);
- startAnimation(0x04211490, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
Sprite *tempSprite;
- which = 3;
-
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;
@@ -1957,7 +1361,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();
@@ -2033,7 +1437,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;
@@ -2042,12 +1446,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) {
@@ -2117,267 +1521,6 @@ static const uint32 kClass428FileHashes[] = {
0x40800711
};
-static const int kClass428Countdowns1[] = {
- 18, 16, 10, 0
-};
-
-static const int kClass428Countdowns2[] = {
- 9, 9, 8, 8, 5, 5, 0, 0
-};
-
-static const uint32 kClass490FileHashes[] = {
- 0x08100071,
- 0x24084215,
- 0x18980A10
-};
-
-static const int16 kClass490FrameIndices1[] = {
- 0, 8, 15, 19
-};
-
-static const int16 kClass490FrameIndices2[] = {
- 0, 4, 8, 11, 15, 17, 19, 0
-};
-
-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);
- SetMessageHandler(&SsScene2808Dispenser::handleMessage);
-}
-
-void SsScene2808Dispenser::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2000, _testTubeIndex);
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void SsScene2808Dispenser::startCountdown(int index) {
- setVisible(true);
- updatePosition();
- if (_testTubeSetNum == 0) {
- _countdown = kClass428Countdowns1[index];
- } else {
- _countdown = kClass428Countdowns2[index];
- }
-}
-
-AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser)
- : AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) {
-
- if (testTubeSetNum == 0) {
- _x = 504;
- _y = 278;
- } else {
- setDoDeltaX(1);
- _x = 136;
- _y = 278;
- }
-
- createSurface1(kClass490FileHashes[testTubeIndex], 1100);
-
- if (testTubeSetNum == 0) {
- loadSound(0, 0x30809E2D);
- loadSound(1, 0x72811E2D);
- loadSound(2, 0x78B01625);
- } else {
- loadSound(3, 0x70A41E0C);
- loadSound(4, 0x50205E2D);
- loadSound(5, 0xF8621E2D);
- loadSound(6, 0xF1A03C2D);
- 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) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- fill();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene2808TestTube::fill() {
- if ((int)_fillLevel < _testTubeSetNum * 3 + 3) {
- if (_testTubeSetNum == 0) {
- playSound(_fillLevel);
- setVisible(true);
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]);
- _newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1];
- } else {
- playSound(3 + _fillLevel);
- setVisible(true);
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]);
- _newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1];
- }
- _ssDispenser->startCountdown(_fillLevel);
- _fillLevel++;
- }
-}
-
-void AsScene2808TestTube::flush() {
- if (_fillLevel != 0) {
- if (_testTubeSetNum == 0) {
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1);
- } else {
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1);
- }
- _newStickFrameIndex = 0;
- _playBackwards = true;
- setVisible(true);
- }
-}
-
-AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
- : AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) {
-
- loadSound(0, 0xE18D1F30);
- _x = 320;
- _y = 240;
- if (_testTubeSetNum == 1)
- setDoDeltaX(1);
- createSurface1(0x040900D0, 1300);
- startAnimation(0x040900D0, 0, -1);
- _needRefresh = true;
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2808Handle::handleMessage);
- AnimatedSprite::updatePosition();
-}
-
-uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isActivated) {
- sendMessage(_parentScene, 0x2001, 0);
- playSound(0);
- activate();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2808Handle::activate() {
- startAnimation(0x040900D0, 0, -1);
- SetMessageHandler(&AsScene2808Handle::hmActivating);
- NextState(&AsScene2808Handle::stActivated);
- _isActivated = true;
- _newStickFrameIndex = -1;
-}
-
-void AsScene2808Handle::stActivated() {
- stopAnimation();
- sendMessage(_parentScene, 0x2002, 0);
-}
-
-AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) {
-
- if (testTubeSetNum == 0) {
- _x = 312;
- _y = 444;
- } else {
- _x = 328;
- _y = 444;
- }
- createSurface1(0xB8414818, 1200);
- startAnimation(0xB8414818, 0, -1);
- setVisible(false);
- _newStickFrameIndex = 0;
- _needRefresh = true;
- loadSound(0, 0x6389B652);
- SetUpdateHandler(&AnimatedSprite::update);
- AnimatedSprite::updatePosition();
-}
-
-uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2808Flow::start() {
- startAnimation(0xB8414818, 0, -1);
- setVisible(true);
- SetMessageHandler(&AsScene2808Flow::hmFlowing);
- NextState(&AsScene2808Flow::stKeepFlowing);
- playSound(0);
-}
-
-void AsScene2808Flow::stKeepFlowing() {
- startAnimation(0xB8414818, 1, -1);
- NextState(&AsScene2808Flow::stKeepFlowing);
-}
-
-AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum)
- : AnimatedSprite(vm, 800), _countdown(1) {
-
- _x = 320;
- _y = 240;
- if (testTubeSetNum == 1)
- setDoDeltaX(1);
- createSurface1(0x804C2404, 800);
- SetUpdateHandler(&AsScene2808LightEffect::update);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
-}
-
-void AsScene2808LightEffect::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1);
- startAnimation(0x804C2404, frameIndex, frameIndex);
- updateAnim();
- updatePosition();
- _countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1;
- }
-}
-
Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _testTubeSetNum(which), _leaveResult(0), _isFlowing(false) {
@@ -2387,7 +1530,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
_vm->gameModule()->initTestTubes1Puzzle();
else
_vm->gameModule()->initTestTubes2Puzzle();
-
+
SetMessageHandler(&Scene2808::handleMessage);
SetUpdateHandler(&Scene2808::update);
@@ -2406,7 +1549,7 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
_asTestTubes[testTubeIndex] = insertSprite<AsScene2808TestTube>(which, testTubeIndex, ssDispenser);
addCollisionSprite(_asTestTubes[testTubeIndex]);
}
-
+
insertScreenMouse(kScene2808FileHashes2[which]);
}
@@ -2445,18 +1588,6 @@ uint32 Scene2808::handleMessage(int messageNum, const MessageParam &param, Entit
}
void Scene2808::update() {
-
- // DEBUG>>> Show correct values
- #if 1
- debug("---------------");
- if (_testTubeSetNum == 0)
- debug("%03d %03d %03d", getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2));
- else
- debug("%03d %03d %03d", getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2));
- debug("%03d %03d %03d", _asTestTubes[0]->getFillLevel(), _asTestTubes[1]->getFillLevel(), _asTestTubes[2]->getFillLevel());
- #endif
- // DEBUG<<<
-
Scene::update();
if (_countdown != 0 && (--_countdown) == 0) {
leaveScene(_leaveResult);
@@ -2484,45 +1615,17 @@ bool Scene2808::isAnyTestTubeFilled() {
_asTestTubes[2]->getFillLevel() > 0;
}
-AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2809Spew::handleMessage);
- createSurface1(0x04211490, 1200);
- _x = 262;
- _y = 423;
- setDoDeltaX(0);
- setVisible(false);
-}
-
-uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- playSound(0, 0x48640244);
- startAnimation(0x04211490, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
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);
@@ -2553,7 +1656,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);
@@ -2628,35 +1731,7 @@ void Scene2809::findClosestPoint() {
_pointIndex = index;
_palette->addPalette(kScene2809PaletteFileHashes[index], 0, 64, 0);
}
-
-}
-
-AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2810Rope::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- _x = x;
- _y = -276;
- startAnimation(0x9D098C23, 35, 53);
-}
-uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x9D098C23, 35, 53);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
}
Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)
@@ -2665,7 +1740,7 @@ Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)
Sprite *tempSprite;
SetMessageHandler(&Scene2810::handleMessage);
-
+
setBackground(0x26508804);
setPalette(0x26508804);
insertScreenMouse(0x0880026D);
@@ -2701,7 +1776,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);
@@ -2880,112 +1955,17 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface1(0x20DA08A0, 1200);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2812Winch::handleMessage);
- setVisible(false);
- _x = 280;
- _y = 184;
-}
-
-AsScene2812Winch::~AsScene2812Winch() {
- _vm->_soundMan->deleteSoundGroup(0x00B000E2);
-}
-
-uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- startAnimation(0x20DA08A0, 0, -1);
- setVisible(true);
- _vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
- _vm->_soundMan->playSoundLooping(0xC874EE6C);
- break;
- case 0x3002:
- startAnimation(0x20DA08A0, 7, -1);
- break;
- }
- return messageResult;
-}
-
-AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2812Rope::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- startAnimation(0xAE080551, 0, -1);
- _x = 334;
- _y = 201;
-}
-
-uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4806:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- stRopingDown();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2812Rope::stRopingDown() {
- sendMessage(_parentScene, 0x4806, 0);
- startAnimation(0x9D098C23, 0, -1);
- SetMessageHandler(&AsScene2812Rope::hmRopingDown);
-}
-
-AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 0x805D0029, 100, 320, 240) {
-
- SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
- _newStickFrameIndex = 0;
-}
-
-uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- startAnimation(0x805D0029, 0, -1);
- playSound(0, 0xEA005F40);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return messageResult;
-}
-
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);
@@ -3001,7 +1981,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);
@@ -3041,9 +2021,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() {
@@ -3138,7 +2118,7 @@ Scene2822::Scene2822(NeverhoodEngine *vm, Module *parentModule, int which)
addBackground(_background);
_background->getSurface()->getDrawRect().y = -10;
setPalette(0xD542022E);
- insertPuzzleMouse(0x0028D089, 20, 620);
+ insertPuzzleMouse(0x2022AD5C, 20, 620);
_ssButton = insertStaticSprite(0x1A4D4120, 1100);
_ssButton->setVisible(false);
loadSound(2, 0x19044E72);
@@ -3158,7 +2138,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..26e44bc543 100644
--- a/engines/neverhood/modules/module2800.h
+++ b/engines/neverhood/modules/module2800.h
@@ -70,38 +70,7 @@ protected:
void changeTuneStatus(int prevTuneStatus, int newTuneStatus);
};
-class AsScene2803LightCord : public AnimatedSprite {
-public:
- AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
- void stPulled();
- void stIdle();
- void setFileHashes(uint32 fileHash1, uint32 fileHash2);
-protected:
- Scene *_parentScene;
- uint32 _fileHash1, _fileHash2;
- bool _isPulled, _isBusy;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPulled(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2803TestTubeOne : public AnimatedSprite {
-public:
- AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2);
-protected:
- uint32 _fileHash1, _fileHash2;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2803Rope : public AnimatedSprite {
-public:
- AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmReleased(int messageNum, const MessageParam &param, Entity *sender);
- void stReleased();
- void stHide();
-};
+class AsScene2803LightCord;
class Scene2803 : public Scene {
public:
@@ -158,101 +127,8 @@ protected:
void updatePaletteArea(bool instantly);
};
-class Scene2804;
-
-class SsScene2804RedButton : public StaticSprite {
-public:
- SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene);
-protected:
- Scene2804 *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804LightCoil : public StaticSprite {
-public:
- SsScene2804LightCoil(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804BeamCoilBody : public StaticSprite {
-public:
- SsScene2804BeamCoilBody(NeverhoodEngine *vm);
-};
-
-class SsScene2804LightTarget : public StaticSprite {
-public:
- SsScene2804LightTarget(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804Flash : public StaticSprite {
-public:
- SsScene2804Flash(NeverhoodEngine *vm);
- void show();
-};
-
-class AsScene2804CrystalWaves : public AnimatedSprite {
-public:
- AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex);
- void show();
- void hide();
-protected:
- uint _crystalIndex;
-};
-
-class AsScene2804Crystal : public AnimatedSprite {
-public:
- AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex);
- void show();
- void hide();
- void activate();
- int16 getColorNum() const { return _colorNum; }
-protected:
- AsScene2804CrystalWaves *_asCrystalWaves;
- uint _crystalIndex;
- int16 _colorNum;
- bool _isLightOn;
- bool _isShowing;
-};
-
-class SsScene2804CrystalButton : public StaticSprite {
-public:
- SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex);
-protected:
- Scene2804 *_parentScene;
- AsScene2804Crystal *_asCrystal;
- uint _crystalIndex;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2804BeamCoil : public AnimatedSprite {
-public:
- AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody);
- virtual ~AsScene2804BeamCoil();
-protected:
- Scene *_parentScene;
- SsScene2804BeamCoilBody *_ssBeamCoilBody;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void show();
- void hide();
- void stBeaming();
- uint32 hmBeaming(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2804BeamTarget : public AnimatedSprite {
-public:
- AsScene2804BeamTarget(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene2804Flash;
+class AsScene2804Crystal;
class Scene2804 : public Scene {
public:
@@ -284,13 +160,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2806Spew : public AnimatedSprite {
-public:
- AsScene2806Spew(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2806 : public Scene {
public:
Scene2806(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -315,63 +184,8 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2808Dispenser : public StaticSprite {
-public:
- SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex);
- void startCountdown(int index);
-protected:
- Scene *_parentScene;
- int _countdown;
- int _testTubeSetNum, _testTubeIndex;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808TestTube : public AnimatedSprite {
-public:
- AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser);
- void fill();
- void flush();
- uint32 getFillLevel() const { return _fillLevel; }
-protected:
- SsScene2808Dispenser *_ssDispenser;
- int _testTubeSetNum;
- uint32 _fillLevel;
- int _testTubeIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808Handle : public AnimatedSprite {
-public:
- AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
- void activate();
- void stActivated();
-protected:
- Scene *_parentScene;
- int _testTubeSetNum;
- bool _isActivated;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmActivating(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808Flow : public AnimatedSprite {
-public:
- AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
- void start();
- void stKeepFlowing();
-protected:
- Scene *_parentScene;
- int _testTubeSetNum;
- uint32 hmFlowing(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808LightEffect : public AnimatedSprite {
-public:
- AsScene2808LightEffect(NeverhoodEngine *vm, int which);
-protected:
- int _countdown;
- void update();
-};
+class AsScene2808Flow;
+class AsScene2808TestTube;
class Scene2808 : public Scene {
public:
@@ -389,13 +203,6 @@ protected:
bool isAnyTestTubeFilled();
};
-class AsScene2809Spew : public AnimatedSprite {
-public:
- AsScene2809Spew(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2809 : public Scene {
public:
Scene2809(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -408,19 +215,11 @@ protected:
Sprite *_sprite3;
Sprite *_sprite4;
Sprite *_asSpew;
- void update();
+ void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void findClosestPoint();
};
-class AsScene2810Rope : public AnimatedSprite {
-public:
- AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2810 : public Scene {
public:
Scene2810(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -440,31 +239,6 @@ protected:
void insertKlaymenLadder();
};
-class AsScene2812Winch : public AnimatedSprite {
-public:
- AsScene2812Winch(NeverhoodEngine *vm);
- virtual ~AsScene2812Winch();
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2812Rope : public AnimatedSprite {
-public:
- AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRopingDown(int messageNum, const MessageParam &param, Entity *sender);
- void stRopingDown();
-};
-
-class AsScene2812TrapDoor : public AnimatedSprite {
-public:
- AsScene2812TrapDoor(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2812 : public Scene {
public:
Scene2812(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp
new file mode 100644
index 0000000000..a600c55dd3
--- /dev/null
+++ b/engines/neverhood/modules/module2800_sprites.cpp
@@ -0,0 +1,1626 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2800.h"
+#include "neverhood/modules/module2800_sprites.h"
+
+namespace Neverhood {
+
+AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2),
+ _isPulled(false), _isBusy(false) {
+
+ createSurface(1010, 28, 379);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ _x = x;
+ _y = y;
+ stIdle();
+}
+
+uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
+ sendMessage(_parentScene, 0x480F, 0);
+ playSound(0, 0x4E1CA4A0);
+ }
+ break;
+ case 0x480F:
+ stPulled();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2803LightCord::stPulled() {
+ _isBusy = false;
+ _isPulled = true;
+ startAnimation(_fileHash2, 0, -1);
+ SetMessageHandler(&AsScene2803LightCord::hmPulled);
+ NextState(&AsScene2803LightCord::stIdle);
+}
+
+void AsScene2803LightCord::stIdle() {
+ _isPulled = false;
+ startAnimation(_fileHash1, 0, -1);
+ SetMessageHandler(&AsScene2803LightCord::handleMessage);
+}
+
+void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
+ _fileHash1 = fileHash1;
+ _fileHash2 = fileHash2;
+ if (_isPulled) {
+ startAnimation(_fileHash2, _currFrameIndex, -1);
+ _isBusy = true;
+ } else {
+ startAnimation(_fileHash1, 0, -1);
+ }
+}
+
+AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2)
+ : AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) {
+
+ createSurface1(fileHash1, 100);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2803TestTubeOne::handleMessage);
+ _x = 529;
+ _y = 326;
+}
+
+uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (param.asInteger())
+ startAnimation(_fileHash2, 0, -1);
+ else
+ startAnimation(_fileHash1, 0, -1);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ SetMessageHandler(&AsScene2803Rope::handleMessage);
+ startAnimation(0x9D098C23, 35, 53);
+ NextState(&AsScene2803Rope::stReleased);
+ _x = x;
+ _y = -276;
+}
+
+uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x9D098C23, 50, -1);
+ SetMessageHandler(&AsScene2803Rope::hmReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2803Rope::stReleased() {
+ startAnimation(0x8258A030, 0, 1);
+ NextState(&AsScene2803Rope::stHide);
+}
+
+void AsScene2803Rope::stHide() {
+ stopAnimation();
+ setVisible(false);
+}
+
+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);
+ SetMessageHandler(&SsScene2804RedButton::handleMessage);
+ loadSound(0, 0x44241240);
+}
+
+void SsScene2804RedButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_parentScene->isWorking()) {
+ playSound(0);
+ setVisible(true);
+ _countdown = 4;
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ SetMessageHandler(&SsScene2804LightCoil::handleMessage);
+}
+
+uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ setVisible(true);
+ updatePosition();
+ messageResult = 1;
+ break;
+ case 0x2003:
+ setVisible(false);
+ updatePosition();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ SetMessageHandler(&SsScene2804LightTarget::handleMessage);
+}
+
+uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ setVisible(true);
+ updatePosition();
+ messageResult = 1;
+ break;
+ case 0x2005:
+ setVisible(false);
+ updatePosition();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ loadSound(0, 0xCB36BA54);
+}
+
+void SsScene2804Flash::show() {
+ setVisible(true);
+ updatePosition();
+ playSound(0);
+}
+
+SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+}
+
+AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex)
+ : AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) {
+
+ static const NPoint kAsScene2804CrystalWavesPoints[] = {
+ {323, 245},
+ {387, 76},
+ {454, 260},
+ {527, 70}
+ };
+
+ _x = kAsScene2804CrystalWavesPoints[crystalIndex].x;
+ _y = kAsScene2804CrystalWavesPoints[crystalIndex].y;
+ createSurface1(0x840C41F0, 1200);
+ if (crystalIndex & 1)
+ setDoDeltaY(1);
+ setVisible(false);
+ _needRefresh = true;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene2804CrystalWaves::show() {
+ setVisible(true);
+ startAnimation(0x840C41F0, 0, -1);
+}
+
+void AsScene2804CrystalWaves::hide() {
+ setVisible(false);
+ stopAnimation();
+}
+
+static const int16 kAsScene2804CrystalFrameNums[] = {
+ 0, 6, 2, 8, 1, 10, 0, 0
+};
+
+static const uint32 kAsScene2804CrystalFileHashes[] = {
+ 0x000540B0,
+ 0x001280D0,
+ 0x003D0010,
+ 0x00620190,
+ 0x00DC0290
+};
+
+AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex)
+ : AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) {
+
+ static const NPoint kAsScene2804CrystalPoints[] = {
+ {204, 196},
+ {272, 316},
+ {334, 206},
+ {410, 334},
+ {470, 180}
+ };
+
+ _colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex);
+ _isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0;
+ if (_isLightOn) {
+ _x = kAsScene2804CrystalPoints[crystalIndex].x;
+ _y = kAsScene2804CrystalPoints[crystalIndex].y;
+ createSurface1(0x108DFB12, 1200);
+ startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1);
+ _needRefresh = true;
+ _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
+ } else {
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200);
+ startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1);
+ setVisible(false);
+ _needRefresh = true;
+ _newStickFrameIndex = _colorNum;
+ }
+ loadSound(0, 0x725294D4);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene2804Crystal::show() {
+ if (!_isLightOn) {
+ setVisible(true);
+ _isShowing = true;
+ if (_asCrystalWaves)
+ _asCrystalWaves->show();
+ playSound(0);
+ }
+}
+
+void AsScene2804Crystal::hide() {
+ if (!_isLightOn) {
+ setVisible(false);
+ _isShowing = false;
+ if (_asCrystalWaves)
+ _asCrystalWaves->hide();
+ }
+}
+
+void AsScene2804Crystal::activate() {
+ if (!_isShowing) {
+ int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum];
+ _colorNum++;
+ if (_colorNum >= 6)
+ _colorNum = 0;
+ if (_isLightOn) {
+ startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]);
+ _playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum;
+ _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
+ } else {
+ startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1);
+ _newStickFrameIndex = _colorNum;
+ }
+ setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum);
+ }
+}
+
+SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex)
+ : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) {
+
+ static const uint32 kSsScene2804CrystalButtonFileHashes1[] = {
+ 0x911101B0,
+ 0x22226001,
+ 0x4444A362,
+ 0x888925A4,
+ 0x11122829
+ };
+
+ static const uint32 kSsScene2804CrystalButtonFileHashes2[] = {
+ 0xB500A1A0,
+ 0x6A012021,
+ 0xD4022322,
+ 0xA8042525,
+ 0x5008292B
+ };
+
+ loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex],
+ kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44045140);
+ SetUpdateHandler(&SsScene2804CrystalButton::update);
+ SetMessageHandler(&SsScene2804CrystalButton::handleMessage);
+}
+
+void SsScene2804CrystalButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_parentScene->isWorking()) {
+ playSound(0);
+ setVisible(true);
+ _countdown = 4;
+ _asCrystal->activate();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody)
+ : AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) {
+
+ createSurface1(0x00494891, 1000);
+ _x = 125;
+ _y = 184;
+ setVisible(false);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+ loadSound(0, 0x6352F051);
+ _vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094);
+ SetUpdateHandler(&AsScene2804BeamCoil::update);
+ SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
+}
+
+AsScene2804BeamCoil::~AsScene2804BeamCoil() {
+ _vm->_soundMan->deleteSoundGroup(0xC5EA0B28);
+}
+
+void AsScene2804BeamCoil::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ sendMessage(_parentScene, 0x2001, 0);
+ }
+}
+
+uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ show();
+ _countdown = 92;
+ messageResult = 1;
+ break;
+ case 0x2003:
+ hide();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2804BeamCoil::show() {
+ _ssBeamCoilBody->setVisible(true);
+ setVisible(true);
+ startAnimation(0x00494891, 0, -1);
+ playSound(0);
+ SetMessageHandler(&AsScene2804BeamCoil::hmBeaming);
+ NextState(&AsScene2804BeamCoil::stBeaming);
+}
+
+void AsScene2804BeamCoil::hide() {
+ stopAnimation();
+ SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
+ setVisible(false);
+ _ssBeamCoilBody->setVisible(false);
+ _vm->_soundMan->stopSound(0xEF56B094);
+}
+
+void AsScene2804BeamCoil::stBeaming() {
+ startAnimation(0x00494891, 93, -1);
+ NextState(&AsScene2804BeamCoil::stBeaming);
+ _vm->_soundMan->playSoundLooping(0xEF56B094);
+}
+
+uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface1(0x03842000, 1000);
+ _x = 475;
+ _y = 278;
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2804BeamTarget::handleMessage);
+}
+
+uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ setVisible(true);
+ startAnimation(0x03842000, 0, -1);
+ messageResult = 1;
+ break;
+ case 0x2005:
+ setVisible(false);
+ stopAnimation();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ createSurface1(0x04211490, 1200);
+ _x = 378;
+ _y = 423;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2806Spew::handleMessage);
+ setDoDeltaX(1);
+ setVisible(false);
+}
+
+uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ playSound(0, 0x48640244);
+ startAnimation(0x04211490, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+static const uint32 kScene2808FileHashes1[] = {
+ 0x90B0392,
+ 0x90B0192
+};
+
+static const uint32 kScene2808FileHashes2[] = {
+ 0xB0396098,
+ 0xB0196098
+};
+
+static const uint32 kClass428FileHashes[] = {
+ 0x140022CA,
+ 0x4C30A602,
+ 0xB1633402,
+ 0x12982135,
+ 0x0540B728,
+ 0x002A81E3,
+ 0x08982841,
+ 0x10982841,
+ 0x20982841,
+ 0x40982841,
+ 0x80982841,
+ 0x40800711
+};
+
+static const int kClass428Countdowns1[] = {
+ 18, 16, 10, 0
+};
+
+static const int kClass428Countdowns2[] = {
+ 9, 9, 8, 8, 5, 5, 0, 0
+};
+
+static const uint32 kClass490FileHashes[] = {
+ 0x08100071,
+ 0x24084215,
+ 0x18980A10
+};
+
+static const int16 kClass490FrameIndices1[] = {
+ 0, 8, 15, 19
+};
+
+static const int16 kClass490FrameIndices2[] = {
+ 0, 4, 8, 11, 15, 17, 19, 0
+};
+
+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);
+ SetMessageHandler(&SsScene2808Dispenser::handleMessage);
+}
+
+void SsScene2808Dispenser::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2000, _testTubeIndex);
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2808Dispenser::startCountdown(int index) {
+ setVisible(true);
+ updatePosition();
+ if (_testTubeSetNum == 0) {
+ _countdown = kClass428Countdowns1[index];
+ } else {
+ _countdown = kClass428Countdowns2[index];
+ }
+}
+
+AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser)
+ : AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) {
+
+ if (testTubeSetNum == 0) {
+ _x = 504;
+ _y = 278;
+ } else {
+ setDoDeltaX(1);
+ _x = 136;
+ _y = 278;
+ }
+
+ createSurface1(kClass490FileHashes[testTubeIndex], 1100);
+
+ if (testTubeSetNum == 0) {
+ loadSound(0, 0x30809E2D);
+ loadSound(1, 0x72811E2D);
+ loadSound(2, 0x78B01625);
+ } else {
+ loadSound(3, 0x70A41E0C);
+ loadSound(4, 0x50205E2D);
+ loadSound(5, 0xF8621E2D);
+ loadSound(6, 0xF1A03C2D);
+ 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) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ fill();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808TestTube::fill() {
+ if ((int)_fillLevel < _testTubeSetNum * 3 + 3) {
+ if (_testTubeSetNum == 0) {
+ playSound(_fillLevel);
+ setVisible(true);
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]);
+ _newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1];
+ } else {
+ playSound(3 + _fillLevel);
+ setVisible(true);
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]);
+ _newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1];
+ }
+ _ssDispenser->startCountdown(_fillLevel);
+ _fillLevel++;
+ }
+}
+
+void AsScene2808TestTube::flush() {
+ if (_fillLevel != 0) {
+ if (_testTubeSetNum == 0) {
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1);
+ } else {
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1);
+ }
+ _newStickFrameIndex = 0;
+ _playBackwards = true;
+ setVisible(true);
+ }
+}
+
+AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
+ : AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) {
+
+ loadSound(0, 0xE18D1F30);
+ _x = 320;
+ _y = 240;
+ if (_testTubeSetNum == 1)
+ setDoDeltaX(1);
+ createSurface1(0x040900D0, 1300);
+ startAnimation(0x040900D0, 0, -1);
+ _needRefresh = true;
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2808Handle::handleMessage);
+ AnimatedSprite::updatePosition();
+}
+
+uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isActivated) {
+ sendMessage(_parentScene, 0x2001, 0);
+ playSound(0);
+ activate();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808Handle::activate() {
+ startAnimation(0x040900D0, 0, -1);
+ SetMessageHandler(&AsScene2808Handle::hmActivating);
+ NextState(&AsScene2808Handle::stActivated);
+ _isActivated = true;
+ _newStickFrameIndex = -1;
+}
+
+void AsScene2808Handle::stActivated() {
+ stopAnimation();
+ sendMessage(_parentScene, 0x2002, 0);
+}
+
+AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) {
+
+ if (testTubeSetNum == 0) {
+ _x = 312;
+ _y = 444;
+ } else {
+ _x = 328;
+ _y = 444;
+ }
+ createSurface1(0xB8414818, 1200);
+ startAnimation(0xB8414818, 0, -1);
+ setVisible(false);
+ _newStickFrameIndex = 0;
+ _needRefresh = true;
+ loadSound(0, 0x6389B652);
+ SetUpdateHandler(&AnimatedSprite::update);
+ AnimatedSprite::updatePosition();
+}
+
+uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808Flow::start() {
+ startAnimation(0xB8414818, 0, -1);
+ setVisible(true);
+ SetMessageHandler(&AsScene2808Flow::hmFlowing);
+ NextState(&AsScene2808Flow::stKeepFlowing);
+ playSound(0);
+}
+
+void AsScene2808Flow::stKeepFlowing() {
+ startAnimation(0xB8414818, 1, -1);
+ NextState(&AsScene2808Flow::stKeepFlowing);
+}
+
+AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum)
+ : AnimatedSprite(vm, 800), _countdown(1) {
+
+ _x = 320;
+ _y = 240;
+ if (testTubeSetNum == 1)
+ setDoDeltaX(1);
+ createSurface1(0x804C2404, 800);
+ SetUpdateHandler(&AsScene2808LightEffect::update);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+}
+
+void AsScene2808LightEffect::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1);
+ startAnimation(0x804C2404, frameIndex, frameIndex);
+ updateAnim();
+ updatePosition();
+ _countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1;
+ }
+}
+
+AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2809Spew::handleMessage);
+ createSurface1(0x04211490, 1200);
+ _x = 262;
+ _y = 423;
+ setDoDeltaX(0);
+ setVisible(false);
+}
+
+uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ playSound(0, 0x48640244);
+ startAnimation(0x04211490, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2810Rope::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ _x = x;
+ _y = -276;
+ startAnimation(0x9D098C23, 35, 53);
+}
+
+uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x9D098C23, 35, 53);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface1(0x20DA08A0, 1200);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Winch::handleMessage);
+ setVisible(false);
+ _x = 280;
+ _y = 184;
+}
+
+AsScene2812Winch::~AsScene2812Winch() {
+ _vm->_soundMan->deleteSoundGroup(0x00B000E2);
+}
+
+uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x20DA08A0, 0, -1);
+ setVisible(true);
+ _vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
+ _vm->_soundMan->playSoundLooping(0xC874EE6C);
+ break;
+ case 0x3002:
+ startAnimation(0x20DA08A0, 7, -1);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Rope::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ startAnimation(0xAE080551, 0, -1);
+ _x = 334;
+ _y = 201;
+}
+
+uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4806:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ stRopingDown();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2812Rope::stRopingDown() {
+ sendMessage(_parentScene, 0x4806, 0);
+ startAnimation(0x9D098C23, 0, -1);
+ SetMessageHandler(&AsScene2812Rope::hmRopingDown);
+}
+
+AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 0x805D0029, 100, 320, 240) {
+
+ SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
+ _newStickFrameIndex = 0;
+}
+
+uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x805D0029, 0, -1);
+ playSound(0, 0xEA005F40);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x00900849);
+}
+
+uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else
+ GotoState(&Klaymen::stWonderAboutHalf);
+ break;
+ case 0x482E:
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4838:
+ GotoState(&Klaymen::stJumpToGrabRelease);
+ break;
+ }
+ return 0;
+}
+
+KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x81120132);
+}
+
+uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stWalkToFront2Small);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stTurnToBackWalkSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4830:
+ GotoState(&KmScene2803Small::stShrink);
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene2803Small::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x80C110B5)
+ sendMessage(_parentScene, 0x482A, 0);
+ else if (param.asInteger() == 0x33288344)
+ playSound(2, 0x10688664);
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2803Small::stShrink() {
+ _busyStatus = 0;
+ _acceptInput = false;
+ playSound(0, 0x4C69EA53);
+ startAnimation(0x1AE88904, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2803Small::hmShrink);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xDE284B74);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD82A4094);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x98182003);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(440, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x1830009A);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(226, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 5)
+ GotoState(&Klaymen::stTurnToUseExt);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4805:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrabFall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2002, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2800_sprites.h b/engines/neverhood/modules/module2800_sprites.h
new file mode 100644
index 0000000000..91f26d7849
--- /dev/null
+++ b/engines/neverhood/modules/module2800_sprites.h
@@ -0,0 +1,337 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2800_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2800_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene2803LightCord : public AnimatedSprite {
+public:
+ AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
+ void stPulled();
+ void stIdle();
+ void setFileHashes(uint32 fileHash1, uint32 fileHash2);
+protected:
+ Scene *_parentScene;
+ uint32 _fileHash1, _fileHash2;
+ bool _isPulled, _isBusy;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPulled(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2803TestTubeOne : public AnimatedSprite {
+public:
+ AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2);
+protected:
+ uint32 _fileHash1, _fileHash2;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2803Rope : public AnimatedSprite {
+public:
+ AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmReleased(int messageNum, const MessageParam &param, Entity *sender);
+ void stReleased();
+ void stHide();
+};
+
+class Scene2804;
+
+class SsScene2804RedButton : public StaticSprite {
+public:
+ SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene);
+protected:
+ Scene2804 *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804LightCoil : public StaticSprite {
+public:
+ SsScene2804LightCoil(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804BeamCoilBody : public StaticSprite {
+public:
+ SsScene2804BeamCoilBody(NeverhoodEngine *vm);
+};
+
+class SsScene2804LightTarget : public StaticSprite {
+public:
+ SsScene2804LightTarget(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804Flash : public StaticSprite {
+public:
+ SsScene2804Flash(NeverhoodEngine *vm);
+ void show();
+};
+
+class AsScene2804CrystalWaves : public AnimatedSprite {
+public:
+ AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex);
+ void show();
+ void hide();
+protected:
+ uint _crystalIndex;
+};
+
+class AsScene2804Crystal : public AnimatedSprite {
+public:
+ AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex);
+ void show();
+ void hide();
+ void activate();
+ int16 getColorNum() const { return _colorNum; }
+protected:
+ AsScene2804CrystalWaves *_asCrystalWaves;
+ uint _crystalIndex;
+ int16 _colorNum;
+ bool _isLightOn;
+ bool _isShowing;
+};
+
+class SsScene2804CrystalButton : public StaticSprite {
+public:
+ SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex);
+protected:
+ Scene2804 *_parentScene;
+ AsScene2804Crystal *_asCrystal;
+ uint _crystalIndex;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2804BeamCoil : public AnimatedSprite {
+public:
+ AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody);
+ virtual ~AsScene2804BeamCoil();
+protected:
+ Scene *_parentScene;
+ SsScene2804BeamCoilBody *_ssBeamCoilBody;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void show();
+ void hide();
+ void stBeaming();
+ uint32 hmBeaming(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2804BeamTarget : public AnimatedSprite {
+public:
+ AsScene2804BeamTarget(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2806Spew : public AnimatedSprite {
+public:
+ AsScene2806Spew(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2808Dispenser : public StaticSprite {
+public:
+ SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex);
+ void startCountdown(int index);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ int _testTubeSetNum, _testTubeIndex;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808TestTube : public AnimatedSprite {
+public:
+ AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser);
+ void fill();
+ void flush();
+ uint32 getFillLevel() const { return _fillLevel; }
+protected:
+ SsScene2808Dispenser *_ssDispenser;
+ int _testTubeSetNum;
+ uint32 _fillLevel;
+ int _testTubeIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808Handle : public AnimatedSprite {
+public:
+ AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
+ void activate();
+ void stActivated();
+protected:
+ Scene *_parentScene;
+ int _testTubeSetNum;
+ bool _isActivated;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmActivating(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808Flow : public AnimatedSprite {
+public:
+ AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
+ void start();
+ void stKeepFlowing();
+protected:
+ Scene *_parentScene;
+ int _testTubeSetNum;
+ uint32 hmFlowing(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808LightEffect : public AnimatedSprite {
+public:
+ AsScene2808LightEffect(NeverhoodEngine *vm, int which);
+protected:
+ int _countdown;
+ void update();
+};
+
+class AsScene2809Spew : public AnimatedSprite {
+public:
+ AsScene2809Spew(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2810Rope : public AnimatedSprite {
+public:
+ AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2812Winch : public AnimatedSprite {
+public:
+ AsScene2812Winch(NeverhoodEngine *vm);
+ virtual ~AsScene2812Winch();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2812Rope : public AnimatedSprite {
+public:
+ AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRopingDown(int messageNum, const MessageParam &param, Entity *sender);
+ void stRopingDown();
+};
+
+class AsScene2812TrapDoor : public AnimatedSprite {
+public:
+ AsScene2812TrapDoor(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2801 : public Klaymen {
+public:
+ KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803 : public Klaymen {
+public:
+ KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803Small : public Klaymen {
+public:
+ KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stShrink();
+ uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2805 : public Klaymen {
+public:
+ KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2806 : public Klaymen {
+public:
+ KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2809 : public Klaymen {
+public:
+ KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810Small : public Klaymen {
+public:
+ KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810 : public Klaymen {
+public:
+ KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2812 : public Klaymen {
+public:
+ KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2800_SPRITES_H */
diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp
index bd95b82f4c..bb0b69f35d 100644
--- a/engines/neverhood/modules/module2900.cpp
+++ b/engines/neverhood/modules/module2900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module2900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module2900_sprites.h"
#include "neverhood/modules/module1100.h"
#include "neverhood/modules/module1300.h"
#include "neverhood/modules/module1700.h"
@@ -36,13 +36,13 @@ Module2900::Module2900(NeverhoodEngine *vm, Module *parentModule, int which)
if (which >= 0)
setGlobalVar(V_TELEPORTER_WHICH, which);
-
+
createScene(0, 0);
}
void Module2900::createScene(int sceneNum, int which) {
- debug("Module2900::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module2900::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
case 0:
@@ -141,211 +141,6 @@ static const uint32 kScene2901FileHashes2[] = {
0x08030029
};
-static const uint32 kSsScene2901LocationButtonFileHashes[] = {
- 0x2311326A,
- 0x212323AC,
- 0x10098138,
- 0x25213167,
- 0x1119A363,
- 0x94452612,
- 0x39464212,
- 0x01860450,
- 0x53002104,
- 0x58E68412,
- 0x18600300,
- 0xB650A890,
- 0x2452A7C4,
- 0xA0232748,
- 0x08862B02,
- 0x2491E648,
- 0x0010EB46,
- 0x214C8A11,
- 0x16A31921,
- 0x0AC33A00,
- 0x238028AA,
- 0x26737A21,
- 0x063039A8,
- 0x51286C60,
- 0x464006B4,
- 0x42242538,
- 0x20716010,
- 0x4A2000AE,
- 0x225124A6,
- 0x28E82E45,
- 0x58652C04,
- 0xC82210A4,
- 0x62A84060,
- 0xC0693CB4,
- 0x22212C64,
- 0x5034EA71
-};
-
-static const NPoint kSsScene2901LocationButtonPoints[] = {
- {525, 120}, {576, 149}, {587, 205},
- {538, 232}, {484, 205}, {479, 153}
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
- 0x03136246,
- 0x2106216E,
- 0x4025A13A,
- 0x21816927,
- 0x110B2202,
- 0xCC0522B2,
- 0x3CC24258,
- 0x59C600F0,
- 0x534A2480,
- 0x50E61019,
- 0x34400150,
- 0x225BA090,
- 0xB059AFC4,
- 0xE093A741,
- 0x0086BF09,
- 0x3281E760,
- 0xA048AB42,
- 0x20649C01,
- 0x14611904,
- 0x26E33850,
- 0x23A52A68,
- 0xA2733024,
- 0x10203880,
- 0x1B2DE860,
- 0x0644A6EC,
- 0x426E20BC,
- 0x80292014,
- 0x4360B02E,
- 0x22742664,
- 0x98682705,
- 0x0925B82C,
- 0x5C2918A4,
- 0xD2284920,
- 0x41083CA6,
- 0x6824A864,
- 0x50266B10
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
- 0x43C46D4C,
- 0x43C4AD4C,
- 0x43C52D4C,
- 0x43C62D4C,
- 0x43C02D4C,
- 0x43CC2D4C
-};
-
-static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
- 0x3081BD3A,
- 0xD3443003,
- 0x0786A320,
- 0xE3A22029,
- 0x61611814,
- 0x425848E2
-};
-
-static const uint32 kSsScene2901BigButtonFileHashes[] = {
- 0x010D7748,
- 0x9D02019A,
- 0x351A2F43,
- 0x448138E5,
- 0x02788CF0,
- 0x71718024
-};
-
-SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
- : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
-
- const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
-
- loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
- _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
- setVisible(false);
- loadSound(0, 0x440430C0);
- SetUpdateHandler(&SsScene2901LocationButton::update);
- SetMessageHandler(&SsScene2901LocationButton::handleMessage);
-}
-
-void SsScene2901LocationButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- sendMessage(_parentScene, 0x2001, _index);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
- : StaticSprite(vm, 900), _index(index) {
-
- loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
- setVisible(false);
- loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
-}
-
-void SsScene2901LocationButtonLight::show() {
- playSound(0);
- setVisible(true);
- updatePosition();
-}
-
-void SsScene2901LocationButtonLight::hide() {
- setVisible(false);
- updatePosition();
-}
-
-SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
- : StaticSprite(vm, 900) {
-
- loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
-}
-
-SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
- : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
-
- loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
- _collisionBounds.set(62, 94, 322, 350);
- setVisible(false);
- loadSound(0, 0xF3D420C8);
- SetUpdateHandler(&SsScene2901BigButton::update);
- SetMessageHandler(&SsScene2901BigButton::handleMessage);
-}
-
-void SsScene2901BigButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _currLocationButtonNum(which), _selectedButtonNum(which),
_currWhirlButtonNum(0), _prevWhirlButtonNum(0), _countdown1(1), _skipCountdown(0), _blinkOn(0) {
@@ -361,7 +156,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 +164,7 @@ Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
_ssLocationButtonLights[i] = insertSprite<SsScene2901LocationButtonLight>(_currLocationButtonNum, i);
}
}
-
+
if (_isButton2Broken)
insertSprite<SsScene2901BrokenButton>(_currLocationButtonNum);
@@ -377,10 +172,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..5f6ed29a12 100644
--- a/engines/neverhood/modules/module2900.h
+++ b/engines/neverhood/modules/module2900.h
@@ -42,41 +42,7 @@ protected:
void updateMusic(bool halfVolume);
};
-class SsScene2901LocationButton : public StaticSprite {
-public:
- SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
-protected:
- Scene *_parentScene;
- uint _index;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2901LocationButtonLight : public StaticSprite {
-public:
- SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
- void show();
- void hide();
-protected:
- uint _index;
-};
-
-class SsScene2901BrokenButton : public StaticSprite {
-public:
- SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
-};
-
-class SsScene2901BigButton : public StaticSprite {
-public:
- SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
-protected:
- Scene *_parentScene;
- int _which;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene2901LocationButtonLight;
class Scene2901 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2900_sprites.cpp b/engines/neverhood/modules/module2900_sprites.cpp
new file mode 100644
index 0000000000..59780b33a0
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.cpp
@@ -0,0 +1,232 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2900_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene2901LocationButtonFileHashes[] = {
+ 0x2311326A,
+ 0x212323AC,
+ 0x10098138,
+ 0x25213167,
+ 0x1119A363,
+ 0x94452612,
+ 0x39464212,
+ 0x01860450,
+ 0x53002104,
+ 0x58E68412,
+ 0x18600300,
+ 0xB650A890,
+ 0x2452A7C4,
+ 0xA0232748,
+ 0x08862B02,
+ 0x2491E648,
+ 0x0010EB46,
+ 0x214C8A11,
+ 0x16A31921,
+ 0x0AC33A00,
+ 0x238028AA,
+ 0x26737A21,
+ 0x063039A8,
+ 0x51286C60,
+ 0x464006B4,
+ 0x42242538,
+ 0x20716010,
+ 0x4A2000AE,
+ 0x225124A6,
+ 0x28E82E45,
+ 0x58652C04,
+ 0xC82210A4,
+ 0x62A84060,
+ 0xC0693CB4,
+ 0x22212C64,
+ 0x5034EA71
+};
+
+static const NPoint kSsScene2901LocationButtonPoints[] = {
+ {525, 120}, {576, 149}, {587, 205},
+ {538, 232}, {484, 205}, {479, 153}
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
+ 0x03136246,
+ 0x2106216E,
+ 0x4025A13A,
+ 0x21816927,
+ 0x110B2202,
+ 0xCC0522B2,
+ 0x3CC24258,
+ 0x59C600F0,
+ 0x534A2480,
+ 0x50E61019,
+ 0x34400150,
+ 0x225BA090,
+ 0xB059AFC4,
+ 0xE093A741,
+ 0x0086BF09,
+ 0x3281E760,
+ 0xA048AB42,
+ 0x20649C01,
+ 0x14611904,
+ 0x26E33850,
+ 0x23A52A68,
+ 0xA2733024,
+ 0x10203880,
+ 0x1B2DE860,
+ 0x0644A6EC,
+ 0x426E20BC,
+ 0x80292014,
+ 0x4360B02E,
+ 0x22742664,
+ 0x98682705,
+ 0x0925B82C,
+ 0x5C2918A4,
+ 0xD2284920,
+ 0x41083CA6,
+ 0x6824A864,
+ 0x50266B10
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
+ 0x43C46D4C,
+ 0x43C4AD4C,
+ 0x43C52D4C,
+ 0x43C62D4C,
+ 0x43C02D4C,
+ 0x43CC2D4C
+};
+
+static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
+ 0x3081BD3A,
+ 0xD3443003,
+ 0x0786A320,
+ 0xE3A22029,
+ 0x61611814,
+ 0x425848E2
+};
+
+static const uint32 kSsScene2901BigButtonFileHashes[] = {
+ 0x010D7748,
+ 0x9D02019A,
+ 0x351A2F43,
+ 0x448138E5,
+ 0x02788CF0,
+ 0x71718024
+};
+
+SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
+
+ const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
+
+ loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
+ _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
+ setVisible(false);
+ loadSound(0, 0x440430C0);
+ SetUpdateHandler(&SsScene2901LocationButton::update);
+ SetMessageHandler(&SsScene2901LocationButton::handleMessage);
+}
+
+void SsScene2901LocationButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ sendMessage(_parentScene, 0x2001, _index);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
+ : StaticSprite(vm, 900), _index(index) {
+
+ loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
+ setVisible(false);
+ loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
+}
+
+void SsScene2901LocationButtonLight::show() {
+ playSound(0);
+ setVisible(true);
+ updatePosition();
+}
+
+void SsScene2901LocationButtonLight::hide() {
+ setVisible(false);
+ updatePosition();
+}
+
+SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
+}
+
+SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
+
+ loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
+ _collisionBounds.set(62, 94, 322, 350);
+ setVisible(false);
+ loadSound(0, 0xF3D420C8);
+ SetUpdateHandler(&SsScene2901BigButton::update);
+ SetMessageHandler(&SsScene2901BigButton::handleMessage);
+}
+
+void SsScene2901BigButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2900_sprites.h b/engines/neverhood/modules/module2900_sprites.h
new file mode 100644
index 0000000000..9f7df502e1
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2900
+
+class SsScene2901LocationButton : public StaticSprite {
+public:
+ SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
+protected:
+ Scene *_parentScene;
+ uint _index;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2901LocationButtonLight : public StaticSprite {
+public:
+ SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
+ void show();
+ void hide();
+protected:
+ uint _index;
+};
+
+class SsScene2901BrokenButton : public StaticSprite {
+public:
+ SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
+};
+
+class SsScene2901BigButton : public StaticSprite {
+public:
+ SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
+protected:
+ Scene *_parentScene;
+ int _which;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2900_SPRITES_H */
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index 2bdb9f0497..a12776611e 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module3000.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -39,7 +40,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);
@@ -49,7 +50,7 @@ Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
_isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
- if (_isWallBroken) {
+ if (!_isWallBroken) {
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
}
@@ -73,15 +74,16 @@ Module3000::~Module3000() {
}
void Module3000::createScene(int sceneNum, int which) {
- static const byte kNavigationTypes05[] = {3, 0};
+ static const byte kNavigationTypes05[] = {2, 0};
static const byte kNavigationTypes06[] = {5};
- debug("Module3000::createScene(%d, %d)", sceneNum, which);
+ debug(1, "Module3000::createScene(%d, %d)", sceneNum, which);
_vm->gameState().sceneNum = sceneNum;
+ _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
switch (_vm->gameState().sceneNum) {
case 1:
if (!getGlobalVar(V_BOLT_DOOR_OPEN)) {
createNavigationScene(0x004B7C80, which);
- } else if (getGlobalVar(V_WALL_BROKEN)) {
+ } else if (_isWallBroken) {
createNavigationScene(0x004B7CE0, which);
} else {
createNavigationScene(0x004B7CB0, which);
@@ -89,11 +91,11 @@ void Module3000::createScene(int sceneNum, int which) {
break;
case 2:
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
- if (_isWallBroken) {
+ if (!_isWallBroken) {
_soundVolume = 90;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 90);
}
- if (getGlobalVar(V_WALL_BROKEN)) {
+ if (_isWallBroken) {
createNavigationScene(0x004B7D58, which);
} else {
createNavigationScene(0x004B7D10, which);
@@ -102,7 +104,7 @@ void Module3000::createScene(int sceneNum, int which) {
case 3:
if (getGlobalVar(V_STAIRS_DOWN))
createNavigationScene(0x004B7E60, which);
- else if (getGlobalVar(V_WALL_BROKEN))
+ else if (_isWallBroken)
createNavigationScene(0x004B7DA0, which);
else
createNavigationScene(0x004B7E00, which);
@@ -150,12 +152,12 @@ void Module3000::createScene(int sceneNum, int which) {
// NOTE: Newly introduced sceneNums
case 1001:
if (!getGlobalVar(V_BOLT_DOOR_OPEN))
- if (getGlobalVar(V_WALL_BROKEN))
+ if (_isWallBroken)
createSmackerScene(0x00940021, true, true, false);
else
createSmackerScene(0x01140021, true, true, false);
else
- if (getGlobalVar(V_WALL_BROKEN))
+ if (_isWallBroken)
createSmackerScene(0x001011B1, true, true, false);
else
createSmackerScene(0x001021B1, true, true, false);
@@ -299,7 +301,7 @@ void Module3000::updateScene() {
} else if (frameNumber == 10) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
_soundVolume = 40;
else
@@ -313,7 +315,7 @@ void Module3000::updateScene() {
if (navigationScene()->isWalkingForward()) {
uint32 frameNumber = navigationScene()->getFrameNumber();
int navigationIndex = navigationScene()->getNavigationIndex();
- if (_isWallBroken && _soundVolume > 1 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume > 1 && frameNumber % 2) {
_soundVolume--;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
}
@@ -338,7 +340,7 @@ void Module3000::updateScene() {
if (frameNumber == 40) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
_soundVolume = 40;
else
@@ -414,355 +416,18 @@ static const uint32 kScene3009CannonActionVideos[] = {
0x240A1101 // 14 Lower the cannon
};
-static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
- 0x618827A0,
- 0xB1A92322
-};
-
-static const uint32 kSsScene3009TargetLineFileHashes[] = {
- 0x4011018C,
- 0x15086623
-};
-
-static const NPoint kAsScene3009SymbolPoints[] = {
- {289, 338},
- {285, 375},
- {284, 419},
- {456, 372},
- {498, 372},
- {541, 372}
-};
-
-static const uint32 kAsScene3009SymbolFileHashes[] = {
- 0x24542582,
- 0x1CD61D96
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
- 0x24016060,
- 0x21216221,
- 0x486160A0,
- 0x42216422,
- 0x90A16120,
- 0x84216824,
- 0x08017029,
- 0x08217029,
- 0x10014032,
- 0x10214032,
- 0x20012004,
- 0x20212004
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
- 0x40092024,
- 0x01636002,
- 0x8071E028,
- 0x02A56064,
- 0x00806031,
- 0x052960A8,
- 0x0A116130,
- 0x0A316130,
- 0x14216200,
- 0x14016200,
- 0x28416460,
- 0x28616460
-};
-
-SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
-
- loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- SetUpdateHandler(&SsScene3009FireCannonButton::update);
- SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
- loadSound(0, 0x3901B44F);
-}
-
-void SsScene3009FireCannonButton::update() {
- updatePosition();
- if (_isClicked && !isSoundPlaying(0)) {
- sendMessage(_parentScene, 0x2000, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isClicked && !_parentScene->isTurning()) {
- _isClicked = true;
- setVisible(true);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400), _blinkCountdown(0) {
-
- loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- if (getGlobalVar(V_ROBOT_HIT))
- hide();
- else
- startBlinking();
- SetUpdateHandler(&SsScene3009SymbolEdges::update);
-}
-
-void SsScene3009SymbolEdges::update() {
- if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
- if (_blinkToggle) {
- setVisible(true);
- } else {
- setVisible(false);
- }
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = !_blinkToggle;
- }
-}
-
-void SsScene3009SymbolEdges::show() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::hide() {
- setVisible(false);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::startBlinking() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = true;
-}
-
-SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400) {
-
- loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- setVisible(false);
-}
-
-void SsScene3009TargetLine::show() {
- setVisible(true);
- updatePosition();
-}
-
-SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
- : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
-
- _incrDecr = _index % 2;
-
- createSurface(1200, 33, 31);
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
- _drawOffset.set(0, 0, 33, 31);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
- _needRefresh = true;
-
- SetUpdateHandler(&SsScene3009SymbolArrow::update);
- SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
- loadSound(0, 0x2C852206);
-}
-
-void SsScene3009SymbolArrow::hide() {
- _enabled = false;
- setVisible(false);
-}
-
-void SsScene3009SymbolArrow::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
- }
-}
-
-uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled && _countdown == 0) {
- _countdown = 2;
- loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
- playSound(0);
- sendMessage(_asSymbol, 0x2005, _incrDecr);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = 300;
- _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
- createSurface1(0xC2463913, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
-}
-
-void AsScene3009VerticalIndicator::show() {
- startAnimation(0xC2463913, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2002, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
- _y = 150;
- createSurface1(0xC0C12954, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
- if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
- _x = 280;
- }
-}
-
-uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2004, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009HorizontalIndicator::suMoveLeft() {
- _x -= 6;
- if (_x < 92) {
- SetSpriteUpdate(NULL);
- _x = 92;
- }
-}
-
-void AsScene3009HorizontalIndicator::suMoveRight() {
- _x += 6;
- if (_x > 533) {
- SetSpriteUpdate(NULL);
- _x = 533;
- }
-}
-
-void AsScene3009HorizontalIndicator::show() {
- startAnimation(0xC0C12954, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-void AsScene3009HorizontalIndicator::stMoveLeft() {
- _x = 533;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
-}
-
-void AsScene3009HorizontalIndicator::stMoveRight() {
- _x = 330;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
-}
-
-AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
-
- _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
-
- _x = kAsScene3009SymbolPoints[_symbolPosition].x;
- _y = kAsScene3009SymbolPoints[_symbolPosition].y;
- createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- _needRefresh = true;
- updatePosition();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009Symbol::handleMessage);
- _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
- _parentScene->addCollisionSprite(_ssArrowPrev);
- _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
- _parentScene->addCollisionSprite(_ssArrowNext);
-}
-
-uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2005:
- if (param.asInteger()) {
- if (_symbolIndex == 11)
- _symbolIndex = 0;
- else
- _symbolIndex++;
- } else {
- if (_symbolIndex == 0)
- _symbolIndex = 11;
- else
- _symbolIndex--;
- }
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
- if (_symbolPosition / 3 == 0) {
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- sendMessage(_parentScene, 0x2003, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009Symbol::hide() {
- _ssArrowPrev->hide();
- _ssArrowNext->hide();
-}
-
Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
- : Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
+ : 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);
@@ -786,8 +451,8 @@ Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
}
}
- _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009CannonScopeVideos[_cannonTargetStatus], false, _keepVideo));
- _smackerPlayer->setDrawPos(89, 37);
+ _cannonSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009CannonScopeVideos[_cannonTargetStatus], false, _keepVideo));
+ _cannonSmackerPlayer->setDrawPos(89, 37);
_palette->usePalette(); // Use it again since the SmackerPlayer overrides the usage
insertStaticSprite(0x8540252C, 400);
@@ -807,42 +472,39 @@ Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene3009::handleMessage);
SetUpdateHandler(&Scene3009::update);
+}
- // DEBUG Enable to set the correct code
-#if 0
- for (int i = 0; i < 6; i++)
- setSubVar(VA_CURR_CANNON_SYMBOLS, i, _correctSymbols[i]);
- sendMessage(this, 0x2003, 0);
-#endif
+Scene3009::~Scene3009() {
+}
+void Scene3009::openSmacker(uint32 fileHash, bool keepLastFrame) {
+ _cannonSmackerPlayer->open(fileHash, keepLastFrame);
+ //_vm->_screen->setSmackerDecoder(_cannonSmackerPlayer->getSmackerDecoder());
+ _palette->usePalette();
}
void Scene3009::update() {
Scene::update();
-
- if (!_keepVideo && _smackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) {
+
+ if (!_keepVideo && _cannonSmackerPlayer->isDone() && _cannonTargetStatus <= kCTSCount) {
switch (_cannonTargetStatus) {
case kCTSNull:
case kCTSLowerCannon:
- _smackerPlayer->open(0x340A0049, true);
- _palette->usePalette();
+ openSmacker(0x340A0049, true);
_keepVideo = true;
break;
case kCTSRightRobotNoTarget:
- _smackerPlayer->open(0x0082080D, true);
- _palette->usePalette();
+ openSmacker(0x0082080D, true);
_keepVideo = true;
_isTurning = false;
break;
case kCTSRightRobotIsTarget:
- _smackerPlayer->open(0x0282080D, true);
- _palette->usePalette();
+ openSmacker(0x0282080D, true);
_keepVideo = true;
_isTurning = false;
break;
case kCTSRightNoRobot:
- _smackerPlayer->open(0x0882080D, true);
- _palette->usePalette();
+ openSmacker(0x0882080D, true);
_keepVideo = true;
_isTurning = false;
break;
@@ -851,12 +513,11 @@ void Scene3009::update() {
case kCTSLeftNoRobot:
if (_moveCannonLeftFirst) {
if (_cannonTargetStatus == kCTSLeftRobotNoTarget)
- _smackerPlayer->open(0x110A000F, false);
- else if (_cannonTargetStatus == kCTSLeftRobotIsTarget)
- _smackerPlayer->open(0x500B004F, false);
- else if (_cannonTargetStatus == kCTSLeftNoRobot)
- _smackerPlayer->open(0x100B010E, false);
- _palette->usePalette();
+ openSmacker(0x110A000F, false);
+ else if (_cannonTargetStatus == kCTSLeftRobotIsTarget)
+ openSmacker(0x500B004F, false);
+ else if (_cannonTargetStatus == kCTSLeftNoRobot)
+ openSmacker(0x100B010E, false);
_moveCannonLeftFirst = false;
_asHorizontalIndicator->stMoveLeft();
} else {
@@ -955,15 +616,14 @@ uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entit
// Cannon is at the right position
if (!getGlobalVar(V_ROBOT_TARGET)) {
_cannonTargetStatus = kCTSLeftRobotNoTarget;
- _smackerPlayer->open(0x108A000F, false);
+ openSmacker(0x108A000F, false);
} else if (!getGlobalVar(V_ROBOT_HIT)) {
_cannonTargetStatus = kCTSLeftRobotIsTarget;
- _smackerPlayer->open(0x500B002F, false);
+ openSmacker(0x500B002F, false);
} else {
_cannonTargetStatus = kCTSLeftNoRobot;
- _smackerPlayer->open(0x100B008E, false);
+ openSmacker(0x100B008E, false);
}
- _palette->usePalette();
_moveCannonLeftFirst = true;
_isTurning = true;
_keepVideo = false;
@@ -1019,217 +679,10 @@ static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
0x5000A7E8
};
-static const NPoint kAsScene3010DeadBoltPoints[] = {
- {550, 307},
- {564, 415},
- {560, 514}
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
- 0x181A0042,
- 0x580A08F2,
- 0x18420076
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
- 0x300E105A,
- 0x804E0052,
- 0x040E485A
-};
-
-SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
- : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
-
- _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
- createSurface(400, 88, 95);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- if (initDisabled)
- disableButton();
- else if (_buttonEnabled)
- _countdown1 = initCountdown * 12 + 1;
- loadSound(0, 0xF4217243);
- loadSound(1, 0x44049000);
- loadSound(2, 0x6408107E);
- SetUpdateHandler(&SsScene3010DeadBoltButton::update);
- SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
-}
-
-void SsScene3010DeadBoltButton::update() {
-
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- playSound(0);
- setVisible(false);
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- }
-
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- setVisible(true);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- }
-
-}
-
-uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_buttonLocked && _countdown1 == 0) {
- if (_buttonEnabled) {
- playSound(1);
- playSound(2);
- setVisible(true);
- _buttonLocked = true;
- sendMessage(_parentScene, 0x2000, _buttonIndex);
- } else {
- sendMessage(_parentScene, 0x2002, _buttonIndex);
- }
- _needRefresh = true;
- updatePosition();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void SsScene3010DeadBoltButton::disableButton() {
- _buttonLocked = true;
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- setVisible(true);
-}
-
-void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
-}
-
-void SsScene3010DeadBoltButton::setCountdown(int count) {
- _countdown2 = count * 18 + 1;
-}
-
-AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
- _unlocked(false), _locked(false), _countdown(0) {
-
- _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
- _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
-
- if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
- createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- loadSound(0, 0x46005BC4);
- } else {
- createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- loadSound(0, 0x420073DC);
- loadSound(1, 0x420073DC);
- }
-
- setVisible(false);
- stIdle();
- if (initUnlocked)
- unlock(true);
-
- _needRefresh = true;
- AnimatedSprite::updatePosition();
-
-}
-
-void AsScene3010DeadBolt::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- stDisabled();
- }
-}
-
-uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene3010DeadBolt::stIdle() {
- stopAnimation();
- SetUpdateHandler(&AsScene3010DeadBolt::update);
- SetMessageHandler(&Sprite::handleMessage);
- _locked = false;
-}
-
-void AsScene3010DeadBolt::unlock(bool skipAnim) {
- if (!_unlocked) {
- setVisible(true);
- if (skipAnim) {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- playSound(0);
- }
- _unlocked = true;
- loadSound(2, 0x4010C345);
- }
-}
-
-void AsScene3010DeadBolt::stIdleMessage() {
- stopAnimation();
- SetMessageHandler(&Sprite::handleMessage);
- sendMessage(_parentScene, 0x2001, _boltIndex);
-}
-
-void AsScene3010DeadBolt::lock() {
- if (!_locked) {
- _locked = true;
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- if (_soundToggle) {
- playSound(0);
- } else {
- playSound(1);
- }
- _soundToggle = !_soundToggle;
- }
-}
-
-void AsScene3010DeadBolt::setCountdown(int count) {
- _countdown = count * 18 + 1;
-}
-
-void AsScene3010DeadBolt::stDisabled() {
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- _playBackwards = true;
- playSound(2);
-}
-
-void AsScene3010DeadBolt::stDisabledMessage() {
- setVisible(false);
- sendMessage(_parentScene, 0x2003, _boltIndex);
-}
-
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
-
- int initCountdown = 0;
- // DEBUG Enable to activate all buttons
-#if 0
- setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[0], 1);
- setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[1], 1);
- setSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[2], 1);
-#endif
+ int initCountdown = 0;
setBackground(0x80802626);
setPalette(0x80802626);
@@ -1328,127 +781,6 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene3011
-
-static const uint32 kAsScene3011SymbolFileHashes[] = {
- 0x00C88050,
- 0x01488050,
- 0x02488050,
- 0x04488050,
- 0x08488050,
- 0x10488050,
- 0x20488050,
- 0x40488050,
- 0x80488050,
- 0x00488051,
- 0x00488052,
- 0x00488054,
- 0x008B0000,
- 0x008D0000,
- 0x00810000,
- 0x00990000,
- 0x00A90000,
- 0x00C90000,
- 0x00090000,
- 0x01890000,
- 0x02890000,
- 0x04890000,
- 0x08890000,
- 0x10890000
-};
-
-SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene3011Button::update);
- SetMessageHandler(&SsScene3011Button::handleMessage);
-}
-
-void SsScene3011Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- }
-}
-
-uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- StaticSprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- setVisible(true);
- _countdown = 4;
- sendMessage(_parentScene, 0x2000, 0);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
- : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
-
- if (_largeSymbol) {
- _x = 310;
- _y = 200;
- createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
- loadSound(0, 0x6052C60F);
- loadSound(1, 0x6890433B);
- } else {
- _symbolIndex = 12;
- _x = symbolIndex * 39 + 96;
- _y = 225;
- createSurface(1200, 41, 48);
- loadSound(0, 0x64428609);
- loadSound(1, 0x7080023B);
- }
- setVisible(false);
- _needRefresh = true;
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene3011Symbol::show(bool isNoisy) {
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
-void AsScene3011Symbol::hide() {
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene3011Symbol::stopSymbolSound() {
- if (_isNoisy) {
- stopSound(1);
- } else {
- stopSound(0);
- }
-}
-
-void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
- _symbolIndex = symbolIndex;
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _updateStatus(0), _buttonClicked(false), _currentSymbolIndex(0), _countdown(0) {
@@ -1457,7 +789,7 @@ Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene3011::handleMessage);
SetUpdateHandler(&Scene3011::update);
-
+
setBackground(0x92124A04);
setPalette(0xA4070114);
addEntity(_palette);
@@ -1469,12 +801,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 7634360d7c..a88dea513e 100644
--- a/engines/neverhood/modules/module3000.h
+++ b/engines/neverhood/modules/module3000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,98 +40,21 @@ protected:
void updateScene();
};
-// Scene3009
-
-class Scene3009;
-
-class SsScene3009FireCannonButton : public StaticSprite {
-public:
- SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
-protected:
- Scene3009 *_parentScene;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene3009SymbolEdges : public StaticSprite {
-public:
- SsScene3009SymbolEdges(NeverhoodEngine *vm, int index);
- void show();
- void hide();
- void startBlinking();
-protected:
- int _blinkCountdown;
- bool _blinkToggle;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene3009TargetLine : public StaticSprite {
-public:
- SsScene3009TargetLine(NeverhoodEngine *vm, int index);
- void show();
-};
-
-class SsScene3009SymbolArrow : public StaticSprite {
-public:
- SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
- void hide();
-protected:
- Sprite *_asSymbol;
- int _index;
- int _incrDecr;
- bool _enabled;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009VerticalIndicator : public AnimatedSprite {
-public:
- AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
- void show();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009HorizontalIndicator : public AnimatedSprite {
-public:
- AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
- void show();
- void stMoveLeft();
- void stMoveRight();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveLeft();
- void suMoveRight();
-};
-
-class AsScene3009Symbol : public AnimatedSprite {
-public:
- AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
- void hide();
-protected:
- Scene3009 *_parentScene;
- int _symbolPosition;
- uint32 _symbolIndex;
- SsScene3009SymbolArrow *_ssArrowPrev;
- SsScene3009SymbolArrow *_ssArrowNext;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene3009SymbolEdges;
+class SsScene3009TargetLine;
+class AsScene3009VerticalIndicator;
+class AsScene3009HorizontalIndicator;
+class AsScene3009Symbol;
class Scene3009 : public Scene {
public:
Scene3009(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Scene3009();
bool isTurning();
protected:
int _lockSymbolsPart1Countdown;
int _lockSymbolsPart2Countdown;
- SmackerPlayer *_smackerPlayer;
+ SmackerPlayer *_cannonSmackerPlayer;
Sprite *_ssFireCannonButton;
SsScene3009SymbolEdges *_ssSymbolEdges[2];
SsScene3009TargetLine *_ssTargetLines[2];
@@ -149,47 +71,11 @@ protected:
void playActionVideo();
bool isSymbolsPart1Solved();
bool isSymbolsPart2Solved();
+ void openSmacker(uint32 fileHash, bool keepLastFrame);
};
-// Scene3010
-
-class SsScene3010DeadBoltButton : public StaticSprite {
-public:
- SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
- void setCountdown(int count);
-protected:
- Scene *_parentScene;
- int _buttonIndex;
- bool _buttonEnabled;
- bool _buttonLocked;
- int _countdown1;
- int _countdown2;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void disableButton();
- void setSprite(uint32 fileHash);
-};
-
-class AsScene3010DeadBolt : public AnimatedSprite {
-public:
- AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
- void setCountdown(int count);
- void lock();
- void unlock(bool skipAnim);
-protected:
- Scene *_parentScene;
- int _boltIndex;
- int _countdown;
- bool _soundToggle;
- bool _unlocked;
- bool _locked;
- void update();
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stIdle();
- void stIdleMessage();
- void stDisabled();
- void stDisabledMessage();
-};
+class SsScene3010DeadBoltButton;
+class AsScene3010DeadBolt;
class Scene3010 : public Scene {
public:
@@ -206,31 +92,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene3011
-
-class SsScene3011Button : public StaticSprite {
-public:
- SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3011Symbol : public AnimatedSprite {
-public:
- AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
- void show(bool isNoisy);
- void hide();
- void stopSymbolSound();
- void change(int symbolIndex, bool isNoisy);
- int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
-protected:
- bool _largeSymbol;
- bool _isNoisy;
- int _symbolIndex;
-};
+class AsScene3011Symbol;
class Scene3011 : public Scene {
public:
@@ -242,7 +104,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/modules/module3000_sprites.cpp b/engines/neverhood/modules/module3000_sprites.cpp
new file mode 100644
index 0000000000..7d0162d7d0
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.cpp
@@ -0,0 +1,763 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+enum {
+ kCTSNull = 0,
+ kCTSBreakWall = 1,
+ kCTSWall = 2,
+ kCTSEmptyness = 3,
+ kCTSFireRobotNoTarget = 4,
+ kCTSFireRobotIsTarget = 5,
+ kCTSFireNoRobot = 6,
+ kCTSRaiseCannon = 7,
+ kCTSRightRobotNoTarget = 8,
+ kCTSRightRobotIsTarget = 9,
+ kCTSRightNoRobot = 10,
+ kCTSLeftRobotNoTarget = 11,
+ kCTSLeftRobotIsTarget = 12,
+ kCTSLeftNoRobot = 13,
+ kCTSLowerCannon = 14,
+ kCTSCount = 14
+};
+
+static const uint32 kScene3009CannonScopeVideos[] = {
+ 0x1010000D,
+ 0x340A0049,
+ 0x340A0049,
+ 0x0282081D,
+ 0x0082080D,
+ 0x0882080D,
+ 0x0882080D,
+ 0x0282081D,
+ 0x004B000B,
+ 0x014B000B,
+ 0x044B000B,
+ 0x0282081D,
+ 0x0282081D,
+ 0x0282081D,
+ 0x340A0049
+};
+
+static const uint32 kScene3009CannonActionVideos[] = {
+ 0x00000000,
+ 0x8004001B, // 1 Fire cannon at wall, it breaks (lowered)
+ 0x0004001A, // 2 Fire cannon at wall, nothing happens (lowered)
+ 0x1048404B, // 3 Fire cannon at emptyness (raised)
+ 0x50200109, // 4 Fire cannon, robot missed (raised)
+ 0x12032109, // 5 Fire cannon, robot hit (raised)
+ 0x10201109, // 6 Fire cannon, no robot (raised)
+ 0x000A2030, // 7 Raise the cannon
+ 0x000A0028, // 8
+ 0x000A0028, // 9
+ 0x000A0028, // 10
+ 0x040A1069, // 11
+ 0x040A1069, // 12
+ 0x040A1069, // 13
+ 0x240A1101 // 14 Lower the cannon
+};
+
+static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
+ 0x618827A0,
+ 0xB1A92322
+};
+
+static const uint32 kSsScene3009TargetLineFileHashes[] = {
+ 0x4011018C,
+ 0x15086623
+};
+
+static const NPoint kAsScene3009SymbolPoints[] = {
+ {289, 338},
+ {285, 375},
+ {284, 419},
+ {456, 372},
+ {498, 372},
+ {541, 372}
+};
+
+static const uint32 kAsScene3009SymbolFileHashes[] = {
+ 0x24542582,
+ 0x1CD61D96
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
+ 0x24016060,
+ 0x21216221,
+ 0x486160A0,
+ 0x42216422,
+ 0x90A16120,
+ 0x84216824,
+ 0x08017029,
+ 0x08217029,
+ 0x10014032,
+ 0x10214032,
+ 0x20012004,
+ 0x20212004
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
+ 0x40092024,
+ 0x01636002,
+ 0x8071E028,
+ 0x02A56064,
+ 0x00806031,
+ 0x052960A8,
+ 0x0A116130,
+ 0x0A316130,
+ 0x14216200,
+ 0x14016200,
+ 0x28416460,
+ 0x28616460
+};
+
+SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
+
+ loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ SetUpdateHandler(&SsScene3009FireCannonButton::update);
+ SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
+ loadSound(0, 0x3901B44F);
+}
+
+void SsScene3009FireCannonButton::update() {
+ updatePosition();
+ if (_isClicked && !isSoundPlaying(0)) {
+ sendMessage(_parentScene, 0x2000, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isClicked && !_parentScene->isTurning()) {
+ _isClicked = true;
+ setVisible(true);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400), _blinkCountdown(0) {
+
+ loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ if (getGlobalVar(V_ROBOT_HIT))
+ hide();
+ else
+ startBlinking();
+ SetUpdateHandler(&SsScene3009SymbolEdges::update);
+}
+
+void SsScene3009SymbolEdges::update() {
+ if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
+ if (_blinkToggle) {
+ setVisible(true);
+ } else {
+ setVisible(false);
+ }
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = !_blinkToggle;
+ }
+}
+
+void SsScene3009SymbolEdges::show() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::hide() {
+ setVisible(false);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::startBlinking() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = true;
+}
+
+SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400) {
+
+ loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ setVisible(false);
+}
+
+void SsScene3009TargetLine::show() {
+ setVisible(true);
+ updatePosition();
+}
+
+SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
+ : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
+
+ _incrDecr = _index % 2;
+
+ createSurface(1200, 33, 31);
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
+ _drawOffset.set(0, 0, 33, 31);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+ _needRefresh = true;
+
+ SetUpdateHandler(&SsScene3009SymbolArrow::update);
+ SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
+ loadSound(0, 0x2C852206);
+}
+
+void SsScene3009SymbolArrow::hide() {
+ _enabled = false;
+ setVisible(false);
+}
+
+void SsScene3009SymbolArrow::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
+ }
+}
+
+uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled && _countdown == 0) {
+ _countdown = 2;
+ loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
+ playSound(0);
+ sendMessage(_asSymbol, 0x2005, _incrDecr);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = 300;
+ _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
+ createSurface1(0xC2463913, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
+}
+
+void AsScene3009VerticalIndicator::show() {
+ startAnimation(0xC2463913, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
+ _y = 150;
+ createSurface1(0xC0C12954, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
+ if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+ _x = 280;
+ }
+}
+
+uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, 0x2004, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009HorizontalIndicator::suMoveLeft() {
+ _x -= 6;
+ if (_x < 92) {
+ SetSpriteUpdate(NULL);
+ _x = 92;
+ }
+}
+
+void AsScene3009HorizontalIndicator::suMoveRight() {
+ _x += 6;
+ if (_x > 533) {
+ SetSpriteUpdate(NULL);
+ _x = 533;
+ }
+}
+
+void AsScene3009HorizontalIndicator::show() {
+ startAnimation(0xC0C12954, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+void AsScene3009HorizontalIndicator::stMoveLeft() {
+ _x = 533;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
+}
+
+void AsScene3009HorizontalIndicator::stMoveRight() {
+ _x = 330;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+}
+
+AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
+
+ _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
+
+ _x = kAsScene3009SymbolPoints[_symbolPosition].x;
+ _y = kAsScene3009SymbolPoints[_symbolPosition].y;
+ createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ _needRefresh = true;
+ updatePosition();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009Symbol::handleMessage);
+ _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
+ _parentScene->addCollisionSprite(_ssArrowPrev);
+ _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
+ _parentScene->addCollisionSprite(_ssArrowNext);
+}
+
+uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2005:
+ if (param.asInteger()) {
+ if (_symbolIndex == 11)
+ _symbolIndex = 0;
+ else
+ _symbolIndex++;
+ } else {
+ if (_symbolIndex == 0)
+ _symbolIndex = 11;
+ else
+ _symbolIndex--;
+ }
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
+ if (_symbolPosition / 3 == 0) {
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ sendMessage(_parentScene, 0x2003, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009Symbol::hide() {
+ _ssArrowPrev->hide();
+ _ssArrowNext->hide();
+}
+
+// Scene3010
+
+static const uint32 kScene3010ButtonNameHashes[] = {
+ 0x304008D2,
+ 0x40119852,
+ 0x01180951
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes1[] = {
+ 0x301024C2,
+ 0x20280580,
+ 0x30200452
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
+ 0x50C025A8,
+ 0x1020A0A0,
+ 0x5000A7E8
+};
+
+static const NPoint kAsScene3010DeadBoltPoints[] = {
+ {550, 307},
+ {564, 415},
+ {560, 514}
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
+ 0x181A0042,
+ 0x580A08F2,
+ 0x18420076
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
+ 0x300E105A,
+ 0x804E0052,
+ 0x040E485A
+};
+
+SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
+
+ _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
+ createSurface(400, 88, 95);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ if (initDisabled)
+ disableButton();
+ else if (_buttonEnabled)
+ _countdown1 = initCountdown * 12 + 1;
+ loadSound(0, 0xF4217243);
+ loadSound(1, 0x44049000);
+ loadSound(2, 0x6408107E);
+ SetUpdateHandler(&SsScene3010DeadBoltButton::update);
+ SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
+}
+
+void SsScene3010DeadBoltButton::update() {
+
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ playSound(0);
+ setVisible(false);
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ }
+
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ setVisible(true);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ }
+
+}
+
+uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_buttonLocked && _countdown1 == 0) {
+ if (_buttonEnabled) {
+ playSound(1);
+ playSound(2);
+ setVisible(true);
+ _buttonLocked = true;
+ sendMessage(_parentScene, 0x2000, _buttonIndex);
+ } else {
+ sendMessage(_parentScene, 0x2002, _buttonIndex);
+ }
+ _needRefresh = true;
+ updatePosition();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene3010DeadBoltButton::disableButton() {
+ _buttonLocked = true;
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ setVisible(true);
+}
+
+void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
+}
+
+void SsScene3010DeadBoltButton::setCountdown(int count) {
+ _countdown2 = count * 18 + 1;
+}
+
+AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
+ _unlocked(false), _locked(false), _countdown(0) {
+
+ _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
+ _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
+
+ if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
+ createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ loadSound(0, 0x46005BC4);
+ } else {
+ createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ loadSound(0, 0x420073DC);
+ loadSound(1, 0x420073DC);
+ }
+
+ setVisible(false);
+ stIdle();
+ if (initUnlocked)
+ unlock(true);
+
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+
+}
+
+void AsScene3010DeadBolt::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ stDisabled();
+ }
+}
+
+uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3010DeadBolt::stIdle() {
+ stopAnimation();
+ SetUpdateHandler(&AsScene3010DeadBolt::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ _locked = false;
+}
+
+void AsScene3010DeadBolt::unlock(bool skipAnim) {
+ if (!_unlocked) {
+ setVisible(true);
+ if (skipAnim) {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ playSound(0);
+ }
+ _unlocked = true;
+ loadSound(2, 0x4010C345);
+ }
+}
+
+void AsScene3010DeadBolt::stIdleMessage() {
+ stopAnimation();
+ SetMessageHandler(&Sprite::handleMessage);
+ sendMessage(_parentScene, 0x2001, _boltIndex);
+}
+
+void AsScene3010DeadBolt::lock() {
+ if (!_locked) {
+ _locked = true;
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ if (_soundToggle) {
+ playSound(0);
+ } else {
+ playSound(1);
+ }
+ _soundToggle = !_soundToggle;
+ }
+}
+
+void AsScene3010DeadBolt::setCountdown(int count) {
+ _countdown = count * 18 + 1;
+}
+
+void AsScene3010DeadBolt::stDisabled() {
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ _playBackwards = true;
+ playSound(2);
+}
+
+void AsScene3010DeadBolt::stDisabledMessage() {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2003, _boltIndex);
+}
+
+// Scene3011
+
+static const uint32 kAsScene3011SymbolFileHashes[] = {
+ 0x00C88050,
+ 0x01488050,
+ 0x02488050,
+ 0x04488050,
+ 0x08488050,
+ 0x10488050,
+ 0x20488050,
+ 0x40488050,
+ 0x80488050,
+ 0x00488051,
+ 0x00488052,
+ 0x00488054,
+ 0x008B0000,
+ 0x008D0000,
+ 0x00810000,
+ 0x00990000,
+ 0x00A90000,
+ 0x00C90000,
+ 0x00090000,
+ 0x01890000,
+ 0x02890000,
+ 0x04890000,
+ 0x08890000,
+ 0x10890000
+};
+
+SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene3011Button::update);
+ SetMessageHandler(&SsScene3011Button::handleMessage);
+}
+
+void SsScene3011Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ StaticSprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ setVisible(true);
+ _countdown = 4;
+ sendMessage(_parentScene, 0x2000, 0);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
+ : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
+
+ if (_largeSymbol) {
+ _x = 310;
+ _y = 200;
+ createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
+ loadSound(0, 0x6052C60F);
+ loadSound(1, 0x6890433B);
+ } else {
+ _symbolIndex = 12;
+ _x = symbolIndex * 39 + 96;
+ _y = 225;
+ createSurface(1200, 41, 48);
+ loadSound(0, 0x64428609);
+ loadSound(1, 0x7080023B);
+ }
+ setVisible(false);
+ _needRefresh = true;
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene3011Symbol::show(bool isNoisy) {
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+void AsScene3011Symbol::hide() {
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene3011Symbol::stopSymbolSound() {
+ if (_isNoisy) {
+ stopSound(1);
+ } else {
+ stopSound(0);
+ }
+}
+
+void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
+ _symbolIndex = symbolIndex;
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module3000_sprites.h b/engines/neverhood/modules/module3000_sprites.h
new file mode 100644
index 0000000000..7316613327
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.h
@@ -0,0 +1,185 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1200.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+class Scene3009;
+
+class SsScene3009FireCannonButton : public StaticSprite {
+public:
+ SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
+protected:
+ Scene3009 *_parentScene;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene3009SymbolEdges : public StaticSprite {
+public:
+ SsScene3009SymbolEdges(NeverhoodEngine *vm, int index);
+ void show();
+ void hide();
+ void startBlinking();
+protected:
+ int _blinkCountdown;
+ bool _blinkToggle;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene3009TargetLine : public StaticSprite {
+public:
+ SsScene3009TargetLine(NeverhoodEngine *vm, int index);
+ void show();
+};
+
+class SsScene3009SymbolArrow : public StaticSprite {
+public:
+ SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
+ void hide();
+protected:
+ Sprite *_asSymbol;
+ int _index;
+ int _incrDecr;
+ bool _enabled;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009VerticalIndicator : public AnimatedSprite {
+public:
+ AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
+ void show();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009HorizontalIndicator : public AnimatedSprite {
+public:
+ AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
+ void show();
+ void stMoveLeft();
+ void stMoveRight();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveLeft();
+ void suMoveRight();
+};
+
+class AsScene3009Symbol : public AnimatedSprite {
+public:
+ AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
+ void hide();
+protected:
+ Scene3009 *_parentScene;
+ int _symbolPosition;
+ uint32 _symbolIndex;
+ SsScene3009SymbolArrow *_ssArrowPrev;
+ SsScene3009SymbolArrow *_ssArrowNext;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+// Scene3010
+
+class SsScene3010DeadBoltButton : public StaticSprite {
+public:
+ SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
+ void setCountdown(int count);
+protected:
+ Scene *_parentScene;
+ int _buttonIndex;
+ bool _buttonEnabled;
+ bool _buttonLocked;
+ int _countdown1;
+ int _countdown2;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void disableButton();
+ void setSprite(uint32 fileHash);
+};
+
+class AsScene3010DeadBolt : public AnimatedSprite {
+public:
+ AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
+ void setCountdown(int count);
+ void lock();
+ void unlock(bool skipAnim);
+protected:
+ Scene *_parentScene;
+ int _boltIndex;
+ int _countdown;
+ bool _soundToggle;
+ bool _unlocked;
+ bool _locked;
+ void update();
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stIdle();
+ void stIdleMessage();
+ void stDisabled();
+ void stDisabledMessage();
+};
+
+// Scene3011
+
+class SsScene3011Button : public StaticSprite {
+public:
+ SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3011Symbol : public AnimatedSprite {
+public:
+ AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
+ void show(bool isNoisy);
+ void hide();
+ void stopSymbolSound();
+ void change(int symbolIndex, bool isNoisy);
+ int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
+protected:
+ bool _largeSymbol;
+ bool _isNoisy;
+ int _symbolIndex;
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE3000_SPRITES_H */
diff --git a/engines/neverhood/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 d802322858..a15c00de07 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -25,33 +25,36 @@
namespace Neverhood {
+enum AreaType {
+ kAreaCanMoveForward = 0,
+ kAreaCannotMoveForward = 1
+};
+
NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes)
: Scene(vm, parentModule), _itemsTypes(itemsTypes), _navigationIndex(navigationIndex), _smackerDone(false),
_isWalkingForward(false), _isTurning(false), _smackerFileHash(0), _interactive(true), _leaveSceneAfter(false) {
_navigationList = _vm->_staticData->getNavigationList(navigationListId);
-
+ _navigationListId = 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 = new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true);
- addEntity(_smackerPlayer);
- addSurface(_smackerPlayer->getSurface());
-
+
+ _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, (*_navigationList)[_navigationIndex].fileHash, true, true));
+
createMouseCursor();
_vm->_screen->clear();
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
sendMessage(_parentModule, 0x100A, _navigationIndex);
-
}
NavigationScene::~NavigationScene() {
@@ -97,7 +100,7 @@ void NavigationScene::update() {
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
sendMessage(_parentModule, 0x100A, _navigationIndex);
}
- }
+ }
Scene::update();
}
@@ -123,39 +126,34 @@ uint32 NavigationScene::handleMessage(int messageNum, const MessageParam &param,
}
void NavigationScene::createMouseCursor() {
-
const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
uint32 mouseCursorFileHash;
int areaType;
- if (_mouseCursor) {
+ if (_mouseCursor)
deleteSprite((Sprite**)&_mouseCursor);
- }
mouseCursorFileHash = navigationItem.mouseCursorFileHash;
if (mouseCursorFileHash == 0)
mouseCursorFileHash = 0x63A40028;
-
- if (_itemsTypes) {
+
+ if (_itemsTypes)
areaType = _itemsTypes[_navigationIndex];
- } else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag) {
- areaType = 0;
- } else {
- areaType = 1;
- }
+ else if (navigationItem.middleSmackerFileHash != 0 || navigationItem.middleFlag)
+ areaType = kAreaCanMoveForward;
+ else
+ areaType = kAreaCannotMoveForward;
insertNavigationMouse(mouseCursorFileHash, areaType);
sendPointMessage(_mouseCursor, 0x4002, _vm->getMousePos());
-
}
void NavigationScene::handleNavigation(const NPoint &mousePos) {
-
const NavigationItem &navigationItem = (*_navigationList)[_navigationIndex];
bool oldIsWalkingForward = _isWalkingForward;
bool oldIsTurning = _isTurning;
uint32 direction = sendPointMessage(_mouseCursor, 0x2064, mousePos);
-
+
switch (direction) {
case 0:
if (navigationItem.leftSmackerFileHash != 0) {
@@ -206,13 +204,12 @@ void NavigationScene::handleNavigation(const NPoint &mousePos) {
}
break;
}
-
+
if (oldIsTurning != _isTurning)
_vm->_soundMan->setSoundThreePlayFlag(_isTurning);
if (oldIsWalkingForward != _isWalkingForward)
_vm->_soundMan->setTwoSoundsPlayFlag(_isWalkingForward);
-
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h
index ebe9a3597c..c17446811c 100644
--- a/engines/neverhood/navigationscene.h
+++ b/engines/neverhood/navigationscene.h
@@ -38,10 +38,12 @@ public:
bool isWalkingForward() const { return _isWalkingForward; }
bool isTurning() const { return _isTurning; }
int getFrameNumber() const { return _smackerPlayer->getFrameNumber(); }
+ uint32 getNavigationListId() const { return _navigationListId; }
protected:
SmackerPlayer *_smackerPlayer;
bool _smackerDone;
NavigationList *_navigationList;
+ uint32 _navigationListId; // used for debugging
int _navigationIndex;
uint32 _smackerFileHash;
bool _interactive;
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 42fe1176b4..b961bccea7 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -22,12 +22,18 @@
#include "common/file.h"
#include "common/config-manager.h"
+#include "common/textconsole.h"
+
#include "base/plugins.h"
#include "base/version.h"
+
#include "graphics/cursorman.h"
+
#include "engines/util.h"
+
#include "neverhood/neverhood.h"
#include "neverhood/blbarchive.h"
+#include "neverhood/console.h"
#include "neverhood/gamemodule.h"
#include "neverhood/gamevars.h"
#include "neverhood/graphics.h"
@@ -71,12 +77,17 @@ Common::Error NeverhoodEngine::run() {
_gameState.sceneNum = 0;
_gameState.which = 0;
+ // Assign default values to the config manager, in case settings are missing
+ ConfMan.registerDefault("originalsaveload", "false");
+ ConfMan.registerDefault("skiphallofrecordsscenes", "false");
+
_staticData = new StaticData();
_staticData->load("neverhood.dat");
_gameVars = new GameVars();
_screen = new Screen(this);
_res = new ResourceMan();
-
+ _console = new Console(this);
+
if (isDemo()) {
_res->addArchive("a.blb");
_res->addArchive("nevdemo.blb");
@@ -90,15 +101,17 @@ Common::Error NeverhoodEngine::run() {
_res->addArchive("t.blb");
}
- CursorMan.showMouse(true);
+ CursorMan.showMouse(false);
_soundMan = new SoundMan(this);
_audioResourceMan = new AudioResourceMan(this);
-
+
_gameModule = new GameModule(this);
-
+
_isSaveAllowed = true;
-
+ _updateSound = true;
+ _enableMusic = !_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType);
+
if (isDemo()) {
// Adjust this navigation list for the demo version
NavigationList *navigationList = _staticData->getNavigationList(0x004B67E8);
@@ -111,24 +124,26 @@ Common::Error NeverhoodEngine::run() {
(*navigationList)[5].middleSmackerFileHash = 0;
(*navigationList)[5].middleFlag = 1;
}
-
- if (ConfMan.hasKey("save_slot"))
- loadGameState(ConfMan.getInt("save_slot"));
- else
+
+ 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;
+ delete _console;
delete _res;
delete _screen;
delete _gameVars;
delete _staticData;
-
+
return Common::kNoError;
}
@@ -140,6 +155,11 @@ void NeverhoodEngine::mainLoop() {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
+ if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) {
+ // Open debugger console
+ _console->attach();
+ continue;
+ }
_gameModule->handleKeyDown(event.kbd.keycode);
_gameModule->handleAsciiKey(event.kbd.ascii);
break;
@@ -169,11 +189,16 @@ void NeverhoodEngine::mainLoop() {
_gameModule->checkRequests();
_gameModule->handleUpdate();
_gameModule->draw();
+ _console->onFrame();
_screen->update();
nextFrameTime = _screen->getNextFrameTime();
};
- _soundMan->update();
- _audioResourceMan->updateMusic();
+
+ if (_updateSound) {
+ _soundMan->update();
+ _audioResourceMan->updateMusic();
+ }
+
_system->updateScreen();
_system->delayMillis(10);
}
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 577fbd7a66..0561aa251e 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -48,6 +48,7 @@ class Screen;
class SoundMan;
class AudioResourceMan;
class StaticData;
+class Console;
struct NPoint;
struct GameState {
@@ -71,8 +72,10 @@ public:
uint32 getFeatures() const;
uint16 getVersion() const;
Common::Platform getPlatform() const;
+ Common::Language getLanguage() const;
bool hasFeature(EngineFeature f) const;
bool isDemo() const;
+ bool applyResourceFixes() const;
Common::String getTargetName() { return _targetName; };
Common::RandomSource *_rnd;
@@ -86,12 +89,13 @@ public:
ResourceMan *_res;
GameModule *_gameModule;
StaticData *_staticData;
-
+ Console *_console;
+
SoundMan *_soundMan;
AudioResourceMan *_audioResourceMan;
public:
-
+
/* Save/load */
enum kReadSaveHeaderError {
@@ -116,12 +120,12 @@ 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);
- void savegame(const char *filename, const char *description);
- void loadgame(const char *filename);
+ bool savegame(const char *filename, const char *description);
+ bool loadgame(const char *filename);
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
@@ -132,7 +136,13 @@ public:
int16 getMouseY() const { return _mouseY; }
NPoint getMousePos();
-public:
+ void toggleSoundUpdate(bool state) { _updateSound = state; }
+ void toggleMusic(bool state) { _enableMusic = state; }
+ bool musicIsEnabled() { return _enableMusic; }
+
+private:
+ bool _updateSound;
+ bool _enableMusic;
};
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index d4b9b67f53..941bcc3cd3 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -66,6 +66,11 @@ void Palette::init() {
_status = 0;
_palette = new byte[1024];
_basePalette = new byte[1024];
+ _palCounter = 0;
+ _fadeToR = 0;
+ _fadeToG = 0;
+ _fadeToB = 0;
+ _fadeStep = 0;
}
void Palette::usePalette() {
@@ -81,7 +86,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 +95,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 +120,7 @@ void Palette::startFadeToBlack(int counter) {
_fadeToB = 0;
_palCounter = counter;
_fadeStep = 255 / counter;
- _status = 1;
+ _status = 1;
}
void Palette::startFadeToWhite(int counter) {
@@ -127,7 +132,7 @@ void Palette::startFadeToWhite(int counter) {
_fadeToB = 255;
_palCounter = counter;
_fadeStep = 255 / counter;
- _status = 1;
+ _status = 1;
}
void Palette::startFadeToPalette(int counter) {
@@ -136,7 +141,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..b45dbff3b9 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);
@@ -53,11 +53,11 @@ bool SpriteResource::load(uint32 fileHash, bool doLoadPosition) {
unload();
_vm->_res->queryResource(fileHash, _resourceHandle);
if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeBitmap) {
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
const byte *spriteData = _resourceHandle.data();
NPoint *position = doLoadPosition ? &_position : NULL;
parseBitmapResource(spriteData, &_rle, &_dimensions, position, NULL, &_pixels);
- }
+ }
return _pixels != NULL;
}
@@ -83,7 +83,7 @@ bool PaletteResource::load(uint32 fileHash) {
_vm->_res->queryResource(fileHash, _resourceHandle);
if (_resourceHandle.isValid() &&
(_resourceHandle.type() == kResTypeBitmap || _resourceHandle.type() == kResTypePalette)) {
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
_palette = _resourceHandle.data();
// Check if the palette is stored in a bitmap
if (_resourceHandle.type() == kResTypeBitmap)
@@ -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,32 +134,32 @@ 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;
uint32 spriteDataOfs, paletteDataOfs;
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
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() {
@@ -323,7 +323,7 @@ void TextResource::load(uint32 fileHash) {
unload();
_vm->_res->queryResource(fileHash, _resourceHandle);
if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeText) {
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
_textData = _resourceHandle.data();
_count = READ_LE_UINT32(_textData);
}
@@ -359,7 +359,7 @@ void DataResource::load(uint32 fileHash) {
unload();
_vm->_res->queryResource(fileHash, _resourceHandle);
if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeData) {
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
data = _resourceHandle.data();
dataSize = _resourceHandle.size();
}
@@ -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..f6937384c0 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;
@@ -85,7 +85,44 @@ void ResourceMan::queryResource(uint32 fileHash, ResourceHandle &resourceHandle)
resourceHandle._extData = firstEntry ? firstEntry->archiveEntry->extData : NULL;
}
-void ResourceMan::loadResource(ResourceHandle &resourceHandle) {
+struct EntrySizeFix {
+ uint32 fileHash;
+ uint32 offset;
+ uint32 diskSize;
+ uint32 size;
+ uint32 fixedSize;
+};
+
+static const EntrySizeFix entrySizeFixes[] = {
+ // fileHash offset diskSize size fixedSize
+ // Fixes for the Russian "Dyadyushka Risech" version
+ { 0x041137051, 667019, 23391, 41398, 41401 }, // "Options" menu header text
+ { 0x00f960021, 402268, 1704, 4378, 1870 }, // "Save" menu
+ { 0x01301a7ea, 1220008, 2373, 4146, 2877 }, // "Load" menu
+ { 0x084181e81, 201409, 1622, 5058, 1833 }, // "Delete" menu
+ { 0x008C0AC24, 1031009, 3030, 6498, 3646 }, // Overwrite dialog
+ { 0x0c6604282, 12813649, 19623, 35894, 35895 }, // One of the fonts when reading Willie's notes
+ { 0x080283101, 13104841, 1961, 3712, 3511 }, // First message from Willie
+ { 0x000918480, 17676417, 581, 916, 706 }, // First wall in the museum
+ { 0x00800090C, 16064875, 19555, 38518, 38526 }, // First wall in the museum
+ { 0x058208810, 46010519, 24852, 131874, 131776 }, // Entry to hut with musical lock
+ { 0x00008E486, 39600019, 240, 454, 271 }, // Second wall in the museum
+ { 0x003086004, 39621755, 482, 614, 600 }, // Second wall in the museum
+ { 0x02008048E, 39611075, 3798, 21089, 21087 }, // Next couple of walls in the museum
+ { 0x008586283, 39587864, 12155, 29731, 29730 }, // Next couple of walls in the museum
+ { 0x030A84C80, 39606142, 4933, 16305, 16275 }, // Next couple of walls in the museum
+ { 0x000C9A480, 39614873, 6882, 23915, 23913 }, // Next couple of walls in the museum
+ { 0x000098880, 39603114, 3028, 10860, 10859 }, // Next couple of walls in the museum
+ { 0x040080183, 39600259, 2855, 13400, 13395 }, // Last buggy wall in the museum
+
+ // Fixes for the Russian "Fargus" version
+ { 0x041137051, 758264, 29037, 49590, 49591 }, // "Options" menu header text
+ { 0x0c10b2015, 787304, 4414, 15848, 15853 }, // Text on option buttons
+ //
+ { 0, 0, 0, 0, 0 }
+};
+
+void ResourceMan::loadResource(ResourceHandle &resourceHandle, bool applyResourceFixes) {
resourceHandle._data = NULL;
if (resourceHandle.isValid()) {
const uint32 fileHash = resourceHandle.fileHash();
@@ -97,8 +134,19 @@ void ResourceMan::loadResource(ResourceHandle &resourceHandle) {
if (resourceData->data != NULL) {
resourceData->dataRefCount++;
} else {
- resourceData->data = new byte[resourceHandle._resourceFileEntry->archiveEntry->size];
- resourceHandle._resourceFileEntry->archive->load(resourceHandle._resourceFileEntry->archiveEntry, resourceData->data, 0);
+ BlbArchiveEntry *entry = resourceHandle._resourceFileEntry->archiveEntry;
+
+ // Apply fixes for broken resources in Russian versions
+ if (applyResourceFixes) {
+ for (const EntrySizeFix *cur = entrySizeFixes; cur->fileHash > 0; ++cur) {
+ if (entry->fileHash == cur->fileHash && entry->offset == cur->offset &&
+ entry->diskSize == cur->diskSize && entry->size == cur->size)
+ entry->size = cur->fixedSize;
+ }
+ }
+
+ resourceData->data = new byte[entry->size];
+ resourceHandle._resourceFileEntry->archive->load(entry, resourceData->data, 0);
resourceData->dataRefCount = 1;
}
resourceHandle._data = resourceData->data;
diff --git a/engines/neverhood/resourceman.h b/engines/neverhood/resourceman.h
index 5a3697fe0d..29bf40a6b8 100644
--- a/engines/neverhood/resourceman.h
+++ b/engines/neverhood/resourceman.h
@@ -78,7 +78,7 @@ public:
const ResourceFileEntry& getEntry(uint index) { return _entries[index]; }
uint getEntryCount() { return _entries.size(); }
void queryResource(uint32 fileHash, ResourceHandle &resourceHandle);
- void loadResource(ResourceHandle &resourceHandle);
+ void loadResource(ResourceHandle &resourceHandle, bool applyResourceFixes);
void unloadResource(ResourceHandle &resourceHandle);
void purgeResources();
protected:
diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp
index 578d9858ff..01988769e6 100644
--- a/engines/neverhood/saveload.cpp
+++ b/engines/neverhood/saveload.cpp
@@ -61,12 +61,12 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se
return ((in->eos() || in->err()) ? kRSHEIoError : kRSHENoError);
}
-void NeverhoodEngine::savegame(const char *filename, const char *description) {
+bool NeverhoodEngine::savegame(const char *filename, const char *description) {
Common::OutSaveFile *out;
if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
warning("Can't create file '%s', game not saved", filename);
- return;
+ return false;
}
TimeDate curTime;
@@ -78,7 +78,7 @@ void 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,50 +96,53 @@ void 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;
}
-void NeverhoodEngine::loadgame(const char *filename) {
+bool NeverhoodEngine::loadgame(const char *filename) {
Common::InSaveFile *in;
if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
warning("Can't open file '%s', game not loaded", filename);
- return;
+ return false;
}
SaveHeader header;
kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
-
+
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
delete in;
- return;
+ 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);
_gameModule->requestRestoreGame();
delete in;
-
+ return true;
}
Common::Error NeverhoodEngine::loadGameState(int slot) {
const char *fileName = getSavegameFilename(slot);
- loadgame(fileName);
+ if (!loadgame(fileName))
+ return Common::kReadingFailed;
return Common::kNoError;
}
Common::Error NeverhoodEngine::saveGameState(int slot, const Common::String &description) {
const char *fileName = getSavegameFilename(slot);
- savegame(fileName, description.c_str());
+ if (!savegame(fileName, description.c_str()))
+ return Common::kWritingFailed;
return Common::kNoError;
}
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 07d41754c9..9a7e87ac8d 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "neverhood/console.h"
#include "neverhood/scene.h"
namespace Neverhood {
@@ -27,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;
@@ -49,15 +50,22 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
_smackerPlayer = NULL;
_isMessageListBusy = false;
_messageValue = -1;
-
+ _messageListStatus = 0;
+ _messageListCount = 0;
+ _messageListIndex = 0;
+
+ _backgroundFileHash = _cursorFileHash = 0;
+
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene::handleMessage);
-
+
_vm->_screen->clearRenderQueue();
}
Scene::~Scene() {
+ _vm->_screen->setSmackerDecoder(NULL);
+
if (_palette) {
removeEntity(_palette);
delete _palette;
@@ -68,7 +76,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();
@@ -81,7 +89,7 @@ void Scene::draw() {
} else {
for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++)
(*iter)->draw();
- }
+ }
}
void Scene::addEntity(Entity *entity) {
@@ -96,7 +104,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) {
@@ -105,7 +113,7 @@ bool Scene::removeEntity(Entity *entity) {
_entities.remove_at(index);
return true;
}
- return false;
+ return false;
}
void Scene::addSurface(BaseSurface *surface) {
@@ -121,7 +129,7 @@ void Scene::addSurface(BaseSurface *surface) {
if (insertIndex >= 0)
_surfaces.insert_at(insertIndex, surface);
else
- _surfaces.push_back(surface);
+ _surfaces.push_back(surface);
}
}
@@ -132,7 +140,19 @@ bool Scene::removeSurface(BaseSurface *surface) {
return true;
}
}
- return false;
+ return false;
+}
+
+void Scene::printSurfaces(Console *con) {
+ for (uint index = 0; index < _surfaces.size(); index++) {
+ NDrawRect drawRect = _surfaces[index]->getDrawRect();
+ NRect clipRect = _surfaces[index]->getClipRect();
+ int priority = _surfaces[index]->getPriority();
+ con->DebugPrintf("%d ('%s'): Priority %d, draw rect (%d, %d, %d, %d), clip rect (%d, %d, %d, %d)\n",
+ index, _surfaces[index]->getName().c_str(), priority,
+ drawRect.x, drawRect.y, drawRect.x2(), drawRect.y2(),
+ clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2);
+ }
}
Sprite *Scene::addSprite(Sprite *sprite) {
@@ -173,6 +193,7 @@ Background *Scene::addBackground(Background *background) {
void Scene::setBackground(uint32 fileHash) {
_background = addBackground(new Background(_vm, fileHash, 0, 0));
+ _backgroundFileHash = fileHash;
}
void Scene::changeBackground(uint32 fileHash) {
@@ -197,18 +218,21 @@ 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));
+ _cursorFileHash = fileHash;
}
void Scene::insertPuzzleMouse(uint32 fileHash, int16 x1, int16 x2) {
insertMouse(new Mouse(_vm, fileHash, x1, x2));
+ _cursorFileHash = fileHash;
}
void Scene::insertNavigationMouse(uint32 fileHash, int type) {
insertMouse(new Mouse(_vm, fileHash, type));
+ _cursorFileHash = fileHash;
}
void Scene::showMouse(bool visible) {
@@ -231,12 +255,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);
}
@@ -247,7 +271,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();
@@ -268,7 +292,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
@@ -317,7 +341,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;
}
@@ -397,8 +421,8 @@ void Scene::processMessageList() {
_messageList2 = NULL;
_messageListStatus = 0;
}
-
- if (_messageList && _klaymen) {
+
+ if (_messageList && _klaymen) {
#if 0
debug("MessageList: %p, %d", (void*)_messageList, _messageList->size());
@@ -408,11 +432,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);
@@ -445,7 +469,7 @@ void Scene::processMessageList() {
if (_klaymen->hasMessageHandler() && sendMessage(_klaymen, messageNum, messageParam) != 0) {
_isKlaymenBusy = false;
}
- }
+ }
if (_messageListIndex == _messageListCount) {
_canAcceptInput = true;
_messageList = NULL;
@@ -454,7 +478,7 @@ void Scene::processMessageList() {
}
_isMessageListBusy = false;
-
+
}
void Scene::cancelMessageList() {
@@ -516,7 +540,7 @@ uint16 Scene::convertMessageNum(uint32 messageNum) {
case 0x42002200:
return 0x4004;
case 0x428D4894:
- return 0x101A;
+ return 0x101A;
}
return 0x1000;
}
@@ -531,7 +555,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) {
@@ -546,7 +570,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) {
@@ -568,7 +592,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) {
@@ -578,4 +602,27 @@ void Scene::insertMouse(Mouse *mouseCursor) {
addEntity(_mouseCursor);
}
+// StaticScene
+
+StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash)
+ : Scene(vm, parentModule) {
+
+ SetMessageHandler(&StaticScene::handleMessage);
+
+ setBackground(backgroundFileHash);
+ setPalette(backgroundFileHash);
+ insertPuzzleMouse(cursorFileHash, 20, 620);
+}
+
+uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
+ leaveScene(0);
+ break;
+ }
+ return 0;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 1abcbfb964..e6183199ce 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -37,6 +37,8 @@
namespace Neverhood {
+class Console;
+
class Scene : public Entity {
public:
Scene(NeverhoodEngine *vm, Module *parentModule);
@@ -46,6 +48,7 @@ public:
bool removeEntity(Entity *entity);
void addSurface(BaseSurface *surface);
bool removeSurface(BaseSurface *surface);
+ void printSurfaces(Console *con);
Sprite *addSprite(Sprite *sprite);
void removeSprite(Sprite *sprite);
void setSurfacePriority(BaseSurface *surface, int priority);
@@ -73,92 +76,96 @@ 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);
}
+
+ uint32 getBackgroundFileHash() const { return _backgroundFileHash; }
+ uint32 getCursorFileHash() const { return _cursorFileHash; }
+
protected:
Module *_parentModule;
Common::Array<Entity*> _entities;
@@ -194,8 +201,9 @@ protected:
HitRectList *_hitRects;
Common::Array<Sprite*> _collisionSprites;
- void (Entity::*_savedUpdateHandlerCb)();
- uint32 (Entity::*_savedMessageHandlerCb)(int messageNum, const MessageParam &param, Entity *sender);
+ // Used for debugging
+ uint32 _backgroundFileHash, _cursorFileHash; // for StaticScene and all Scene* classes
+
int _messageValue;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
bool queryPositionSprite(int16 mouseX, int16 mouseY);
@@ -221,6 +229,14 @@ protected:
void insertMouse(Mouse *mouseCursor);
};
+
+class StaticScene : public Scene {
+public:
+ StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_SCENE_H */
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index 5a748cfab4..901ab73b39 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -27,17 +27,18 @@ namespace Neverhood {
Screen::Screen(NeverhoodEngine *vm)
: _vm(vm), _paletteData(NULL), _paletteChanged(false), _smackerDecoder(NULL),
- _yOffset(0), _fullRefresh(false) {
-
+ _yOffset(0), _fullRefresh(false), _frameDelay(0), _savedSmackerDecoder(NULL),
+ _savedFrameDelay(0), _savedYOffset(0) {
+
_ticks = _vm->_system->getMillis();
-
+
_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 +55,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 +73,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 +94,7 @@ void Screen::update() {
for (RectangleList::iterator ri = updateRects->begin(); ri != updateRects->end(); ++ri)
blitRenderItem(renderItem, *ri);
}
-
+
SWAP(_renderQueue, _prevRenderQueue);
_renderQueue->clear();
@@ -174,7 +175,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 +203,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 +216,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 +225,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 +243,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 +251,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 +271,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 +293,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 +322,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 +332,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 +351,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 +370,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/screen.h b/engines/neverhood/screen.h
index c778066152..a9b5af02f6 100644
--- a/engines/neverhood/screen.h
+++ b/engines/neverhood/screen.h
@@ -79,7 +79,6 @@ public:
void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version,
const Graphics::Surface *shadowSurface = NULL);
void drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version);
- void drawShadowSurface(const Graphics::Surface *surface, const Graphics::Surface *shadowSurface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect);
void drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect);
void drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent, byte version);
void drawSurfaceClipRects(const Graphics::Surface *surface, NDrawRect &drawRect, NRect *clipRects, uint clipRectsCount, bool transparent, byte version);
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index b67c8db9fc..187939faee 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -31,7 +31,7 @@ namespace Neverhood {
// SmackerSurface
SmackerSurface::SmackerSurface(NeverhoodEngine *vm)
- : BaseSurface(vm, 0, 0, 0), _smackerFrame(NULL) {
+ : BaseSurface(vm, 0, 0, 0, "smacker"), _smackerFrame(NULL) {
}
void SmackerSurface::draw() {
@@ -51,6 +51,18 @@ void SmackerSurface::setSmackerFrame(const Graphics::Surface *smackerFrame) {
_smackerFrame = smackerFrame;
}
+void SmackerSurface::unsetSmackerFrame() {
+ _drawRect.x = 0;
+ _drawRect.y = 0;
+ _drawRect.width = 0;
+ _drawRect.height = 0;
+ _sysRect.x = 0;
+ _sysRect.y = 0;
+ _sysRect.width = 0;
+ _sysRect.height = 0;
+ _smackerFrame = NULL;
+}
+
// SmackerDoubleSurface
SmackerDoubleSurface::SmackerDoubleSurface(NeverhoodEngine *vm)
@@ -62,25 +74,27 @@ void SmackerDoubleSurface::draw() {
_vm->_screen->drawDoubleSurface2(_smackerFrame, _drawRect);
}
+// NeverhoodSmackerDecoder
+
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);
}
@@ -92,40 +106,43 @@ SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash,
_drawX(-1), _drawY(-1) {
SetUpdateHandler(&SmackerPlayer::update);
+
+ if (_doubleSurface) {
+ _smackerSurface = new SmackerDoubleSurface(_vm);
+ } else {
+ _smackerSurface = new SmackerSurface(_vm);
+ }
+
open(fileHash, flag);
}
SmackerPlayer::~SmackerPlayer() {
close();
+ delete _smackerSurface;
+ _smackerSurface = NULL;
}
void SmackerPlayer::open(uint32 fileHash, bool keepLastFrame) {
debug(0, "SmackerPlayer::open(%08X)", fileHash);
-
+
_fileHash = fileHash;
_keepLastFrame = keepLastFrame;
close();
- if (_doubleSurface) {
- _smackerSurface = new SmackerDoubleSurface(_vm);
- } else {
- _smackerSurface = new SmackerSurface(_vm);
- }
-
_smackerFirst = true;
_stream = _vm->_res->createStream(fileHash);
_smackerDecoder = new NeverhoodSmackerDecoder();
_smackerDecoder->loadStream(_stream);
-
+
_palette = new Palette(_vm);
_palette->usePalette();
if (!_paused)
_smackerDecoder->start();
-
+
}
void SmackerPlayer::close() {
@@ -134,11 +151,10 @@ void SmackerPlayer::close() {
delete _smackerDecoder;
delete _palette;
// NOTE The SmackerDecoder deletes the _stream
- delete _smackerSurface;
_smackerDecoder = NULL;
_palette = NULL;
_stream = NULL;
- _smackerSurface = NULL;
+ _smackerSurface->unsetSmackerFrame();
}
void SmackerPlayer::gotoFrame(int frameNumber) {
@@ -196,10 +212,14 @@ void SmackerPlayer::update() {
_videoDone = false;
}
}
-
+
}
void SmackerPlayer::updateFrame() {
+
+ if (!_smackerDecoder || !_smackerSurface)
+ return;
+
const Graphics::Surface *smackerFrame = _smackerDecoder->decodeNextFrame();
if (_smackerFirst) {
@@ -220,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 26ebff5d33..dd7199dd6d 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -37,6 +37,7 @@ public:
SmackerSurface(NeverhoodEngine *vm);
virtual void draw();
void setSmackerFrame(const Graphics::Surface *smackerFrame);
+ void unsetSmackerFrame();
protected:
const Graphics::Surface *_smackerFrame;
};
@@ -61,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/smackerscene.h b/engines/neverhood/smackerscene.h
index 7ed2e0262b..8e5084512f 100644
--- a/engines/neverhood/smackerscene.h
+++ b/engines/neverhood/smackerscene.h
@@ -36,6 +36,7 @@ public:
void setFileHash(uint32 fileHash);
void setFileHashList(const uint32 *fileHashList);
void nextVideo();
+ uint32 getSmackerFileHash() const { return _fileHash[0]; }
protected:
bool _doubleSurface;
bool _canSkip;
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index c84b751e44..3ea45491a7 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;
@@ -250,14 +250,36 @@ void SoundItem::update() {
// SoundMan
SoundMan::SoundMan(NeverhoodEngine *vm)
- : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1) {
+ : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1),
+ _initialCountdown(0), _playOnceAfterCountdown(false),
+ _initialCountdown3(0), _playOnceAfterCountdown3(false) {
}
SoundMan::~SoundMan() {
- for (uint i = 0; i < _soundItems.size(); ++i)
- delete _soundItems[i];
- for (uint i = 0; i < _musicItems.size(); ++i)
- delete _musicItems[i];
+ stopAllMusic();
+ stopAllSounds();
+}
+
+void SoundMan::stopAllMusic() {
+ for (uint i = 0; i < _musicItems.size(); ++i) {
+ if (_musicItems[i]) {
+ _musicItems[i]->stopMusic(0, 0);
+ delete _musicItems[i];
+ _musicItems[i] = NULL;
+ }
+ }
+}
+
+void SoundMan::stopAllSounds() {
+ for (uint i = 0; i < _soundItems.size(); ++i) {
+ if (_soundItems[i]) {
+ _soundItems[i]->stopSound();
+ delete _soundItems[i];
+ _soundItems[i] = NULL;
+ }
+ }
+
+ _soundIndex1 = _soundIndex2 = _soundIndex3 = -1;
}
void SoundMan::addMusic(uint32 groupNameHash, uint32 musicFileHash) {
@@ -345,7 +367,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)
@@ -440,7 +462,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) {
@@ -514,16 +536,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--) {
@@ -557,7 +579,7 @@ AudioResourceManSoundItem::AudioResourceManSoundItem(NeverhoodEngine *vm, uint32
void AudioResourceManSoundItem::loadSound() {
if (!_data && _resourceHandle.isValid() &&
(_resourceHandle.type() == kResTypeSound || _resourceHandle.type() == kResTypeMusic)) {
- _vm->_res->loadResource(_resourceHandle);
+ _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes());
_data = _resourceHandle.data();
}
}
@@ -607,7 +629,8 @@ bool AudioResourceManSoundItem::isPlaying() {
AudioResourceManMusicItem::AudioResourceManMusicItem(NeverhoodEngine *vm, uint32 fileHash)
: _vm(vm), _fileHash(fileHash), _terminate(false), _canRestart(false),
- _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false) {
+ _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false),
+ _fadeVolume(0), _fadeVolumeStep(0) {
}
@@ -678,7 +701,7 @@ void AudioResourceManMusicItem::update() {
_start = false;
_isPlaying = true;
}
-
+
if (_vm->_mixer->isSoundHandleActive(_soundHandle)) {
if (_isFadingIn) {
_fadeVolume += _fadeVolumeStep;
@@ -708,11 +731,29 @@ AudioResourceMan::AudioResourceMan(NeverhoodEngine *vm)
: _vm(vm) {
}
+void AudioResourceMan::stopAllMusic() {
+ for (uint i = 0; i < _musicItems.size(); ++i) {
+ if (_musicItems[i]) {
+ _musicItems[i]->stopMusic(0);
+ delete _musicItems[i];
+ _musicItems[i] = NULL;
+ }
+ }
+}
+
+void AudioResourceMan::stopAllSounds() {
+ for (uint i = 0; i < _soundItems.size(); ++i) {
+ if (_soundItems[i]) {
+ _soundItems[i]->stopSound();
+ delete _soundItems[i];
+ _soundItems[i] = NULL;
+ }
+ }
+}
+
AudioResourceMan::~AudioResourceMan() {
- for (uint i = 0; i < _soundItems.size(); ++i)
- delete _soundItems[i];
- for (uint i = 0; i < _musicItems.size(); ++i)
- delete _musicItems[i];
+ stopAllMusic();
+ stopAllSounds();
}
int16 AudioResourceMan::addSound(uint32 fileHash) {
@@ -757,11 +798,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 d3318998db..548fe88501 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;
@@ -129,12 +129,15 @@ public:
SoundMan(NeverhoodEngine *vm);
~SoundMan();
+ void stopAllMusic();
+ void stopAllSounds();
+
// Music
void addMusic(uint32 groupNameHash, uint32 musicFileHash);
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);
@@ -146,7 +149,7 @@ public:
void playSoundLooping(uint32 soundFileHash);
void stopSound(uint32 soundFileHash);
void setSoundVolume(uint32 soundFileHash, int volume);
-
+
// Misc
void update();
void deleteGroup(uint32 groupNameHash);
@@ -159,25 +162,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 {
@@ -207,7 +210,7 @@ private:
// TODO Rename these
class AudioResourceManSoundItem {
-public:
+public:
AudioResourceManSoundItem(NeverhoodEngine *vm, uint32 fileHash);
void loadSound();
void unloadSound();
@@ -216,7 +219,7 @@ public:
void playSound(bool looping);
void stopSound();
bool isPlaying();
-protected:
+protected:
NeverhoodEngine *_vm;
uint32 _fileHash;
ResourceHandle _resourceHandle;
@@ -241,7 +244,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;
@@ -261,16 +264,19 @@ class AudioResourceMan {
public:
AudioResourceMan(NeverhoodEngine *vm);
~AudioResourceMan();
-
+
+ void stopAllMusic();
+ void stopAllSounds();
+
int16 addSound(uint32 fileHash);
void removeSound(int16 soundIndex);
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 45d131fd3c..1a432461fb 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) {
@@ -83,7 +83,7 @@ void Sprite::loadDataResource(uint32 fileHash) {
}
void Sprite::createSurface(int surfacePriority, int16 width, int16 height) {
- _surface = new BaseSurface(_vm, surfacePriority, width, height);
+ _surface = new BaseSurface(_vm, surfacePriority, width, height, "sprite");
}
int16 Sprite::defFilterY(int16 y) {
@@ -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 {
@@ -211,6 +211,12 @@ void AnimatedSprite::init() {
_replNewColor = 0;
_animResource.setReplEnabled(false);
_playBackwards = false;
+ _currAnimFileHash = 0;
+ _lastFrameIndex = 0;
+ _plLastFrameIndex = 0;
+ _plFirstFrameHash = 0;
+ _plLastFrameHash = 0;
+ _animStatus = 0;
}
void AnimatedSprite::update() {
@@ -261,7 +267,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 +276,7 @@ void AnimatedSprite::updateAnim() {
_currAnimFileHash = 0;
}
if (_replOldColor != _replNewColor) {
- _animResource.setRepl(_replOldColor, _replNewColor);
+ _animResource.setRepl(_replOldColor, _replNewColor);
}
_nextAnimFileHash = 0;
if (_animStatus != 0) {
@@ -278,17 +284,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 +307,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 +320,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;
@@ -398,7 +404,7 @@ void AnimatedSprite::updateFrameInfo() {
void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) {
NDimensions dimensions = _animResource.loadSpriteDimensions(fileHash);
- _surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height);
+ _surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height, "animated sprite");
}
void AnimatedSprite::createShadowSurface1(BaseSurface *shadowSurface, uint32 fileHash, int surfacePriority) {
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index 80da1768bd..1d17bf0e70 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -30,9 +30,24 @@
namespace Neverhood {
-#define SetSpriteUpdate(callback) _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback); debug(2, "SetSpriteUpdate(" #callback ")"); _spriteUpdateCbName = #callback
-#define SetFilterX(callback) _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback); debug(2, "SetFilterX(" #callback ")")
-#define SetFilterY(callback) _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback); debug(2, "SetFilterY(" #callback ")")
+#define SetSpriteUpdate(callback) \
+ do { \
+ _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback); \
+ debug(2, "SetSpriteUpdate(" #callback ")"); \
+ _spriteUpdateCbName = #callback; \
+ } while (0)
+
+#define SetFilterX(callback) \
+ do { \
+ _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback); \
+ debug(2, "SetFilterX(" #callback ")"); \
+ } while (0)
+
+#define SetFilterY(callback) \
+ do { \
+ _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback); \
+ debug(2, "SetFilterY(" #callback ")"); \
+ } while (0)
const int16 kDefPosition = -32768;
@@ -113,7 +128,11 @@ protected:
#define AnimationCallback(callback) static_cast <void (AnimatedSprite::*)()> (callback)
#define GotoState(callback) gotoState(static_cast <void (AnimatedSprite::*)()> (callback))
-#define NextState(callback) _nextStateCb = static_cast <void (AnimatedSprite::*)(void)> (callback); debug(2, "NextState(" #callback ")"); _nextStateCbName = #callback
+#define NextState(callback) \
+ do { \
+ _nextStateCb = static_cast <void (AnimatedSprite::*)(void)> (callback); \
+ debug(2, "NextState(" #callback ")"); _nextStateCbName = #callback; \
+ } while (0)
#define FinalizeState(callback) setFinalizeState(static_cast <void (AnimatedSprite::*)()> (callback));
const int STICK_LAST_FRAME = -2;
diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp
index 3f89c2236f..ec9c852118 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);
@@ -53,6 +53,22 @@ void StaticData::load(const char *filename) {
messageItem.messageValue = fd.readUint32LE();
messageList->push_back(messageItem);
}
+
+ // WORKAROUND for a problem in two of the game's message lists:
+ // the message lists used when Klaymen is drinking the wrong potion
+ // have as a last element the animation itself (message 0x4832).
+ // However, when processMessageList() reaches the last element in a
+ // message list, it allows player input, which means that the player
+ // can erroneously skip these potion drinking animations. We insert
+ // another message at the end of these lists to prevent player input
+ // till the animations are finished
+ if (id == 0x004AF0C8 || id == 0x004B5BD0) { // wrong potion message lists
+ MessageItem messageItem;
+ messageItem.messageNum = 0x4004; // set Klaymen's state to idle
+ messageItem.messageValue = 0;
+ messageList->push_back(messageItem);
+ }
+
_messageLists[id] = messageList;
}
@@ -84,7 +100,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/neverhood/todo.txt b/engines/neverhood/todo.txt
deleted file mode 100644
index 9d781e06ec..0000000000
--- a/engines/neverhood/todo.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-NOTE:
--------
-Some of the TODOs should be done AFTER the whole game logic is implemented
-else the game disasm and reimplemtation code become even more different
-(unless I decide it's ok to do it :)
-
-TODOs which can be done any time:
------------------------------------
-- Cleanup
-- Clean up staticdata structs to look more like the ones in create_neverhood
- (e.g. by using template classes etc.)
- - Or use a common base class and manage all stuff in one single table and cast stuff accordingly
-
-TODOs which should be done only after the game logic is finished:
--------------------------------------------------------------------
-- Maybe rework organization of files (e.g. put ALL Sprites into one separate file, same with Modules and Scenes)
- - This would solve the problem of how to organize stuff which is used several times, and less headers would have to be included
- - The move special scenes (SmackerScene) into the scenes file
-
-DONE:
--------
-- Implement game menus
-- Rework sound system (I don't like that SoundResources need to be explicitly initialized in Scene constructors)
- - Should be just a handle object which initializes itself
- - Play routine should fill the handle so it can be stopped/queried later
- - Basically like ScummVM own sound handles
-- RE and implement yet unknown music/sound stuff
-- Implement clever sprite redrawing code (dirty rectangles, microtiles etc.), only redraw what's neccessary
-- Rework the resource system
- - The current system can be simplified a lot
- - Also resource purging needs to be implemented
-- Maybe merge CollisionMan with Scene (since it's so far never used independently)
-- Give placeholder stuff (e.g. sub?????, _flag??? etc.) better fitting names
-- Use CursorMan for the mouse cursor (instead of using it like a normal sprite)
- - This whould make it neccessary to call _system->updateScreen more often else
- the mouse movement would be choppy
-
-TODOs which are experimental:
--------------------------------
-NOTE: Since they affect the whole game, they really should be only implemented once the full game logic is implemented.
-These are nothing more than wild ideas for now, any might never be implemented.
-- Use states instead of separate callback methods
-- Try to move more stuff to neverhood.dat
-- Try to use more template functions instead of manually creating functions
- (Can be coupled with the above to move parameters to the dat and only use IDs)
diff --git a/engines/parallaction/POTFILES b/engines/parallaction/POTFILES
new file mode 100644
index 0000000000..f3b1c45afa
--- /dev/null
+++ b/engines/parallaction/POTFILES
@@ -0,0 +1 @@
+engines/parallaction/saveload.cpp
diff --git a/engines/parallaction/configure.engine b/engines/parallaction/configure.engine
new file mode 100644
index 0000000000..babca4579f
--- /dev/null
+++ b/engines/parallaction/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine parallaction "Parallaction" yes
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 25acac9b06..4a8f8c71d7 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -62,8 +62,8 @@ void Debugger::postEnter() {
bool Debugger::Cmd_Location(int argc, const char **argv) {
- const char *character = _vm->_char.getName();
- const char *location = _vm->_location._name;
+ const char *character; // = _vm->_char.getName();
+ const char *location; // = _vm->_location._name;
char tmp[PATH_LEN];
diff --git a/engines/parallaction/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.h b/engines/parallaction/exec.h
index b966d677cd..5968954ba0 100644
--- a/engines/parallaction/exec.h
+++ b/engines/parallaction/exec.h
@@ -62,7 +62,7 @@ struct ProgramContext {
AnimationPtr _anim;
ProgramPtr _program;
InstructionPtr _inst;
- uint32 _ip;
+ uint32 _ip;
uint16 _modCounter;
bool _suspend;
};
diff --git a/engines/parallaction/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/font.cpp b/engines/parallaction/font.cpp
index 03b1ced8e1..627c6ebe22 100644
--- a/engines/parallaction/font.cpp
+++ b/engines/parallaction/font.cpp
@@ -518,6 +518,9 @@ AmigaFont::AmigaFont(Common::SeekableReadStream &stream) {
_charSpace = 0;
_charKern = 0;
+ _cp = 0;
+ _pitch = 0;
+
if (_font->_charSpace != 0)
_charSpace = (uint16 *)(_data + FROM_BE_32(_font->_charSpace));
if (_font->_charKern != 0)
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index b8a8ceb61f..dca1870cb7 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -218,7 +218,7 @@ void Palette::rotate(uint first, uint last, bool forward) {
-void Gfx::setPalette(Palette pal) {
+void Gfx::setPalette(Palette &pal) {
byte sysPal[256*3];
uint n = pal.fillRGB(sysPal);
@@ -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/graphics.h b/engines/parallaction/graphics.h
index 55c1c0c04e..401e753775 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -138,7 +138,7 @@ public:
}
Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false)
- : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) {
+ : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData), field_8(0) {
}
@@ -465,7 +465,7 @@ public:
void invertBackground(const Common::Rect& r);
// palette
- void setPalette(Palette palette);
+ void setPalette(Palette &palette);
void setBlackPalette();
void animatePalette();
diff --git a/engines/parallaction/gui.h b/engines/parallaction/gui.h
index a6eed240c4..9f2e96475b 100644
--- a/engines/parallaction/gui.h
+++ b/engines/parallaction/gui.h
@@ -43,7 +43,7 @@ class MenuInputHelper {
MenuInputState *_newState;
public:
- MenuInputHelper() : _state(0) {
+ MenuInputHelper() : _state(0), _newState(0) {
}
~MenuInputHelper();
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index ddbc31d730..2ec5ba6e8d 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -196,6 +196,11 @@ class MainMenuInputState_BR : public MenuInputState {
public:
MainMenuInputState_BR(Parallaction_br *vm, MenuInputHelper *helper) : MenuInputState("mainmenu", helper), _vm(vm) {
memset(_lines, 0, sizeof(_lines));
+
+ _menuStrings = 0;
+ _options = 0;
+ _availItems = 0;
+ _selection = 0;
}
~MainMenuInputState_BR() {
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index 082c37f666..ae32a416e3 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -117,6 +117,7 @@ public:
_allowChoice = false;
_nextState = "selectgame";
_label = 0;
+ _blocks = 0;
_dosLanguageSelectBlocks[0] = Common::Rect( 80, 110, 128, 180 ); // Italian
_dosLanguageSelectBlocks[1] = Common::Rect( 129, 85, 177, 155 ); // French
@@ -414,7 +415,7 @@ class SelectCharacterInputState_NS : public MenuInputState {
#define CHAR_DONNA 1
#define CHAR_DOUGH 2
- Common::Rect _codeSelectBlocks[9];
+ Common::Rect _codeSelectBlocks[9];
Common::Rect _codeTrueBlocks[9];
Parallaction_ns *_vm;
diff --git a/engines/parallaction/input.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/input.h b/engines/parallaction/input.h
index a815469ec3..a303eb96c8 100644
--- a/engines/parallaction/input.h
+++ b/engines/parallaction/input.h
@@ -114,7 +114,7 @@ public:
void trackMouse(ZonePtr z);
void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
uint32 getLastButtonEvent() { return _mouseButtons; }
- bool getLastKeyDown(uint16 &ascii);
+ bool getLastKeyDown(uint16 &ascii);
void stopHovering();
diff --git a/engines/parallaction/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/parallaction/objects.h b/engines/parallaction/objects.h
index 81761b2c6b..89e8134431 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -147,7 +147,7 @@ typedef Common::List<CommandPtr> CommandList;
struct Answer {
Common::String _text;
uint16 _mood;
- Common::String _followingName;
+ Common::String _followingName;
CommandList _commands;
uint32 _noFlags;
@@ -188,7 +188,7 @@ struct Dialogue {
~Dialogue();
};
-#define MAX_WALKPOINT_LISTS 20
+#define MAX_WALKPOINT_LISTS 20
#define FREE_HEAR_CHANNEL -1
#define MUSIC_HEAR_CHANNEL -2
@@ -452,7 +452,7 @@ struct Program {
uint16 _numLocals;
uint32 _ip;
- uint32 _loopStart;
+ uint32 _loopStart;
InstructionList _instructions;
uint32 _status;
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index f868abfbf4..e7be1eb8a3 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -59,6 +59,33 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
DebugMan.addDebugChannel(kDebugAudio, "audio", "Audio debug level");
DebugMan.addDebugChannel(kDebugMenu, "menu", "Menu debug level");
DebugMan.addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
+
+ _screenHeight = 0;
+ _screenSize = 0;
+ _gameType = 0;
+ _gfx = 0;
+ _disk = 0;
+ _input = 0;
+ _debugger = 0;
+ _saveLoad = 0;
+ _menuHelper = 0;
+ _soundMan = 0;
+ _labelFont = 0;
+ _menuFont = 0;
+ _introFont = 0;
+ _dialogueFont = 0;
+ _globalFlagsNames = 0;
+ _objectsNames = 0;
+ _objects = 0;
+ _callableNames = 0;
+ _localFlagNames = 0;
+ _cmdExec = 0;
+ _programExec = 0;
+ _balloonMan = 0;
+ _inventoryRenderer = 0;
+ _inventory = 0;
+ _currentLocationIndex = 0;
+ _numLocations = 0;
}
Parallaction::~Parallaction() {
@@ -882,6 +909,9 @@ void CharacterName::dummify() {
CharacterName::CharacterName() {
dummify();
+
+ _suffix = 0;
+ _prefix = 0;
}
CharacterName::CharacterName(const char *name) {
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 2dbb0227d6..203a0168ea 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -360,7 +360,7 @@ public:
uint32 getLocationFlags();
bool checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y);
bool checkZoneBox(ZonePtr z, uint32 type, uint x, uint y);
- bool checkZoneType(ZonePtr z, uint32 type);
+ bool checkZoneType(ZonePtr z, uint32 type);
bool checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y);
ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
void runZone(ZonePtr z);
@@ -579,7 +579,7 @@ private:
void freeLocation(bool removeAll);
void loadProgram(AnimationPtr a, const char *filename);
void startGui(bool showSplash);
- void startIngameMenu();
+ void startIngameMenu();
void freeCharacter();
typedef void (Parallaction_br::*Callable)(void *);
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index f9df9d85db..586e4bbd6a 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -45,6 +45,18 @@ const char *Parallaction_br::_partNames[] = {
Parallaction_br::Parallaction_br(OSystem* syst, const PARALLACTIONGameDescription *gameDesc) : Parallaction(syst, gameDesc),
_locationParser(0), _programParser(0), _soundManI(0) {
+ _audioCommandsNamesRes = 0;
+ _part = 0;
+ _nextPart = 0;
+ _subtitleY = 0;
+ _subtitle[0] = 0;
+ _subtitle[1] = 0;
+ _charInventories[0] = 0;
+ _charInventories[1] = 0;
+ _charInventories[2] = 0;
+ _countersNames = 0;
+ _callables = 0;
+ _walker = 0;
}
Common::Error Parallaction_br::init() {
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 49b63dcac3..91e8c78fc2 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -145,6 +145,18 @@ void LocationName::bind(const char *s) {
Parallaction_ns::Parallaction_ns(OSystem* syst, const PARALLACTIONGameDescription *gameDesc) : Parallaction(syst, gameDesc),
_locationParser(0), _programParser(0), _walker(0) {
+ _soundManI = 0;
+ _score = 0;
+ _inTestResult = 0;
+ _callables = 0;
+ num_foglie = 0;
+ _sarcophagusDeltaX = 0;
+ _movingSarcophagus = 0;
+ _freeSarcophagusSlotX = 0;
+ _intro = 0;
+
+ _testResultLabels[0] = 0;
+ _testResultLabels[1] = 0;
}
Common::Error Parallaction_ns::init() {
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index 3e2604eda2..622e507aad 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -207,6 +207,11 @@ protected:
public:
LocationParser_ns(Parallaction_ns *vm) : _vm(vm), _commandsNames(0), _locationStmt(0),
_locationZoneStmt(0), _locationAnimStmt(0) {
+ _script = 0;
+ _parser = 0;
+ _zoneTypeNames = 0;
+ _zoneFlagNames = 0;
+ _zoneProg = 0;
}
virtual void init();
@@ -292,14 +297,14 @@ public:
virtual void parseGetData(ZonePtr z);
virtual void parseDoorData(ZonePtr z);
virtual void parseHearData(ZonePtr z);
- virtual void parseNoneData(ZonePtr z);
+ virtual void parseNoneData(ZonePtr z);
protected:
void parseAnswerCounter(Answer *answer);
virtual Answer *parseAnswer();
public:
LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm),
- _audioCommandsNames(0) {
+ _audioCommandsNames(0), _out(0) {
}
virtual void init();
@@ -363,7 +368,7 @@ protected:
}
public:
- ProgramParser_ns(Parallaction_ns *vm) : _vm(vm), _parser(0), _instructionNames(0) {
+ ProgramParser_ns(Parallaction_ns *vm) : _vm(vm), _parser(0), _instructionNames(0), _script(0), _currentInstruction(0) {
}
virtual void init();
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index e12e50e278..e8dde78ddc 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -103,7 +103,7 @@ protected:
Audio::Mixer *_mixer;
char _musicFile[PATH_LEN];
- bool _sfxLooping;
+ bool _sfxLooping;
int _sfxVolume;
int _sfxRate;
uint _sfxChannel;
@@ -156,7 +156,7 @@ class AmigaSoundMan_ns : public SoundMan_ns {
Audio::AudioStream *_musicStream;
Audio::SoundHandle _musicHandle;
- uint32 beepSoundBufferSize;
+ uint32 beepSoundBufferSize;
int8 *beepSoundBuffer;
Channel _channels[NUM_SFX_CHANNELS];
@@ -188,7 +188,7 @@ protected:
Common::String _musicFile;
- bool _sfxLooping;
+ bool _sfxLooping;
int _sfxVolume;
int _sfxRate;
uint _sfxChannel;
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 4a643aaf1d..ea769de9e8 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -207,6 +207,7 @@ public:
void play(Common::SeekableReadStream *stream);
virtual void pause(bool p);
+ virtual void pause() { assert(0); } // overridden
virtual void setVolume(int volume);
virtual void onTimer();
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index 0ee3d73556..ed3031e94e 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -43,6 +43,7 @@ public:
void play(Common::SeekableReadStream *stream);
void pause(bool p);
+ virtual void pause() { assert(0); } // overridden
virtual void onTimer();
private:
diff --git a/engines/pegasus/POTFILES b/engines/pegasus/POTFILES
new file mode 100644
index 0000000000..c06cb07479
--- /dev/null
+++ b/engines/pegasus/POTFILES
@@ -0,0 +1 @@
+engines/pegasus/pegasus.cpp
diff --git a/engines/pegasus/configure.engine b/engines/pegasus/configure.engine
new file mode 100644
index 0000000000..ed7e295287
--- /dev/null
+++ b/engines/pegasus/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
diff --git a/engines/pegasus/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/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
index 1416c51c8d..0b95e9bc2b 100644
--- a/engines/pegasus/neighborhood/norad/delta/globegame.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
@@ -905,6 +905,11 @@ void GlobeGame::clickGlobe(const Input &input) {
_monitorMovie.start();
_owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut,
kFilterNoInput, kSpotSoundCompletedFlag);
+
+ // This sound was left out of the original.
+ _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut,
+ kFilterNoInput, kSpotSoundCompletedFlag);
+
_gameState = kPlayerWon1;
} else {
_owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag);
@@ -1060,12 +1065,13 @@ void GlobeGame::doSolve() {
_upperNamesMovie.hide();
_lowerNamesMovie.hide();
_countdown.hide();
- _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(), kMaxDeactivatedStop * _monitorMovie.getScale());
- _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale());
+ _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale() + (kSiloDeactivatedOut - kSiloDeactivatedIn), kMaxDeactivatedStop * _monitorMovie.getScale());
+ _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale() + (kSiloDeactivatedOut - kSiloDeactivatedIn));
_monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished);
_monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_monitorMovie.start();
_owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut, kFilterNoInput, kSpotSoundCompletedFlag);
+ _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut, kFilterNoInput, kSpotSoundCompletedFlag);
_gameState = kPlayerWon1;
}
diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
index f2ea53ff89..1eea2f0156 100644
--- a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
@@ -565,6 +565,11 @@ void NoradDelta::activateHotspots() {
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad59, kWest)) {
if (GameState.isCurrentDoorOpen())
_vm->getAllHotspots().deactivateOneHotspot(kNorad59WestSpotID);
+ } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
+ // WORKAROUND: Make sure the retinal hotspot is disabled after the door opens.
+ // Fixes a bug in the original.
+ if (GameState.isCurrentDoorOpen())
+ _vm->getAllHotspots().deactivateOneHotspot(kNorad68WestSpotID);
}
}
diff --git a/engines/pegasus/neighborhood/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/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
index 9b843da5d6..99efe10272 100644
--- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
@@ -2653,7 +2653,6 @@ void FullTSA::receiveNotification(Notification *notification, const Notification
GameState.setWSCAnalyzerOn(false);
GameState.setWSCDartInAnalyzer(false);
GameState.setWSCAnalyzedDart(false);
- GameState.setWSCPickedUpAntidote(false);
GameState.setWSCSawMorph(false);
GameState.setWSCDesignedAntidote(false);
GameState.setWSCOfficeMessagesOpen(false);
diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
index 4f109620c1..0d11f5d904 100644
--- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
@@ -337,7 +337,6 @@ void TinyTSA::receiveNotification(Notification *notification, const Notification
GameState.setWSCRemovedDart(false);
GameState.setWSCAnalyzerOn(false);
GameState.setWSCAnalyzedDart(false);
- GameState.setWSCPickedUpAntidote(false);
GameState.setWSCSawMorph(false);
GameState.setWSCDesignedAntidote(false);
GameState.setWSCOfficeMessagesOpen(false);
diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp
index 50b7774da4..09e2a48a52 100644
--- a/engines/pegasus/neighborhood/wsc/wsc.cpp
+++ b/engines/pegasus/neighborhood/wsc/wsc.cpp
@@ -2336,13 +2336,16 @@ Hotspot *WSC::getItemScreenSpot(Item *item, DisplayElement *element) {
void WSC::pickedUpItem(Item *item) {
switch (item->getObjectID()) {
case kAntidote:
+ // WORKAROUND: Make sure the poison is cleared separately from deactivating
+ // the synthesizer video.
+ GameState.setWSCPoisoned(false);
+ GameState.setWSCRemovedDart(false);
+ _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
+ playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
+ setUpPoison();
+
if (!GameState.getWSCPickedUpAntidote()) {
- GameState.setWSCPoisoned(false);
- GameState.setWSCRemovedDart(false);
GameState.setWSCPickedUpAntidote(true);
- _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
- playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
- setUpPoison();
startExtraSequence(kW03SouthDeactivate, kExtraCompletedFlag, kFilterNoInput);
}
break;
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index 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..5fb2551e7a 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())
@@ -333,6 +333,7 @@ void TimeBaseCallBack::releaseCallBack() {
void TimeBaseCallBack::disposeCallBack() {
_timeBase = 0;
+ _trigger = kTriggerNone;
_hasBeenTriggered = false;
}
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
deleted file mode 100644
index c68aa05e58..0000000000
--- a/engines/plugins_table.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// This file is being included by "base/plugins.cpp"
-#if PLUGIN_ENABLED_STATIC(SCUMM)
-LINK_PLUGIN(SCUMM)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGI)
-LINK_PLUGIN(AGI)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGOS)
-LINK_PLUGIN(AGOS)
-#endif
-#if PLUGIN_ENABLED_STATIC(CGE)
-LINK_PLUGIN(CGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(CINE)
-LINK_PLUGIN(CINE)
-#endif
-#if PLUGIN_ENABLED_STATIC(COMPOSER)
-LINK_PLUGIN(COMPOSER)
-#endif
-#if PLUGIN_ENABLED_STATIC(CRUISE)
-LINK_PLUGIN(CRUISE)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRACI)
-LINK_PLUGIN(DRACI)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRASCULA)
-LINK_PLUGIN(DRASCULA)
-#endif
-#if PLUGIN_ENABLED_STATIC(DREAMWEB)
-LINK_PLUGIN(DREAMWEB)
-#endif
-#if PLUGIN_ENABLED_STATIC(GOB)
-LINK_PLUGIN(GOB)
-#endif
-#if PLUGIN_ENABLED_STATIC(GROOVIE)
-LINK_PLUGIN(GROOVIE)
-#endif
-#if PLUGIN_ENABLED_STATIC(HOPKINS)
-LINK_PLUGIN(HOPKINS)
-#endif
-#if PLUGIN_ENABLED_STATIC(HUGO)
-LINK_PLUGIN(HUGO)
-#endif
-#if PLUGIN_ENABLED_STATIC(KYRA)
-LINK_PLUGIN(KYRA)
-#endif
-#if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
-LINK_PLUGIN(LASTEXPRESS)
-#endif
-#if PLUGIN_ENABLED_STATIC(LURE)
-LINK_PLUGIN(LURE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MADE)
-LINK_PLUGIN(MADE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MOHAWK)
-LINK_PLUGIN(MOHAWK)
-#endif
-#if PLUGIN_ENABLED_STATIC(NEVERHOOD)
-LINK_PLUGIN(NEVERHOOD)
-#endif
-#if PLUGIN_ENABLED_STATIC(PARALLACTION)
-LINK_PLUGIN(PARALLACTION)
-#endif
-#if PLUGIN_ENABLED_STATIC(PEGASUS)
-LINK_PLUGIN(PEGASUS)
-#endif
-#if PLUGIN_ENABLED_STATIC(QUEEN)
-LINK_PLUGIN(QUEEN)
-#endif
-#if PLUGIN_ENABLED_STATIC(SAGA)
-LINK_PLUGIN(SAGA)
-#endif
-#if PLUGIN_ENABLED_STATIC(SCI)
-LINK_PLUGIN(SCI)
-#endif
-#if PLUGIN_ENABLED_STATIC(SKY)
-LINK_PLUGIN(SKY)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD1)
-LINK_PLUGIN(SWORD1)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD2)
-LINK_PLUGIN(SWORD2)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD25)
-LINK_PLUGIN(SWORD25)
-#endif
-#if PLUGIN_ENABLED_STATIC(TEENAGENT)
-LINK_PLUGIN(TEENAGENT)
-#endif
-#if PLUGIN_ENABLED_STATIC(TESTBED)
-LINK_PLUGIN(TESTBED)
-#endif
-#if PLUGIN_ENABLED_STATIC(TINSEL)
-LINK_PLUGIN(TINSEL)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOLTECS)
-LINK_PLUGIN(TOLTECS)
-#endif
-#if PLUGIN_ENABLED_STATIC(TONY)
-LINK_PLUGIN(TONY)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOON)
-LINK_PLUGIN(TOON)
-#endif
-#if PLUGIN_ENABLED_STATIC(TSAGE)
-LINK_PLUGIN(TSAGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOUCHE)
-LINK_PLUGIN(TOUCHE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TUCKER)
-LINK_PLUGIN(TUCKER)
-#endif
-#if PLUGIN_ENABLED_STATIC(VOYEUR)
-LINK_PLUGIN(VOYEUR)
-#endif
-#if PLUGIN_ENABLED_STATIC(WINTERMUTE)
-LINK_PLUGIN(WINTERMUTE)
-#endif
diff --git a/engines/queen/POTFILES b/engines/queen/POTFILES
new file mode 100644
index 0000000000..1baf9c24de
--- /dev/null
+++ b/engines/queen/POTFILES
@@ -0,0 +1 @@
+engines/queen/queen.cpp
diff --git a/engines/queen/configure.engine b/engines/queen/configure.engine
new file mode 100644
index 0000000000..c8766743f9
--- /dev/null
+++ b/engines/queen/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine queen "Flight of the Amazon Queen" yes
diff --git a/engines/saga/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/configure.engine b/engines/saga/configure.engine
new file mode 100644
index 0000000000..99e2ab367b
--- /dev/null
+++ b/engines/saga/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine saga "SAGA" yes "ihnm saga2" "ITE"
+add_engine ihnm "IHNM" yes
+add_engine saga2 "SAGA 2 games" no
diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp
index d98cef0740..c5842f4998 100644
--- a/engines/saga/events.cpp
+++ b/engines/saga/events.cpp
@@ -533,6 +533,7 @@ int Events::handleOneShot(Event *event) {
default:
break;
}
+ break;
#ifdef ENABLE_IHNM
case kCutawayEvent:
switch (event->op) {
@@ -545,6 +546,7 @@ int Events::handleOneShot(Event *event) {
default:
break;
}
+ break;
#endif
case kActorEvent:
switch (event->op) {
@@ -554,6 +556,7 @@ int Events::handleOneShot(Event *event) {
default:
break;
}
+ break;
default:
break;
}
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_ite.cpp b/engines/saga/introproc_ite.cpp
index 484ebe1779..ed53e078a0 100644
--- a/engines/saga/introproc_ite.cpp
+++ b/engines/saga/introproc_ite.cpp
@@ -993,7 +993,7 @@ int Scene::ITEIntroTreeHouseProc(int param) {
}
// Queue game credits list
- eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
+ ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2);
// End scene after credit display
@@ -1073,7 +1073,7 @@ int Scene::ITEIntroFairePathProc(int param) {
_vm->_events->chain(eventColumns, event);
// Queue game credits list
- eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
+ ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2);
// End scene after credit display
diff --git a/engines/saga/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/saga.h b/engines/saga/saga.h
index 01cab21f5d..645e1c30d0 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -138,7 +138,7 @@ enum GameFileTypes {
enum GameFeatures {
GF_ITE_FLOPPY = 1 << 0,
#if 0
- GF_OLD_ITE_DOS = 1 << 1, // Currently unused
+ GF_OLD_ITE_DOS = 1 << 1, // Currently unused
#endif
GF_EXTRA_ITE_CREDITS = 1 << 2,
GF_8BIT_UNSIGNED_PCM = 1 << 3
diff --git a/engines/saga/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/saga/shorten.cpp b/engines/saga/shorten.cpp
index 69c27b6a6b..619ffc243e 100644
--- a/engines/saga/shorten.cpp
+++ b/engines/saga/shorten.cpp
@@ -196,11 +196,13 @@ byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, by
break;
case kTypeS16LH:
flags |= Audio::FLAG_LITTLE_ENDIAN;
+ // fallthrough
case kTypeS16HL:
flags |= Audio::FLAG_16BITS;
break;
case kTypeU16LH:
flags |= Audio::FLAG_LITTLE_ENDIAN;
+ // fallthrough
case kTypeU16HL:
flags |= Audio::FLAG_16BITS;
flags |= Audio::FLAG_UNSIGNED;
diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp
index 49d24753a1..ca843af465 100644
--- a/engines/saga/sndres.cpp
+++ b/engines/saga/sndres.cpp
@@ -249,11 +249,11 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff
if (!memcmp(header, "Creative", 8)) {
resourceType = kSoundVOC;
- } else if (!memcmp(header, "RIFF", 4) != 0) {
+ } else if (!memcmp(header, "RIFF", 4)) {
resourceType = kSoundWAV;
- } else if (!memcmp(header, "FORM", 4) != 0) {
+ } else if (!memcmp(header, "FORM", 4)) {
resourceType = kSoundAIFF;
- } else if (!memcmp(header, "ajkg", 4) != 0) {
+ } else if (!memcmp(header, "ajkg", 4)) {
resourceType = kSoundShorten;
}
diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp
index 2895c6800c..bf550659e9 100644
--- a/engines/saga/sprite.cpp
+++ b/engines/saga/sprite.cpp
@@ -71,17 +71,7 @@ Sprite::~Sprite() {
}
void Sprite::loadList(int resourceId, SpriteList &spriteList) {
- SpriteInfo *spriteInfo;
ByteArray spriteListData;
- uint16 oldSpriteCount;
- uint16 newSpriteCount;
- uint16 spriteCount;
- uint i;
- int outputLength, inputLength;
- uint32 offset;
- const byte *spritePointer;
- const byte *spriteDataPointer;
-
_vm->_resource->loadResource(_spriteContext, resourceId, spriteListData);
if (spriteListData.empty()) {
@@ -90,19 +80,19 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
ByteArrayReadStreamEndian readS(spriteListData, _spriteContext->isBigEndian());
- spriteCount = readS.readUint16();
+ uint16 spriteCount = readS.readUint16();
debug(9, "Sprites: %d", spriteCount);
- oldSpriteCount = spriteList.size();
- newSpriteCount = oldSpriteCount + spriteCount;
+ uint16 oldSpriteCount = spriteList.size();
+ uint16 newSpriteCount = oldSpriteCount + spriteCount;
spriteList.resize(newSpriteCount);
bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources();
- for (i = oldSpriteCount; i < spriteList.size(); i++) {
- spriteInfo = &spriteList[i];
+ for (uint i = oldSpriteCount; i < spriteList.size(); i++) {
+ uint32 offset;
if (bigHeader)
offset = readS.readUint32();
else
@@ -115,9 +105,11 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
return;
}
- spritePointer = spriteListData.getBuffer();
+ const byte *spritePointer = spriteListData.getBuffer();
spritePointer += offset;
+ const byte *spriteDataPointer;
+ SpriteInfo *spriteInfo = &spriteList[i];
if (bigHeader) {
Common::MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian());
@@ -139,8 +131,8 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
spriteDataPointer = spritePointer + readS2.pos();
}
- outputLength = spriteInfo->width * spriteInfo->height;
- inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer());
+ int outputLength = spriteInfo->width * spriteInfo->height;
+ int inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer());
spriteInfo->decodedBuffer.resize(outputLength);
if (outputLength > 0) {
decodeRLEBuffer(spriteDataPointer, inputLength, outputLength);
diff --git a/engines/sci/POTFILES b/engines/sci/POTFILES
new file mode 100644
index 0000000000..f076c292d9
--- /dev/null
+++ b/engines/sci/POTFILES
@@ -0,0 +1,2 @@
+engines/sci/detection.cpp
+engines/sci/engine/kfile.cpp
diff --git a/engines/sci/configure.engine b/engines/sci/configure.engine
new file mode 100644
index 0000000000..d1c45a4654
--- /dev/null
+++ b/engines/sci/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
+add_engine sci32 "SCI32 games" no
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 50fae61de0..80d8ab8257 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -3840,10 +3840,15 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.');
if (tmp != str_objname.end()) {
index = strtol(tmp + 1, &endptr, 16);
- if (*endptr)
- return -1;
- // Chop off the index
- str_objname = Common::String(str_objname.c_str(), tmp);
+ if (*endptr) {
+ // The characters after the dot do not represent an index.
+ // This can happen if an object contains a dot in its name,
+ // like 'dominoes.opt' in Hoyle 3.
+ index = -1;
+ } else {
+ // Valid index found, chop it off
+ str_objname = Common::String(str_objname.c_str(), tmp);
+ }
}
// Replace all underscores in the name with spaces
diff --git a/engines/sci/detection.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 fa7acaf4b8..05af2ff78c 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -50,7 +50,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474},
{"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.000"
@@ -62,7 +62,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380},
{"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes English language)
// Executable scanning reports "1.005.001"
@@ -74,7 +74,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309},
{"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain Macintosh (from omer_mor, bug report #3328251)
{"castlebrain", "", {
@@ -84,7 +84,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e1a6b6f1060f60be9dcb6d28ad7a2a20", 1168310},
{"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 891295},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.005
@@ -93,7 +93,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367},
{"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 5.25" Floppy EGA (from omer_mor, bug report #3035349)
{"castlebrain", "EGA", {
@@ -106,7 +106,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838},
{"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 3.5" Floppy EGA (from nozomi77, bug report #3405307)
{"castlebrain", "EGA", {
@@ -116,7 +116,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "de2f182529efaad2c4b510b452ab77ac", 633662},
{"resource.003", 0, "38b4b37febc6b4f5061c461a283df148", 430388},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000"
@@ -127,7 +127,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832},
{"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 5.25" Floppy VGA 1.1 (from rnjacobs, bug report #3578286)
{"castlebrain", "", {
@@ -137,7 +137,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "583d348c908f89f94f8551d7fe0a2eca", 991752},
{"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 728315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy 1.1
{"castlebrain", "", {
@@ -146,7 +146,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776},
{"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy 1.000
// Reported by graxer in bug report #3037942
@@ -161,7 +161,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "1d778a0c65cac9ddbab65495e50a94ee", 335281},
{"resource.007", 0, "063bb8ce4157c778cf30d1c912c006f1", 335631},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - Spanish DOS (also includes english language)
// SCI interpreter version 1.000.510
@@ -170,7 +170,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694},
{"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Inside the Chest / Behind the Developer's Shield
@@ -179,7 +179,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9dd015e79cac4f91e7de805448f39775", 1912},
{"resource.000", 0, "e4efcd042f86679dd4e1834bb3a38edb", 3770943},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
#endif
// Christmas Card 1988 - English DOS
@@ -188,7 +188,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426},
{"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors)
// SCI interpreter version 1.000.172
@@ -196,7 +196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600},
{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors)
// SCI interpreter version 1.000.174
@@ -204,7 +204,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600},
{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1992 - English DOS
// SCI interpreter version 1.001.055
@@ -212,7 +212,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318},
{"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.031"
@@ -226,7 +226,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382},
{"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.685"
@@ -234,7 +234,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056},
{"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033"
@@ -247,7 +247,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303},
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (from FRG)
// SCI interpreter version 0.000.668
@@ -259,7 +259,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118},
{"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (supplied by ssburnout in bug report #3049193)
// 1.022 9x5.25" (label: Int#0.000.668)
@@ -274,7 +274,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942},
{"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267811},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS 1.023 (from abevi, bug report #2612718)
{"iceman", "", {
@@ -288,7 +288,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942},
{"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.030"
@@ -303,7 +303,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882},
{"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.668
@@ -311,7 +311,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468},
{"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
@@ -323,7 +323,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS
// SCI interpreter version 0.000.685
@@ -337,7 +337,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446},
{"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.001"
@@ -352,7 +352,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002},
{"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS
// SCI interpreter version 1.000.510
@@ -366,7 +366,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.168", Floppy label reports "1.1, 1.13.92", VERSION file reports "1.1"
@@ -380,7 +380,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS
// SCI interpreter version 1.000.510
@@ -393,30 +393,32 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow EGA - English DOS
// SCI interpreter version 1.000.510
{"longbow", "EGA", {
- {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261},
- {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161},
- {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680},
- {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633},
- {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510},
- {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631},
- {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
- {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261},
+ {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161},
+ {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680},
+ {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633},
+ {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510},
+ {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631},
+ {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
+ {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow DOS 1.0 EGA (4 x 5.25" disks)
// Provided by ssburnout in bug report #3046802
{"longbow", "EGA", {
- {"resource.map", 0, "0517ca368ec844df0cb21a05020fae01", 6021},
- {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 934643},
- {"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133},
- {"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478},
- {"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ {"resource.map", 0, "0517ca368ec844df0cb21a05020fae01", 6021},
+ {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 934643},
+ {"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133},
+ {"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478},
+ {"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.510
@@ -424,7 +426,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588},
{"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681, also includes english language)
// SCI interpreter version 1.000.510
@@ -438,7 +440,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "x.yyy.zzz"
@@ -447,7 +449,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873},
{"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS CD 1.1
// SCI interpreter version 1.001.064
@@ -455,7 +457,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS CD 1.1
// SCI interpreter version 1.001.064
@@ -465,7 +467,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Floppy
// SCI interpreter version 1.000.510
@@ -476,7 +478,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816},
{"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Floppy
// SCI interpreter version 1.000.510
@@ -487,7 +489,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316},
{"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744, also includes english language)
// SCI interpreter version 1.000.510
@@ -498,7 +500,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - Spanish DOS Floppy (from jvprat, also includes english language)
// Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92"
@@ -510,7 +512,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - French DOS Floppy (from Strangerke, also includes english language)
// SCI interpreter version 1.ECO.013
@@ -521,7 +523,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872},
{"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.055
@@ -529,7 +531,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321},
{"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761)
// SCI interpreter version 1.001.065
@@ -537,7 +539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658},
{"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - French DOS Floppy (from Strangerke)
// SCI interpreter version 1.001.081
@@ -545,7 +547,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588},
{"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - Spanish DOS Floppy (supplied by umbrio in bug report #3313962)
{"ecoquest2", "Floppy", {
@@ -553,7 +555,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4209150},
{"resource.msg", 0, "eff8be1925d42288de55e405983e9314", 117810},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Eco Quest 2 - German DOS Floppy (supplied by frankenbuam in bug report #3615072)
+ {"ecoquest2", "Floppy", {
+ {"resource.map", 0, "d8b20073e64f41f6437f73143a186753", 5643},
+ {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4210876},
+ {"resource.msg", 0, "2f231d31af172ea72ed533fd112f971b", 133458},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
@@ -561,7 +571,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909},
{"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English CD DOS (from FRG)
// SCI interpreter version 1.001.132
@@ -569,7 +579,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058},
{"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720)
// Executable scanning reports "1.cfs.081"
@@ -579,7 +589,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - French DOS Floppy (supplied by misterhands in bug report #3589449)
// Executable scanning reports "1.cfs.081"
@@ -588,7 +598,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230},
{"resource.msg", 0, "4dc478f5c73b57e5d690bdfffdcf1c44", 816518},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Windows (supplied by abevi in bug report #2612718)
// Executable scanning reports "1.cfs.081"
@@ -597,7 +607,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816},
{"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720)
// Executable scanning reports "1.cfs.081"
@@ -607,7 +617,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Spanish DOS (from jvprat)
// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995"
@@ -620,7 +630,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310},
{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Spanish DOS (from jvprat)
// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995"
@@ -630,7 +640,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS CD Demo
// SCI interpreter version 1.001.095
@@ -638,14 +648,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918},
{"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English Macintosh
{"freddypharkas", "", {
{"Data1", 0, "ef7cbd62727989818f1cfae69c9fd61d", 3038492},
{"Data2", 0, "2424b418f7d52c385cea4701f529c69a", 4721732},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Fun Seeker's Guide - English DOS
// SCI interpreter version 0.000.506
@@ -653,7 +663,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282},
{"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS CD Demo
// SCI interpreter version 1.001.092
@@ -661,7 +671,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490},
{"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Gabriel Knight - English DOS CD Demo (from DrMcCoy)
+ // SCI interpreter version 1.001.092
+ {"gk1", "CD Demo", {
+ {"resource.map", 0, "8cad2a256f41463030cbb7ea1bfb2857", 2490},
+ {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Gabriel Knight - English DOS Floppy
@@ -670,7 +688,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777)
// SCI interpreter version 2.000.000
@@ -678,7 +696,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS Floppy
// SCI interpreter version 2.000.000, VERSION file reports "1.0\nGabriel Knight\n11/22/10:33 pm\n\x1A"
@@ -686,7 +704,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ef41df08cf2c1f680216cdbeed0f8311", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775)
// SCI interpreter version 2.000.000
@@ -694,7 +712,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - French DOS Floppy (supplied my kervala in bug report #3611487)
// SCI interpreter version 2.000.000
@@ -702,7 +720,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "236e36cc847cdeafdd5e5fa8cba916ed", 10801},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13033072},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -710,7 +728,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -718,7 +736,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German DOS CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -726,7 +744,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -734,7 +752,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - French DOS CD (from Hkz)
// VERSION file reports "1.000.000, May 3, 1994"
@@ -742,7 +760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German Windows CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -750,7 +768,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -758,7 +776,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English Macintosh
{"gk1", "", {
@@ -767,7 +785,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data3", 0, "f25068b408b09275d8b698866462f578", 3677599},
{"Data4", 0, "1cceebbe411b26c860a74f91c337fdf3", 3230086},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English Windows Non-Interactive Demo
// Executable scanning reports "2.100.002"
@@ -775,7 +793,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351},
{"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// using Enrico Rolfi's HD/DVD installer: http://gkpatches.vogons.zetafleet.com/
@@ -783,7 +801,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "b996fa1e57389a1e179a00a0049de1f4", 8110},
{"ressci.000", 0, "a19fc3604c6e5407abcf03d59ee87217", 168522221},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.1"
@@ -801,7 +819,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977},
{"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -819,7 +837,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001},
{"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English Macintosh
// NOTE: This only contains disc 1 files (as well as the persistent file:
@@ -831,7 +849,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data4", 0, "8b843c62eb53136a855d6e0087e3cb0d", 5889553},
{"Data5", 0, "f9fcf9ab2eb13b2125c33a1cda03a093", 14349984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
@@ -843,7 +861,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342149},
{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 - English DOS (supplied by wibble92 in bug report #2644547)
// SCI interpreter version 0.000.530
@@ -853,7 +871,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309},
{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 - English DOS (supplied by merkur in bug report #2719227)
// SCI interpreter version 0.000.530
@@ -861,14 +879,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 3.5' - English DOS (supplied by eddydrama in bug report #3052366 and dinnerx in bug report #3090841)
{"hoyle1", "", {
{"resource.map", 0, "0af9a3dcd72a091960de070432e1f524", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518127},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#if 0 // TODO: unknown if these files are corrupt
// Hoyle 1 - English Amiga (from www.back2roots.org)
@@ -878,7 +896,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755},
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Hoyle 2 - English DOS
@@ -888,7 +906,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138},
{"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 1x3.5" (label:Int#6.21.90)
@@ -896,7 +914,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "db0ba08b953e9904a4960ad99cd29c20", 1356},
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 216315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -905,7 +923,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356},
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
@@ -913,7 +931,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1af1d3aa3cf564f93477c9f87e53f495", 1728},
{"resource.001", 0, "b73b8131669d69d41a326415e4519138", 482882},
{NULL, 0, NULL, 0}},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#if 0 // TODO: unknown if these files are corrupt
// Hoyle 3 - English Amiga (from www.back2roots.org)
@@ -924,7 +942,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791},
{"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Hoyle 3 - English DOS Non-Interactive Demo
@@ -934,7 +952,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735},
{"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 - English DOS Floppy (from jvprat)
// Executable scanning reports "x.yyy.zzz", Floppy label reports "1.0, 11.2.91", VERSION file reports "1.000"
@@ -944,7 +962,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 - English DOS Floppy (supplied by eddydrama in bug report #3038837)
{"hoyle3", "", {
@@ -955,7 +973,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "97cfd72633f8f9b2a0b1d4116cf3ee81", 346116},
{"resource.004", 0, "2884fb91b225fabd9ca87ea231293b48", 351218},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 EGA - English DOS Floppy 1.0 (supplied by abevi in bug report #2612718)
{"hoyle3", "EGA", {
@@ -963,14 +981,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 319905},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 526438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo
{"hoyle4", "Demo", {
{"resource.map", 0, "60f764020a6b788bbbe415dbc2ccb9f3", 931},
{"resource.000", 0, "5fe3670e3ddcd4f85c10013b5453141a", 615522},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo
// SCI interpreter version 1.001.200 (just a guess)
@@ -979,7 +997,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938},
{"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS/Win
// Supplied by abevi in bug report #3039291
@@ -987,7 +1005,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2b577c975cc8d8d43f61b6a756129fe3", 4352},
{"resource.000", 0, "43e2c15ce436aab611a462ad0603e12d", 2000132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English Macintosh Floppy
// VERSION file reports "2.0"
@@ -995,7 +1013,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "99575fae4579540a314bbedd72d51e8c", 7682887},
{"Data2", 0, "7d4bf5bdf3c02edbf35cb8471c84ec13", 1539134},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane EGA - English DOS
// SCI interpreter version 1.000.172 (not 100% sure FIXME)
@@ -1004,14 +1022,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 202105},
{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 341771},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane EGA - English DOS (supplied by EddyDrama in bug report #3038761)
{"jones", "EGA", {
{"resource.map", 0, "8e92cf319180cc8b5b87b2ce93a4fe22", 1602},
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 511528},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane VGA - English DOS
// SCI interpreter version 1.000.172
@@ -1020,7 +1038,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476},
{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane VGA - English DOS (supplied by omer_mor in bug report #3037054)
// VERSION file reports "1.000.060"
@@ -1028,14 +1046,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "db175ab494ab0666f19ab8f2597a8e49", 1602},
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 994487},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane - English DOS CD
{"jones", "CD", {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
// Jones in the Fast Lane - English DOS CD
// Same entry as the DOS version above. This one is used for the alternate
@@ -1044,7 +1062,24 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
+
+ // Jones in the Fast Lane - English DOS US CD (alternate version)
+ // Supplied by collector9 in bug #3614668
+ {"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"
@@ -1056,7 +1091,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224},
{"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS Non-Interactive Demo
// Executable scanning reports "S.old.010"
@@ -1064,7 +1099,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954},
{"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection)
// Executable scanning reports "S.old.010", VERSION file reports "1.000.051"
@@ -1075,7 +1110,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062},
{"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.051 9x5.25" (label: INT#9.19.90)
@@ -1089,7 +1124,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "fed9e0072ffd511d248674e60dee2099", 351062},
{"resource.007", 0, "fed9e0072ffd511d248674e60dee2099", 330472},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -1102,7 +1137,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016},
{"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.494"
@@ -1110,7 +1145,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594},
{"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (original boxed release, 3 1/2" disks)
// SCI interpreter version 0.000.247
@@ -1121,7 +1156,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 683145},
{"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 649441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (from the King's Quest Collection)
// Executable scanning reports "0.000.502"
@@ -1133,7 +1168,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591},
{"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.006.003 8x5.25" (label: Int.#0.000.502)
@@ -1147,7 +1182,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "6db7de6f93c6ea62dca78abee677f8c0", 324789},
{"resource.007", 0, "6db7de6f93c6ea62dca78abee677f8c0", 334441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.274
@@ -1161,7 +1196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777},
{"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.253
@@ -1175,7 +1210,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288},
{"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English Atari ST (double-sided diskettes)
// Game version 1.003.006 (January 12, 1989)
@@ -1188,7 +1223,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a3cdb4848fb859fdd302976fff56490f", 705074},
{"resource.004", 0, "a3cdb4848fb859fdd302976fff56490f", 478366},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.004.018"
@@ -1204,7 +1239,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048},
{"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -1220,7 +1255,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099},
{"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Italian Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -1236,7 +1271,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527},
{"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052"
@@ -1246,7 +1281,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052"
@@ -1258,7 +1293,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy
// SCI interpreter version 1.000.060
@@ -1273,7 +1308,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619},
{"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy
// VERSION file reports "0.000.051"
@@ -1291,7 +1326,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456},
{"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy (supplied by omer_mor in bug report #3036996)
// VERSION file reports "0.000.051"
@@ -1306,7 +1341,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "06cb3f689836086ebe08b1efc0126592", 921113},
{"resource.007", 0, "252249753c6e850eacceb8af634986d3", 1133608},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA (supplied by markcoolio in bug report #2829470)
// SCI interpreter version 1.000.060
@@ -1322,7 +1357,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666527},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541743},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA 1.2M disk version (from LordHoto)
// VERSION file reports "0.000.055"
@@ -1334,7 +1369,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "53206afb4fd73871a484e83acab80f31", 7608},
{"resource.004", 0, "83568edf7fde18b3eed988bc5d22ceb1", 1188053},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA (supplied by omer_mor in bug report #3035421)
// VERSION file reports "0.000.062"
@@ -1349,7 +1384,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest V DOS 0.000.062 EGA (5 x 5.25" disks)
// Supplied by ssburnout in bug report #3046780
@@ -1361,7 +1396,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 1092325},
{"resource.004", 0, "8e5c1bc4d738cf7316ff506f59d265e2", 1187803},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 DOS Spanish Floppy 0.000.062 VGA (5 x 3.5" disks)
// Supplied by dianiu in bug report #3555646
@@ -1376,7 +1411,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "65b520e60c4217e6a6572d9edf77193b", 1141985},
{"resource.007", 0, "f42b0100f0a1c30806814f8648b6bc28", 1145583},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101, also includes english language)
// SCI interpreter version 1.000.060
@@ -1391,7 +1426,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972},
{"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994, also includes english language)
// Supplied by aroenai in bug report #2812611
@@ -1407,7 +1442,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081},
{"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Italian DOS Floppy (from glorifindel, includes english language)
// SCI interpreter version 1.000.060
@@ -1422,7 +1457,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325},
{"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722)
// SCI interpreter version 1.000.060
@@ -1440,7 +1475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176},
{"text.000", 0, "601aa35a3ddeb558e1280e0963e955a2", 1517},
AD_LISTEND},
- Common::PL_POL, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English Macintosh
// VERSION file reports "1.000.055"
@@ -1455,7 +1490,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "3d22904a374c192f51e5665b74364133", 1264079},
{"resource.007", 0, "ffe17e23d5833a79f3695addfc149a56", 1361965},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - FM-Towns (supplied by abevi in bug report #3038720)
{"kq5", "", {
@@ -1463,7 +1498,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
{"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
{"kq5", "", {
{"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733},
{"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
@@ -1481,7 +1516,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "e114ce8f884601c43308fb5cbbea4874", 1174129},
{"resource.005", 0, "349ad9438172265d00680075c5a988d0", 1019669},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English DOS Non-Interactive Demo
// Executable scanning reports "1.001.055", VERSION file reports "1.000.000"
@@ -1491,7 +1526,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116},
{"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English DOS Floppy
// SCI interpreter version 1.001.054
@@ -1500,7 +1535,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - French DOS Floppy (supplied by misterhands in bug #3503425)
// SCI interpreter version ???
@@ -1509,7 +1544,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "adc2aa8adbdcc97507d44a6f492fbd77", 265194},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156)
// SCI interpreter version 1.001.054
@@ -1518,7 +1553,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - Spanish DOS Floppy (from jvprat)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994"
@@ -1528,7 +1563,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260},
{"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - Italian DOS Floppy (supplied by guybrush79 in bug report #3606719)
{"kq6", "", {
@@ -1536,7 +1571,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "d3358ba7306378aed83d02b5c3f11311", 8531908},
{"resource.msg", 0, "b7e8220be596fd6a9287eae5a8fd354a", 279886},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G"
@@ -1545,7 +1580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English Windows CD (from the King's Quest Collection)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G"
@@ -1554,7 +1589,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_NOASPECT, GAMEOPTION_KQ6_WINDOWS_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_NOASPECT, GAMEOPTION_KQ6_WINDOWS_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English Macintosh Floppy
// VERSION file reports "1.0"
@@ -1562,7 +1597,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "a183fc0c22fcbd9be4c8800d974b5599", 3892124},
{"Data2", 0, "b3722460dfd3097a1fbaf99a21ad8ea5", 15031272},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
@@ -1573,7 +1608,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195},
{"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English Windows (from the King's Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.4"
@@ -1581,7 +1616,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English DOS (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1589,7 +1624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English Windows (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1597,7 +1632,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402)
// SCI interpreter version 2.100.002
@@ -1605,7 +1640,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - Spanish DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "2.00"
@@ -1613,7 +1648,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English DOS Non-Interactive Demo
// SCI interpreter version 2.100.002
@@ -1621,7 +1656,23 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690},
{"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // King's Quest 7 - English Windows Demo (from DrMcCoy)
+ // SCI interpreter version 2.100.002
+ {"kq7", "Demo", {
+ {"resource.map", 0, "38e627a37a975aea40cc72b0518b0709", 18412},
+ {"resource.000", 0, "bad61d50aaa64298fa57a7c6ccd3bccf", 84020382},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // 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
@@ -1637,7 +1688,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067},
{"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English Atari ST (from jvprat)
// Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90"
@@ -1649,7 +1700,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1657,7 +1708,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768},
{"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996)
// SCI interpreter version 0.000.631
@@ -1668,7 +1719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS (from FRG)
// SCI interpreter version 0.000.631
@@ -1682,7 +1733,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390},
{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "x.yyy.zzz"
@@ -1691,7 +1742,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855},
{"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS Floppy
// Executable scanning reports "2.000.274"
@@ -1700,7 +1751,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489},
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996)
// Executable scanning reports "1.001.072", VERSION file reports "1.1" (from jvprat)
@@ -1709,7 +1760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274},
{"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 v1.1 - French DOS Floppy (from Hkz)
{"laurabow2", "", {
@@ -1717,7 +1768,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "0fceedfbdd85a4bc7851fdd9dd2d2f19", 278253},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962))
// Executable scanning reports "2.000.274"
@@ -1726,7 +1777,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994"
@@ -1735,7 +1786,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 EGA Remake - English DOS (from spookypeanut)
// SCI interpreter version 0.000.510 (or 0.000.577?)
@@ -1746,7 +1797,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230},
{"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#if 0
// The resource.002 file, contained in disk 3, is broken in this version
@@ -1764,7 +1815,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041},
{"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Larry 1 VGA Remake - English DOS (from spookypeanut)
@@ -1775,7 +1826,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226},
{"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English DOS (from FRG)
// SCI interpreter version 1.000.510
@@ -1785,7 +1836,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688},
{"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English Macintosh (from omer_mor, bug report #3328262)
{"lsl1sci", "SCI", {
@@ -1794,7 +1845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "aa6f153f70f1e32d1bde465fff08eecf", 1137418},
{"resource.002", 0, "b22c616aa789ebef990290c7ffd86548", 1097477},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.084
@@ -1802,7 +1853,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444},
{"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection, also includes english language)
// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000"
@@ -1815,7 +1866,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908},
{"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Russian DOS (also includes english language?!)
// Executable scanning reports "1.000.510", VERSION file reports "2.0"
@@ -1826,7 +1877,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759},
{"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Polish DOS (from Polish Leisure Suit Larry Collection, official release)
// SCI interpreter version 1.000.577, VERSION file reports "2.1" (this release does NOT include english text)
@@ -1834,7 +1885,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "58330a85767e42a2487129913283ab5b", 3228},
{"resource.000", 0, "b6097ff35cdc8469f02150fe2f824198", 4781210},
AD_LISTEND},
- Common::PL_POL, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::PL_POL, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English Amiga (from www.back2roots.org)
// Executable scanning reports "x.yyy.zzz"
@@ -1846,7 +1897,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356},
{"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1855,7 +1906,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528},
{"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.409
@@ -1868,7 +1919,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732},
{"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.343
@@ -1883,7 +1934,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
//{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818},
{"resource.006", 0, "96033f57accfca903750413fd09193c8", -1}, // 345818 or 208739
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 3x3.5" (label: Int. #0.000.343)
@@ -1893,7 +1944,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "96033f57accfca903750413fd09193c8", 407014},
{"resource.003", 0, "96033f57accfca903750413fd09193c8", 592834},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.002.000 3x3.5" (label: INT#0.000.409)
@@ -1903,7 +1954,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406935},
{"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592533},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -1917,7 +1968,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634},
{"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.021 8x5.25" (label: Int#5.15.90)
@@ -1931,7 +1982,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282649},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257178},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS
// SCI interpreter version 0.000.572
@@ -1945,7 +1996,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282465},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257174},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS
// SCI interpreter version 0.000.572
@@ -1956,7 +2007,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f18441027154292836b973c655fa3175", 506807},
{"resource.004", 0, "f18441027154292836b973c655fa3175", 513651},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS (supplied by kervala in bug report #3611488)
{"lsl3", "", {
@@ -1966,7 +2017,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f18441027154292836b973c655fa3175", 506817},
{"resource.004", 0, "f18441027154292836b973c655fa3175", 513337},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.530
@@ -1975,7 +2026,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525},
{"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832, also includes english language)
// Executable scanning reports "S.old.123"
@@ -1987,7 +2038,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036},
{"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language)
// Executable scanning reports "S.old.123"
@@ -1999,7 +2050,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921},
{"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 1.050 Fr/En (9 x 5.25" disks)
// Provided by ssburnout in bug report #3046779
@@ -2013,7 +2064,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "65f1bdaa20f6d0470e9d969f22473873", 325292},
{"resource.007", 0, "65f1bdaa20f6d0470e9d969f22473873", 308982},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English Amiga
// Executable scanning reports "1.004.023"
@@ -2028,7 +2079,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621},
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -2044,7 +2095,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966},
{"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.000.181
@@ -2052,7 +2103,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504},
{"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English DOS (from spookypeanut)
// SCI interpreter version 1.000.510
@@ -2067,7 +2118,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English Macintosh (from omer_mor, bug report #3328257)
{"lsl5", "", {
@@ -2081,7 +2132,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1110043},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 989801},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - German DOS (from Tobis87)
// SCI interpreter version T.A00.196
@@ -2096,7 +2147,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - French DOS (provided by richiefs in bug report #2670691)
// Executable scanning reports "1.lsl5.019"
@@ -2112,7 +2163,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92"
@@ -2128,7 +2179,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - Italian DOS Floppy (from glorifindel)
// SCI interpreter version 1.000.510 (just a guess)
@@ -2136,7 +2187,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919},
{"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 1.0 EGA DOS (8 x 3.5" disks)
// Provided by ssburnout in bug report #3046806
@@ -2151,7 +2202,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f6046a8445422f17d40b1b10ab21ebf3", 568551},
{"resource.007", 0, "640ee65595d40372ef95462f2c1ae28a", 593429},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 EGA
// Supplied by omer_mor in bug report #3049771
@@ -2162,7 +2213,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5a55af4e40728b1a8103dc47ad2afa8d", 1100539},
{"resource.003", 0, "16f4d8fb1b526125edaca4fc6cbb7530", 1064563},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - English DOS (from spookypeanut)
// SCI interpreter version 1.001.113
@@ -2170,7 +2221,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973},
{"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - English/German/French DOS CD - LOWRES
// SCI interpreter version 1.001.115
@@ -2178,7 +2229,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263},
{"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - German DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2186,7 +2237,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - French DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2194,7 +2245,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - Spanish DOS - LOWRES (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93"
@@ -2202,7 +2253,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943},
{"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.001.029", VERSION file reports "1.000"
@@ -2210,35 +2261,35 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783},
{"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: King Graham's Board Game Challenge
{"cnick-kq", "", {
{"resource.map", 0, "44bc538a5cd24b39ffccc967c0ebf84d", 1137},
{"resource.001", 0, "470e7a4a3504635e70b623c44461e1ac", 451272},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Parlor Games with Laura Bow
{"cnick-laurabow", "", {
{"resource.map", 0, "3b826bfe64f8ff1ccf30eef93cd2f727", 999},
{"resource.001", 0, "985ac8db6f636f2b4334c04b0fbb44fb", 336698},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Robin Hood's Game of Skill and Chance
{"cnick-longbow", "", {
{"resource.map", 0, "4a5c81f485a2416bde12978506f2fb5f", 897},
{"resource.001", 0, "ef16dc9e867eb8eeb5b13e110b90bd4b", 571466},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Roger Wilco's Spaced Out Game Pack
{"cnick-sq", "", {
{"resource.map", 0, "b4d95b02d84e297441bd999d34eaa6b1", 879},
{"resource.001", 0, "82ff2b64a60117886fbcd6a3a8c977c6", 364921},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Larry 6 - English/German DOS CD - HIRES
@@ -2247,7 +2298,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872},
{"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2255,7 +2306,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2263,7 +2314,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2271,7 +2322,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878},
{"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// Larry 7 - English DOS CD (from spookypeanut)
@@ -2280,7 +2331,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188},
{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - German DOS (from Tobis87)
// SCI interpreter version 3.000.000
@@ -2288,7 +2339,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188},
{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - French DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 3.000.000
@@ -2296,7 +2347,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206},
{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - Italian DOS CD (from glorifindel)
// SCI interpreter version 3.000.000
@@ -2304,7 +2355,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212},
{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "3.000.000", VERSION file reports "1.0s"
@@ -2312,7 +2363,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188},
{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Lighthouse - English Windows Demo (from jvprat)
@@ -2321,7 +2372,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64},
{"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// Lighthouse - English Windows Demo
@@ -2330,7 +2381,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525},
{"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Lighthouse - English DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2340,7 +2391,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573},
{"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Lighthouse - Spanish DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2350,7 +2401,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630},
{"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2361,7 +2412,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643},
{"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales - English DOS Floppy EGA (from omer_mor, bug report #3035350)
{"fairytales", "EGA", {
@@ -2372,7 +2423,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255},
{"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791)
// Executable scanning reports "1.000.145"
@@ -2384,7 +2435,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565},
{"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.145", Floppy label reports "1.0, 11.13.91", VERSION file reports "1.000"
@@ -2395,7 +2446,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142},
{"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.003.009"
@@ -2405,7 +2456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885},
{"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS Floppy EGA (from omer_mor, bug report #3035354)
{"mothergoose", "EGA", {
@@ -2413,7 +2464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906},
{"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS Floppy EGA (supplied by ssburnout in bug report #3049193)
// 1.011 5x5.25" (label: Int#8.2.90)
@@ -2426,7 +2477,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "dbbc22f124533ce308bc386b08956326", 146251},
{"resource.005", 0, "2ba5348e7fad641b9c4c7ff7c7cf4e68", 110979},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795)
// Executable scanning reports "1.001.031"
@@ -2434,7 +2485,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026},
{"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS CD (from jvprat)
// Executable scanning reports "x.yyy.zzz"
@@ -2443,7 +2494,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790},
{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English Windows Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -2451,19 +2502,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560},
{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - FM-Towns (supplied by abevi in bug report #3038720)
{"mothergoose256", "", {
{"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
{"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
{"mothergoose256", "", {
{"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
{"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810)
@@ -2472,7 +2523,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741},
{"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish)
// Executable scanning reports "2.100.002"
@@ -2480,7 +2531,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969},
{"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// Ms. Astro Chicken - English DOS
@@ -2489,7 +2540,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158},
{"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Phantasmagoria - English DOS (from jvprat)
@@ -2510,7 +2561,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972},
//{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English DOS Demo
// Executable scanning reports "2.100.002"
@@ -2518,7 +2569,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518},
{"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English DOS/Windows (GOG version) - ressci.* merged in ressci.000
// Windows executable scanning reports "2.100.002" - "Sep 19 1995 15:09:43"
@@ -2529,7 +2580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "cd5967f9b9586e3380645961c0765be3", 116822037},
{"resmap.000", 0, "3cafc1c6a53945c1f3babbfd6380c64c", 16468},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English Macintosh
// NOTE: This only contains disc 1 files (as well as the two persistent files:
@@ -2562,7 +2613,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942},
{"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03"
@@ -2572,7 +2623,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481},
{"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2583,7 +2634,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179},
{"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS Non-Interactive Demo
// Executable scanning reports "1.001.060", VERSION file reports "1.000"
@@ -2591,7 +2642,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984},
{"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS/Windows Interactive Demo
// Executable scanning reports "1.001.069", VERSION file reports ".001"
@@ -2599,7 +2650,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514},
{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS Interactive Demo
// Executable scanning reports "1.001.072", VERSION file reports "1.000"
@@ -2607,7 +2658,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524},
{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection)
// Executable scanning reports "1.001.029", VERSION file reports "2.000"
@@ -2615,7 +2666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013},
{"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English Amiga (from www.back2roots.org)
// SCI interpreter version 0.000.685 (just a guess)
@@ -2626,7 +2677,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099},
{"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.413"
@@ -2634,7 +2685,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576},
{"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.395
@@ -2647,7 +2698,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899},
{"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (from the Police Quest Collection)
// Executable scanning reports "0.000.490"
@@ -2657,7 +2708,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (from FRG)
// SCI interpreter version 0.000.395
@@ -2667,7 +2718,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 English DOS 1.001.006 (supplied by merkur-kun in bug report #3028479)
{"pq2", "", {
@@ -2676,7 +2727,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - Japanese PC-98 (also includes english language)
// SCI interpreter version unknown
@@ -2686,7 +2737,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662},
{"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English Amiga
// Executable scanning reports "1.004.024"
@@ -2699,7 +2750,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891},
{"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -2713,7 +2764,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738},
{"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English DOS (from the Police Quest Collection)
// Executable scanning reports "T.A00.178", VERSION file reports "1.00"
@@ -2726,7 +2777,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791},
{"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English DOS Non-Interactive Demo
// Executable scanning reports "T.A00.052"
@@ -2736,7 +2787,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150},
{"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837, also includes english language)
// Executable scanning reports "T.A00.178"
@@ -2749,14 +2800,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956},
{"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - Spanish DOS v1.000 - Supplied by dianiu in bug report #3555647
{"pq3", "", {
{"resource.map", 0, "ffa0b4631c4e36d69631256d19ba29e7", 5421},
{"resource.000", 0, "5ee460af3d70c06a745cc482b6c783ba", 5410263},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 EGA
// Reported by musiclyinspired in bug report #3046573
@@ -2769,7 +2820,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b96a86ab681769e4cbb439670d967ca6", 449682},
{"resource.005", 0, "9e6c53a0e7eef53694d260fade8b1fc7", 724000},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.096
@@ -2777,7 +2828,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472},
{"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Police Quest 4 - English DOS CD (from the Police Quest Collection)
@@ -2786,7 +2837,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374},
{"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - German DOS CD (German text, English speech)
// Supplied by markcoolio in bug report #3392955
@@ -2794,7 +2845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a398076371ed0e1e706c8f9fb9fc7ac5", 11386},
{"resource.000", 0, "6ff21954e0a2c5992279e7eb787c8d56", 18918747},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - English DOS
// SCI interpreter version 2.000.000 (a guess?)
@@ -2802,7 +2853,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895},
{"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - French DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -2810,7 +2861,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "008030846edcc7c5c7a812c7f4ae4ceb", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730153},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840)
// SCI interpreter version 2.000.000 (a guess?)
@@ -2818,7 +2869,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English DOS/Windows Demo (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "0.001.200"
@@ -2826,7 +2877,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648},
{"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English DOS (from GOG.com)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2834,7 +2885,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "1c2563fee189885e29d9348f37306d94", 12175},
{"ressci.000", 0, "b2e1826ca81ce2e7e764587f5a14eee9", 127149181},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English Windows (from the Police Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2849,7 +2900,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.004", 0, "4228038906f041623e65789500b22285", 6835},
{"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784)
@@ -2862,7 +2913,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by alonzotg in bug report #3206006)
{"qfg1", "", {
@@ -2873,7 +2924,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy v1.102 Int#0.000.629 (suppled by digitoxin1 in bug report #3554611)
{"qfg1", "", {
@@ -2884,7 +2935,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640502},
{"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644575},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy v1.102 Int#0.000.629 (suppled by digitoxin1 in bug report #3554611)
{"qfg1", "", {
@@ -2898,7 +2949,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "48b2b3c964dcbeccb68e984e6d4e97db", 278473},
{"resource.007", 0, "f0af87c60ec869946da442833aa5afa8", 269237},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843)
// Executable scanning reports "0.000.566"
@@ -2913,7 +2964,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.001 10x5.25" (label: INT.#0.000.566)
@@ -2928,7 +2979,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.200 10x5.25" (label: INT#9.10.90)
@@ -2943,7 +2994,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f46690dca714abc8c89357d30e363dd3", 278387},
{"resource.007", 0, "951299a82a8134ed12c5c18118d45c2f", 269173},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS Demo
// Executable scanning reports "0.000.685"
@@ -2951,7 +3002,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "df34c758cbb9026da175793ff686b0e6", 882},
{"resource.001", 0, "73fbaafdd313b39aeedb80fbf85ecef1", 389884},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -2961,7 +3012,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -2971,7 +3022,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
// Quest for Glory 1 - English Amiga
// Executable scanning reports "1.002.020"
@@ -2985,7 +3036,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124},
{"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 - English DOS
// SCI interpreter version 0.000.629
@@ -2997,7 +3048,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483},
{"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English DOS
// Executable scanning reports "2.000.411"
@@ -3005,7 +3056,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469},
{"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.029
@@ -3013,7 +3064,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729},
{"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English Macintosh Floppy
// VERSION file reports "2.0"
@@ -3021,7 +3072,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "106527ff8756e4e1a795d63d23e8b833", 1752358},
{"Data2", 0, "5cdd92033231159c6e9c71d43e9f194d", 6574746},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English Amiga
// Executable scanning reports "1.003.004"
@@ -3037,7 +3088,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039},
{"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193)
// 1.000 5x5.25" (label: INT#10.31.90)
@@ -3049,7 +3100,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "0790f67d87642132be515cab05026baa", 972144},
{"resource.004", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 982830},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193)
// 1.000 9x3.5" (label: INT#10.31.90)
@@ -3064,7 +3115,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "5e9deacbdb17198ad844988e04833520", 498593},
{"resource.007", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 490151},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (from FRG)
// Executable scanning reports "1.000.072"
@@ -3076,7 +3127,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804},
{"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS
// Executable scanning reports "1.000.072"
@@ -3091,7 +3142,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489},
{"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS (supplied by digitoxin1 in bug report #3554614)
// v1.102 9x3.5" (label: Int#11.20.90)
@@ -3106,7 +3157,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489},
{"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS Non-Interactive Demo
// Executable scanning reports "1.000.046"
@@ -3114,7 +3165,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906},
{"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92"
@@ -3122,7 +3173,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687},
{"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS
// SCI interpreter version 1.001.050
@@ -3130,7 +3181,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 1.001.050
@@ -3138,7 +3189,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "62c185d190363d7df06330fa0cc45b36", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5867442},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS (supplied by dknute in bug report #3125559)
{"qfg3", "", {
@@ -3146,7 +3197,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042},
{"resource.msg", 0, "27e5419c98ce444253f88c95dced14a9", 246888},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846)
// Executable scanning reports "L.rry.083"
@@ -3154,7 +3205,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - French DOS v1.1 (supplied by misterhands in bug report #3586214)
// Executable scanning reports "L.rry.083"
@@ -3163,7 +3214,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
{"resource.msg", 0, "0fa1047002df904b8d1807bb7bab4fab", 267210},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - Spanish DOS CD (from jvprat)
// Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994"
@@ -3172,7 +3223,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098},
{"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - Italian DOS
// Supplied by ghoost in bug report #3053457
@@ -3181,7 +3232,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
{"resource.msg", 0, "5a0a896ff3e4a628db38a75eb6c84114", 259018},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.069 (just a guess)
@@ -3189,7 +3240,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922},
{"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852)
@@ -3198,7 +3249,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 1.1 Floppy - English DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -3206,7 +3257,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d10a4cc177d2091d744e2ad8c049b0ae", 9295},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11003589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850)
// Executable scanning reports "2.000.000", VERSION file reports "1.1"
@@ -3214,7 +3265,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301},
{"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 CD - English DOS/Windows (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3222,7 +3273,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246},
{"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - English DOS/Windows Demo
// Executable scanning reports "2.100.002", VERSION file reports "000.000.008"
@@ -3230,7 +3281,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393},
{"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// RAMA - English Windows (from jvprat)
@@ -3243,7 +3294,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - English Windows (from Quietust, in bug report #2850645)
{"rama", "", {
@@ -3254,7 +3305,18 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // RAMA - German Windows CD (from farmboy0, in pull request 397)
+ {"rama", "", {
+ {"resmap.001", 0, "f68cd73308c46977a9632dfc618e1e38", 8338},
+ {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70595521},
+ {"resmap.002", 0, "891fc2f5d9e23e7d9a9454acc7aaae52", 12082},
+ {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128508558},
+ {"resmap.003", 0, "222096000bd83a1d56577114a452cccf", 1636},
+ {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6954219},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - Italian Windows CD (from glorifindel)
// SCI interpreter version 3.000.000 (a guess?)
@@ -3262,7 +3324,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091},
{"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
// Shivers - English Windows (from jvprat)
@@ -3271,14 +3333,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525},
{"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers - German Windows (from Tobis87)
{"shivers", "", {
{"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537},
{"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers - English Windows Demo
// Executable scanning reports "2.100.002"
@@ -3286,7 +3348,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186},
{"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers 2 doesn't contain SCI scripts. The whole game logic has
// been reimplemented from SCI in native code placed in DLL files.
@@ -3304,7 +3366,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634},
{"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers 2 - English Windows (from abevi)
// VERSION.TXT Version 1.0 (3/25/97)
@@ -3312,7 +3374,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793},
{"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
@@ -3325,7 +3387,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364},
{"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English DOS/Windows
{"slater", "", {
@@ -3333,7 +3395,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044},
{"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English DOS/Windows (Sierra Originals)
@@ -3342,14 +3404,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044},
{"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English Macintosh
{"slater", "", {
{"Data1", 0, "7243b4390e5f0182d8133fbcae4b50c5", 2298853},
{"Data2", 0, "6b6f18f9b502dc0923eeae0ef47f02d5", 2276956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) },
// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org)
// SCI interpreter version 1.000.510 (just a guess)
@@ -3362,7 +3424,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515},
{"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection)
// Executable scanning reports "T.A00.081", VERSION file reports "2.000"
@@ -3375,7 +3437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262},
{"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English Mac (from Fingolfin)
{"sq1sci", "SCI", {
@@ -3386,7 +3448,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "ae46e195e66df5a131917f0aa80b5669", 1242794},
{"resource.004", 0, "91d58a9eb2187c38424990afe4c12bc6", 1250949},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG)
// SCI interpreter version 1.000.181
@@ -3394,7 +3456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636},
{"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat)
// Executable scanning reports "T.A00.081", VERSION file reports "2.000"
@@ -3408,7 +3470,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325},
{"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest I 2.0 EGA DOS (6 x 3.5" disks)
// Provided by ssburnout in bug report #3046805
@@ -3421,7 +3483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "975c6e81194ae6b65e960a248129ecaa", 684119},
{"resource.005", 0, "13d96f7905637552c0647175ff816145", 695589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English Amiga (from www.back2roots.org)
// SCI interpreter version 0.000.453 (just a guess)
@@ -3432,7 +3494,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496},
{"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.006"
@@ -3453,7 +3515,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612},
{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.453
@@ -3463,7 +3525,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244},
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (from the Space Quest Collection)
// Executable scanning reports "0.000.685", VERSION file reports "1.018"
@@ -3473,7 +3535,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777},
{"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (from abevi, bug report #2612718)
{"sq3", "", {
@@ -3485,7 +3547,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 328278},
{"resource.006", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 356702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English Mac (from Fingolfin)
{"sq3", "", {
@@ -3494,7 +3556,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "0d8dfe42683b46f3131823233a91ce6a", 794072},
{"resource.003", 0, "0d8dfe42683b46f3131823233a91ce6a", 776536},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 0.000.453 (?)
@@ -3508,7 +3570,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643},
{"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860, also includes english language)
// Executable scanning reports "S.old.114"
@@ -3518,7 +3580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768},
{"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Amiga
// Executable scanning reports "1.004.024"
@@ -3533,7 +3595,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296},
{"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - German Amiga (from www.back2roots.org, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3547,7 +3609,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745},
{"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD=
// Executable scanning reports "1.000.753"
@@ -3556,7 +3618,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS
// Executable scanning reports "1.000.753"
@@ -3565,7 +3627,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865)
// Executable scanning reports "1.000.753"
@@ -3579,7 +3641,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631},
{"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - French DOS Floppy (supplied by misterhands in bug report #3515247)
{"sq4", "", {
@@ -3592,7 +3654,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b2cca3afcf2e013b8ce86b64155af766", 1254353},
{"resource.005", 0, "9e520577e035547c4b5149a6d12ef85b", 1098814},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - English DOS Floppy (from abevi, bug report #2612718)
{"sq4", "", {
@@ -3604,7 +3666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368},
{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest IV DOS 1.060 EGA (6 x 3.5" disks)
// Supplied by ssburnout in bug report #3046781
@@ -3617,7 +3679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9a673e33c3f6dd560b993ffed77eeb49", 534994},
{"resource.005", 0, "3c4841d0a3ebba4404af588c93620c22", 595465},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3631,7 +3693,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765},
{"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Italian DOS Floppy (from glorifindel, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3644,7 +3706,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000},
{"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language)
// SCI interpreter version 1.000.1068
@@ -3654,7 +3716,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language)
// SCI interpreter version 1.000.1068
@@ -3664,7 +3726,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3672,7 +3734,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054},
{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Windows CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3682,7 +3744,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054},
{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_MIDIGM, GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_MIDIGM, GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Space Quest 4 - English DOS CD patch 1.2 (unofficial - NRS) - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD=
+ // In essence, this "patch" includes a mixture the CD and floppy versions (the whole game), without the speech file
+ {"sq4", "CD", {
+ {"resource.map", 0, "38287a646458a1dabded55d094407793", 7139},
+ {"resource.000", 0, "231fd8421e1f211e1bcf9d7b8b6408e7", 9525849},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Spanish DOS CD (from jvprat, is still text only, not talkie, also includes english language)
// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000"
@@ -3696,7 +3766,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752},
{"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language)
// Executable scanning reports "1.SQ4.056", VERSION file reports "1.000"
@@ -3708,7 +3778,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801},
{"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862, also includes english language)
// Executable scanning reports "1.SQ4.030"
@@ -3722,7 +3792,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368},
{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
@@ -3737,7 +3807,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "869d16cab6641c80b06f4dcee18f86bc", 1426228},
{"resource.006", 0, "91d23407bc0447a3722fbeb952d7edee", 1402451},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Russian DOS
// Executable scanning reports "1.000.753", VERSION file reports "1.994"
@@ -3750,7 +3820,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "2763fe4f0cb74df716ec8b0c464b0988", 1217428},
{"resource.005", 0, "d608713197c5ba1cd8c6ed46299c3069", 1057924},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - English DOS (from the Space Quest Collection)
// Executable scanning reports "1.001.068", VERSION file reports "1.04"
@@ -3759,7 +3829,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - English DOS - THIS IS THE UNOFFICIAL BETA VERSION, WHICH IS OBVIOUSLY PIRATED AND CONTAINS MANY BUGS
// refer to http://www.akril15.com/sr/sq5alt/sq5alt.html =DO NOT RE-ADD=
@@ -3768,7 +3838,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473},
{"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762)
// SCI interpreter version 1.001.068
@@ -3777,7 +3847,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 v1.04 - French DOS (from Hkz, Included in Space Quest Collector's Edition, with chapters I-V)
{"sq5", "", {
@@ -3785,7 +3855,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "877c42380320eb1db7dad83ccd261214", 140374},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Italian DOS Floppy (from glorifindel)
// SCI interpreter version 1.001.068 (just a guess)
@@ -3793,7 +3863,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170},
{"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Spanish DOS Floppy (from mirir, bug report #3090664)
{"sq5", "", {
@@ -3801,7 +3871,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5714a899033bdebf2d61ad333c8c6637", 6492},
{"resource.msg", 0, "46deca7ef9cf057f7d442df98c1a2ae2", 134612},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Russian DOS
// Executable scanning reports "1.001.068", VERSION file reports "1.994"
@@ -3810,7 +3880,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6f9ed21e1001526b4137f6703ed476af", 6103778},
{"resource.msg", 0, "0a8931990cd2eac1691602391c68ab85", 147580},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection)
@@ -3819,7 +3889,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3827,7 +3897,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - French DOS/Win3.11 CD (from French magazine Joystick - September 1997)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3835,7 +3905,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534},
{"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3843,7 +3913,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534},
{"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3851,7 +3921,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572},
{"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// The Island of Dr. Brain - English DOS CD (from jvprat)
@@ -3860,7 +3930,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281},
{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// The Island of Dr. Brain - English DOS (from Quietust)
// Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93"
@@ -3868,7 +3938,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101},
{"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// The Island of Dr. Brain - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.053 (just a guess)
@@ -3876,7 +3946,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986},
{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Torin's Passage - English Windows Interactive Demo
@@ -3885,7 +3955,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403},
{"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - English Windows CD
// SCI interpreter version 2.100.002
@@ -3893,7 +3963,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3902,7 +3972,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
// TODO: depend on one of the patches?
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - French Windows CD
// SCI interpreter version 2.100.002
@@ -3910,7 +3980,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - German Windows CD
// SCI interpreter version 2.100.002
@@ -3918,7 +3988,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - Italian Windows CD (from glorifindel)
// SCI interpreter version 2.100.002
@@ -3926,7 +3996,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage - French Windows (from LePhilousophe)
// SCI interpreter version 2.100.002
@@ -3934,7 +4004,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "66ed46e3e56f487e688d52f05b33d0ba", 9787},
{"ressci.000", 0, "118f9bec04bfe17c4f87bbb5ddb43c18", 56126981},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// SCI Fanmade Games
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/kernel.cpp b/engines/sci/engine/kernel.cpp
index 8d55790ad2..12746e17d6 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -35,8 +35,6 @@ namespace Sci {
Kernel::Kernel(ResourceManager *resMan, SegManager *segMan)
: _resMan(resMan), _segMan(segMan), _invalid("<invalid>") {
- loadSelectorNames();
- mapSelectors(); // Map a few special selectors for later use
}
Kernel::~Kernel() {
@@ -53,6 +51,11 @@ Kernel::~Kernel() {
}
}
+void Kernel::init() {
+ loadSelectorNames();
+ mapSelectors(); // Map a few special selectors for later use
+}
+
uint Kernel::getSelectorNamesSize() const {
return _selectorNames.size();
}
@@ -104,6 +107,11 @@ int Kernel::findSelector(const char *selectorName) const {
return -1;
}
+// used by Script patcher to figure out, if it's okay to initialize signature/patch-table
+bool Kernel::selectorNamesAvailable() {
+ return !_selectorNames.empty();
+}
+
void Kernel::loadSelectorNames() {
Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0);
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8a021073fc..69c3a6d0c9 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -145,6 +145,8 @@ public:
*/
Kernel(ResourceManager *resMan, SegManager *segMan);
~Kernel();
+
+ void init();
uint getSelectorNamesSize() const;
const Common::String &getSelectorName(uint selector);
@@ -159,6 +161,8 @@ public:
* @return The appropriate selector ID, or -1 on error
*/
int findSelector(const char *selectorName) const;
+
+ bool selectorNamesAvailable();
// Script dissection/dumping functions
void dissectScript(int scriptNumber, Vocabulary *vocab);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index d7858180f1..39244bd760 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -421,7 +421,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL },
{ MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL },
{ MAP_CALL(Random), SIG_EVERYWHERE, "i(i)(i)", NULL, NULL },
- { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, NULL },
+ { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, kReadNumber_workarounds },
{ MAP_CALL(RemapColors), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, NULL },
#ifdef ENABLE_SCI32
{ "RemapColors", kRemapColors32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", NULL, NULL },
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index c6635f2f27..b940eca6f5 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -718,7 +718,7 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) {
reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
Common::String game_id;
- int16 virtualId = argv[1].toSint16();
+ int16 virtualId = argv[1].toSint16();
int16 savegameId = -1;
Common::String game_description;
Common::String version;
diff --git a/engines/sci/engine/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/savegame.cpp b/engines/sci/engine/savegame.cpp
index c8076ec819..6955225fe5 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -465,7 +465,7 @@ void Script::syncStringHeap(Common::Serializer &s) {
break;
} while (1);
- } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
+ } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
// Strings in SCI1.1 come after the object instances
byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
@@ -600,7 +600,10 @@ void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint16LE(dataInc);
s.syncAsSint16LE(ticker);
s.syncAsSint16LE(signal, VER(17));
- s.syncAsByte(priority);
+ if (s.getVersion() >= 31) // FE sound/music.h -> priority
+ s.syncAsSint16LE(priority);
+ else
+ s.syncAsByte(priority);
s.syncAsSint16LE(loop, VER(17));
s.syncAsByte(volume);
s.syncAsByte(hold, VER(17));
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 1d899b0d37..f1f02f89f2 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 31 - priority for sound effects/music is now a signed int16, instead of a byte
* 30 - synonyms
* 29 - system strings
* 28 - heap
@@ -55,7 +56,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 30,
+ CURRENT_SAVEGAME_VERSION = 31,
MINIMUM_SAVEGAME_VERSION = 14
};
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 36d2841b07..6616a0ee13 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -136,7 +136,7 @@ void Script::load(int script_nr, ResourceManager *resMan) {
memcpy(_buf, script->data, script->size);
// Check scripts for matching signatures and patch those, if found
- matchSignatureAndPatch(_nr, _buf, script->size);
+ patcherProcessScript(_nr, _buf, script->size);
if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0);
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 0b499203c2..6a27dc7f64 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -30,7 +30,7 @@ namespace Sci {
struct EngineState;
class ResourceManager;
-struct SciScriptSignature;
+struct SciScriptPatcherEntry;
enum ScriptObjectTypes {
SCI_OBJ_TERMINATOR,
@@ -98,9 +98,11 @@ public:
void freeScript();
void load(int script_nr, ResourceManager *resMan);
- void matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
- int32 findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize);
- void applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset);
+ void patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
+ void patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11);
+ void patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription);
+ int32 patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11);
+ void patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11);
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 20c5c52178..6293fb42ae 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -21,6 +21,7 @@
*/
#include "sci/sci.h"
+#include "sci/engine/kernel.h"
#include "sci/engine/script.h"
#include "sci/engine/state.h"
#include "sci/engine/features.h"
@@ -29,98 +30,257 @@
namespace Sci {
-#define PATCH_END 0xFFFF
-#define PATCH_COMMANDMASK 0xF000
-#define PATCH_VALUEMASK 0x0FFF
-#define PATCH_ADDTOOFFSET 0xE000
-#define PATCH_GETORIGINALBYTE 0xD000
-#define PATCH_ADJUSTWORD 0xC000
-#define PATCH_ADJUSTWORD_NEG 0xB000
-#define PATCH_MAGICDWORD(a, b, c, d) CONSTANT_LE_32(a | (b << 8) | (c << 16) | (d << 24))
+// IMPORTANT:
+// every patch entry needs the following:
+// - script number (pretty obvious)
+//
+// - apply count
+// specifies the number of times a patch is supposed to get applied.
+// Most of the time, it should be 1.
+//
+// - magicDWORD + magicOffset
+// please ALWAYS put 0 for those two. Both will get filled out at runtime by the patcher.
+//
+// - signature data (is used to identify certain script code, that needs patching)
+// every signature needs to contain SIG_MAGICDWORD once.
+// The following 4 bytes after SIG_MAGICDWORD - which don't have to be fixed, you may for example
+// use SIG_SELECTOR16, will get used to quickly search for a partly match before verifying that
+// the whole signature actually matches. If it's not included, the script patcher will error() out
+// right when loading up the game.
+// If selector-IDs are included, please use SIG_SELECTOR16 + SIG_SELECTOR8 [1]. Simply
+// specify the selector that way, so that the patcher will search for the specific
+// selector instead of looking for a hardcoded value. Selectors may not be the same
+// between game versions.
+// For UINT16s either use SIG_UINT16 or SIG_SELECTOR16.
+// Macintosh versions of SCI games are using BE ordering instead of LE since SCI1.1 for UINT16s in scripts
+// By using those 2 commands, it's possible to make patches work for PC and Mac versions of the same game.
+// You may also skip bytes by using the SIG_ADDTOOFFSET command
+// Every signature data needs to get terminated using SIGNATURE_END
+//
+// - patch data (is used for actually patching scripts)
+// When a match is found, the patch data will get applied.
+// Patch data is similar to signature data. Just use PATCH_SELECTOR16 + PATCH_SELECTOR8 [1]
+// for patching in selectors.
+// There are also patch specific commands.
+// Those are PATCH_GETORIGINALBYTE, which fetches a byte from the original script
+// and PATCH_GETORIGINALBYTEADJUST, which does the same but gets a second value
+// from the uint16 array and uses that value to adjust the original byte.
+// Every patch data needs to get terminated using PATCH_END
+//
+// - and please always add a comment about why the patch was done and what's causing issues.
+// If possible make sure, that the patch works on localized (or just different) game versions
+// as well in case those need patching too.
+//
+// [1] - selectors need to get specified in selectorTable[] and ScriptPatcherSelectors-enum
+// before they can get used using the SIG_SELECTORx and PATCH_SELECTORx commands.
+// You have to use the exact same order in both the table and the enum, otherwise
+// it won't work.
+
+#define SIG_END 0xFFFF
+#define SIG_MISMATCH 0xFFFE
+#define SIG_COMMANDMASK 0xF000
+#define SIG_VALUEMASK 0x0FFF
+#define SIG_BYTEMASK 0x00FF
+#define SIG_MAGICDWORD 0xF000
+#define SIG_ADDTOOFFSET 0xE000
+#define SIG_SELECTOR16 0x9000
+#define SIG_SELECTOR8 0x8000
+#define SIG_UINT16 0x1000
+#define SIG_BYTE 0x0000
+
+#define PATCH_END SIG_END
+#define PATCH_COMMANDMASK SIG_COMMANDMASK
+#define PATCH_VALUEMASK SIG_VALUEMASK
+#define PATCH_BYTEMASK SIG_BYTEMASK
+#define PATCH_ADDTOOFFSET SIG_ADDTOOFFSET
+#define PATCH_GETORIGINALBYTE 0xD000
+#define PATCH_GETORIGINALBYTEADJUST 0xC000
+#define PATCH_SELECTOR16 SIG_SELECTOR16
+#define PATCH_SELECTOR8 SIG_SELECTOR8
+#define PATCH_UINT16 SIG_UINT16
+#define PATCH_BYTE SIG_BYTE
+
+// defines maximum scratch area for getting original bytes from unpatched script data
#define PATCH_VALUELIMIT 4096
-struct SciScriptSignature {
+struct SciScriptPatcherEntry {
+ bool active;
uint16 scriptNr;
const char *description;
int16 applyCount;
uint32 magicDWord;
int magicOffset;
- const byte *data;
- const uint16 *patch;
+ const uint16 *signatureData;
+ const uint16 *patchData;
+};
+
+#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL }
+
+struct SciScriptPatcherSelector {
+ const char *name;
+ int16 id;
+};
+
+SciScriptPatcherSelector selectorTable[] = {
+ { "cycles", -1, }, // system selector
+ { "seconds", -1, }, // system selector
+ { "init", -1, }, // system selector
+ { "dispose", -1, }, // system selector
+ { "new", -1, }, // system selector
+ { "curEvent", -1, }, // system selector
+ { "disable", -1, }, // system selector
+ { "show", -1, }, // system selector
+ { "x", -1, }, // system selector
+ { "cel", -1, }, // system selector
+ { "setMotion", -1, }, // system selector
+ { "deskSarg", -1, }, // Gabriel Knight
+ { "localize", -1, }, // Freddy Pharkas
+ { "put", -1, }, // Police Quest 1 VGA
+ { "solvePuzzle", -1, }, // Quest For Glory 3
+ { "timesShownID", -1, }, // Space Quest 1 VGA
+ { "startText", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ { "startAudio", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ { "modNum", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ { NULL, -1 }
+};
+
+enum ScriptPatcherSelectors {
+ SELECTOR_cycles = 0,
+ SELECTOR_seconds,
+ SELECTOR_init,
+ SELECTOR_dispose,
+ SELECTOR_new,
+ SELECTOR_curEvent,
+ SELECTOR_disable,
+ SELECTOR_show,
+ SELECTOR_x,
+ SELECTOR_cel,
+ SELECTOR_setMotion,
+ SELECTOR_deskSarg,
+ SELECTOR_localize,
+ SELECTOR_put,
+ SELECTOR_solvePuzzle,
+ SELECTOR_timesShownID,
+ SELECTOR_startText,
+ SELECTOR_startAudio,
+ SELECTOR_modNum
};
-#define SCI_SIGNATUREENTRY_TERMINATOR { 0, NULL, 0, 0, 0, NULL, NULL }
+// ===========================================================================
+// Conquests of Camelot
+// At the bazaar in Jerusalem, it's possible to see a girl taking a shower.
+// If you get too close, you get warned by the father - if you don't get away,
+// he will kill you.
+// Instead of walking there manually, it's also possible to enter "look window"
+// and ego will automatically walk to the window. It seems that this is something
+// that wasn't properly implemented, because instead of getting killed, you will
+// get an "Oops" message in Sierra SCI.
+//
+// This is caused by peepingTom in script 169 not getting properly initialized.
+// peepingTom calls the object behind global b9h. This global variable is
+// properly initialized, when walking there manually (method fawaz::doit).
+// When you instead walk there automatically (method fawaz::handleEvent), that
+// global isn't initialized, which then results in the Oops-message in Sierra SCI
+// and an error message in ScummVM/SCI.
+//
+// We fix the script by patching in a jump to the proper code inside fawaz::doit.
+// Responsible method: fawaz::handleEvent
+// Fixes bug: #6402
+const uint16 camelotSignaturePeepingTom[] = {
+ 0x72, SIG_MAGICDWORD, SIG_UINT16 + 0x7e, 0x07, // lofsa fawaz <-- start of proper initializion code
+ 0xa1, 0xb9, // sag b9h
+ SIG_ADDTOOFFSET +571, // skip 571 bytes
+ 0x39, 0x7a, // pushi 7a <-- initialization code when walking automatically
+ 0x78, // push1
+ 0x7a, // push2
+ 0x38, SIG_UINT16 + 0xa9, 0x00, // pushi 00a9 - script 169
+ 0x78, // push1
+ 0x43, 0x02, 0x04, // call kScriptID
+ 0x36, // push
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06
+ 0x32, SIG_UINT16 + 0x20, 0x05, // jmp [end of fawaz::handleEvent]
+ SIG_END
+};
+
+const uint16 camelotPatchPeepingTom[] = {
+ PATCH_ADDTOOFFSET +576,
+ 0x32, PATCH_UINT16 + 0xbd, 0xfd, // jmp to fawaz::doit / properly init peepingTom code
+ PATCH_END
+};
-// signatures are built like this:
-// - first a counter of the bytes that follow
-// - then the actual bytes that need to get matched
-// - then another counter of bytes (0 for EOS)
-// - if not EOS, an adjust offset and the actual bytes
-// - rinse and repeat
+// script, description, signature patch
+SciScriptPatcherEntry camelotSignatures[] = {
+ { true, 62, "fix peepingTom Sierra bug", 1, 0, 0, camelotSignaturePeepingTom, camelotPatchPeepingTom },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
// ===========================================================================
// stayAndHelp::changeState (0) is called when ego swims to the left or right
// boundaries of room 660. Normally a textbox is supposed to get on screen
// but the call is wrong, so not only do we get an error message the script
// is also hanging because the cue won't get sent out
-// This also happens in sierra sci - refer to bug #3038387
-const byte ecoquest1SignatureStayAndHelp[] = {
- 40,
- 0x3f, 0x01, // link 01
- 0x87, 0x01, // lap param[1]
- 0x65, 0x14, // aTop state
- 0x36, // push
- 0x3c, // dup
- 0x35, 0x00, // ldi 00
- 0x1a, // eq?
- 0x31, 0x1c, // bnt [next state]
- 0x76, // push0
- 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
- 0x38, 0x22, 0x01, // pushi 0122
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag global[0]
- 0x4a, 0x06, // send 06 - call ego::setMotion(0)
- 0x39, 0x6e, // pushi 6e (selector init)
- 0x39, 0x04, // pushi 04
- 0x76, // push0
- 0x76, // push0
- 0x39, 0x17, // pushi 17
- 0x7c, // pushSelf
- 0x51, 0x82, // class EcoNarrator
- 0x4a, 0x0c, // send 0c - call EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!)
- 0x33, // jmp [end]
- 0
+// This also happens in sierra sci
+// Applies to at least: PC-CD
+// Responsible method: stayAndHelp::changeState
+// Fixes bug: #5107
+const uint16 ecoquest1SignatureStayAndHelp[] = {
+ 0x3f, 0x01, // link 01
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x1c, // bnt [next state]
+ 0x76, // push0
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16 + 0x22, 0x01, // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - call ego::setMotion(0)
+ 0x39, SIG_SELECTOR8 + SELECTOR_init, // pushi "init"
+ 0x39, 0x04, // pushi 04
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x0c, // send 0c - call EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!)
+ 0x33, // jmp [end]
+ SIG_END
};
const uint16 ecoquest1PatchStayAndHelp[] = {
- 0x87, 0x01, // lap param[1]
- 0x65, 0x14, // aTop state
- 0x36, // push
- 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes)
- 0x39, 0x00, // pushi 0 (wasting 1 byte here)
- 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
- 0x38, 0x22, 0x01, // pushi 0122
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag global[0]
- 0x4a, 0x06, // send 06 - call ego::setMotion(0)
- 0x39, 0x6e, // pushi 6e (selector init)
- 0x39, 0x06, // pushi 06
- 0x39, 0x02, // pushi 02 (additional 2 bytes)
- 0x76, // push0
- 0x76, // push0
- 0x39, 0x17, // pushi 17
- 0x7c, // pushSelf
- 0x38, 0x80, 0x02, // pushi 280 (additional 3 bytes)
- 0x51, 0x82, // class EcoNarrator
- 0x4a, 0x10, // send 10 - call EcoNarrator::init(2, 0, 0, 23, self, 640)
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes)
+ 0x39, 0x00, // pushi 0 (wasting 1 byte here)
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ 0x38, PATCH_UINT16 + 0x22, 0x01, // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - call ego::setMotion(0)
+ 0x39, PATCH_SELECTOR8 + SELECTOR_init, // pushi "init"
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x02, // pushi 02 (additional 2 bytes)
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x38, PATCH_UINT16 + 0x80, 0x02, // pushi 280 (additional 3 bytes)
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x10, // send 10 - call EcoNarrator::init(2, 0, 0, 23, self, 640)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature ecoquest1Signatures[] = {
- { 660, "CD: bad messagebox and freeze", 1, PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+// script, description, signature patch
+SciScriptPatcherEntry ecoquest1Signatures[] = {
+ { true, 660, "CD: bad messagebox and freeze", 1, 0, 0, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -129,122 +289,124 @@ const SciScriptSignature ecoquest1Signatures[] = {
// ecorder. This is done by reusing temp-space, that was filled on state 1.
// this worked in sierra sci just by accident. In our sci, the temp space
// is resetted every time, which means the previous text isn't available
-// anymore. We have to patch the code because of that - bug #3035386
-const byte ecoquest2SignatureEcorder[] = {
- 35,
- 0x31, 0x22, // bnt [next state]
- 0x39, 0x0a, // pushi 0a
- 0x5b, 0x04, 0x1e, // lea temp[1e]
- 0x36, // push
- 0x39, 0x64, // pushi 64
- 0x39, 0x7d, // pushi 7d
- 0x39, 0x32, // pushi 32
- 0x39, 0x66, // pushi 66
- 0x39, 0x17, // pushi 17
- 0x39, 0x69, // pushi 69
- 0x38, 0x31, 0x26, // pushi 2631
- 0x39, 0x6a, // pushi 6a
- 0x39, 0x64, // pushi 64
- 0x43, 0x1b, 0x14, // call kDisplay
- 0x35, 0x0a, // ldi 0a
- 0x65, 0x20, // aTop ticks
- 0x33, // jmp [end]
- +1, 5, // [skip 1 byte]
- 0x3c, // dup
- 0x35, 0x03, // ldi 03
- 0x1a, // eq?
- 0x31, // bnt [end]
- 0
+// anymore. We have to patch the code because of that.
+// Fixes bug: #4993
+const uint16 ecoquest2SignatureEcorder[] = {
+ 0x31, 0x22, // bnt [next state]
+ 0x39, 0x0a, // pushi 0a
+ 0x5b, 0x04, 0x1e, // lea temp[1e]
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x39, 0x64, // pushi 64
+ 0x39, 0x7d, // pushi 7d
+ 0x39, 0x32, // pushi 32
+ 0x39, 0x66, // pushi 66
+ 0x39, 0x17, // pushi 17
+ 0x39, 0x69, // pushi 69
+ 0x38, PATCH_UINT16 + 0x31, 0x26, // pushi 2631
+ 0x39, 0x6a, // pushi 6a
+ 0x39, 0x64, // pushi 64
+ 0x43, 0x1b, 0x14, // call kDisplay
+ 0x35, 0x0a, // ldi 0a
+ 0x65, 0x20, // aTop ticks
+ 0x33, // jmp [end]
+ SIG_ADDTOOFFSET +1, // [skip 1 byte]
+ 0x3c, // dup
+ 0x35, 0x03, // ldi 03
+ 0x1a, // eq?
+ 0x31, // bnt [end]
+ SIG_END
};
const uint16 ecoquest2PatchEcorder[] = {
- 0x2f, 0x02, // bt [to pushi 07]
- 0x3a, // toss
- 0x48, // ret
- 0x38, 0x07, 0x00, // pushi 07 (parameter count) (waste 1 byte)
- 0x39, 0x0b, // push (FillBoxAny)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x78, // push1 (visual screen)
- 0x38, 0x17, 0x00, // pushi 17 (color) (waste 1 byte)
- 0x43, 0x6c, 0x0e, // call kGraph
- 0x38, 0x05, 0x00, // pushi 05 (parameter count) (waste 1 byte)
- 0x39, 0x0c, // pushi 12d (UpdateBox)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x43, 0x6c, 0x0a, // call kGraph
+ 0x2f, 0x02, // bt [to pushi 07]
+ 0x3a, // toss
+ 0x48, // ret
+ 0x38, PATCH_UINT16 + 0x07, 0x00, // pushi 07 (parameter count) (waste 1 byte)
+ 0x39, 0x0b, // push (FillBoxAny)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16 + 0xd7, 0x00, // pushi 215d
+ 0x78, // push1 (visual screen)
+ 0x38, PATCH_UINT16 + 0x17, 0x00, // pushi 17 (color) (waste 1 byte)
+ 0x43, 0x6c, 0x0e, // call kGraph
+ 0x38, PATCH_UINT16 + 0x05, 0x00, // pushi 05 (parameter count) (waste 1 byte)
+ 0x39, 0x0c, // pushi 12d (UpdateBox)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16 + 0xd7, 0x00, // pushi 215d
+ 0x43, 0x6c, 0x0a, // call kGraph
PATCH_END
};
// ===========================================================================
-// Same patch as above for the ecorder introduction. Fixes bug #3092115.
+// Same patch as above for the ecorder introduction.
// Two workarounds are needed for this patch in workarounds.cpp (when calling
// kGraphFillBoxAny and kGraphUpdateBox), as there isn't enough space to patch
// the function otherwise.
-const byte ecoquest2SignatureEcorderTutorial[] = {
- 36,
- 0x30, 0x23, 0x00, // bnt [next state]
- 0x39, 0x0a, // pushi 0a
- 0x5b, 0x04, 0x1f, // lea temp[1f]
- 0x36, // push
- 0x39, 0x64, // pushi 64
- 0x39, 0x7d, // pushi 7d
- 0x39, 0x32, // pushi 32
- 0x39, 0x66, // pushi 66
- 0x39, 0x17, // pushi 17
- 0x39, 0x69, // pushi 69
- 0x38, 0x31, 0x26, // pushi 2631
- 0x39, 0x6a, // pushi 6a
- 0x39, 0x64, // pushi 64
- 0x43, 0x1b, 0x14, // call kDisplay
- 0x35, 0x1e, // ldi 1e
- 0x65, 0x20, // aTop ticks
- 0x32, // jmp [end]
+// Fixes bug: #6467
+const uint16 ecoquest2SignatureEcorderTutorial[] = {
+ 0x30, SIG_UINT16 + 0x23, 0x00, // bnt [next state]
+ 0x39, 0x0a, // pushi 0a
+ 0x5b, 0x04, 0x1f, // lea temp[1f]
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x39, 0x64, // pushi 64
+ 0x39, 0x7d, // pushi 7d
+ 0x39, 0x32, // pushi 32
+ 0x39, 0x66, // pushi 66
+ 0x39, 0x17, // pushi 17
+ 0x39, 0x69, // pushi 69
+ 0x38, SIG_UINT16 + 0x31, 0x26, // pushi 2631
+ 0x39, 0x6a, // pushi 6a
+ 0x39, 0x64, // pushi 64
+ 0x43, 0x1b, 0x14, // call kDisplay
+ 0x35, 0x1e, // ldi 1e
+ 0x65, 0x20, // aTop ticks
+ 0x32, // jmp [end]
// 2 extra bytes, jmp offset
- 0
+ SIG_END
};
const uint16 ecoquest2PatchEcorderTutorial[] = {
- 0x31, 0x23, // bnt [next state] (save 1 byte)
+ 0x31, 0x23, // bnt [next state] (save 1 byte)
// The parameter count below should be 7, but we're out of bytes
// to patch! A workaround has been added because of this
- 0x78, // push1 (parameter count)
- //0x39, 0x07, // pushi 07 (parameter count)
- 0x39, 0x0b, // push (FillBoxAny)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x78, // push1 (visual screen)
- 0x39, 0x17, // pushi 17 (color)
- 0x43, 0x6c, 0x0e, // call kGraph
+ 0x78, // push1 (parameter count)
+ //0x39, 0x07, // pushi 07 (parameter count)
+ 0x39, 0x0b, // push (FillBoxAny)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16 + 0xd7, 0x00, // pushi 215d
+ 0x78, // push1 (visual screen)
+ 0x39, 0x17, // pushi 17 (color)
+ 0x43, 0x6c, 0x0e, // call kGraph
// The parameter count below should be 5, but we're out of bytes
// to patch! A workaround has been added because of this
- 0x78, // push1 (parameter count)
- //0x39, 0x05, // pushi 05 (parameter count)
- 0x39, 0x0c, // pushi 12d (UpdateBox)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x43, 0x6c, 0x0a, // call kGraph
+ 0x78, // push1 (parameter count)
+ //0x39, 0x05, // pushi 05 (parameter count)
+ 0x39, 0x0c, // pushi 12d (UpdateBox)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16 + 0xd7, 0x00, // pushi 215d
+ 0x43, 0x6c, 0x0a, // call kGraph
// We are out of bytes to patch at this point,
// so we skip 494 (0x1EE) bytes to reuse this code:
// ldi 1e
// aTop 20
// jmp 030e (jump to end)
- 0x32, 0xee, 0x01, // skip 494 (0x1EE) bytes
+ 0x32, PATCH_UINT16 + 0xee, 0x01, // skip 494 (0x1EE) bytes
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature ecoquest2Signatures[] = {
- { 50, "initial text not removed on ecorder", 1, PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -8, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
- { 333, "initial text not removed on ecorder tutorial",1, PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -9, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
+// script, description, signature patch
+SciScriptPatcherEntry ecoquest2Signatures[] = {
+ { true, 50, "initial text not removed on ecorder", 1, 0, 0, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
+ { true, 333, "initial text not removed on ecorder tutorial",1, 0, 0, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -253,27 +415,27 @@ const SciScriptSignature ecoquest2Signatures[] = {
// wrong address when an incorrect word is typed, therefore leading to an
// infinite loop. This script bug was not apparent in SSCI, probably because
// event handling was slightly different there, so it was never discovered.
-// Fixes bug #3038870.
-const byte fanmadeSignatureInfiniteLoop[] = {
- 13,
- 0x38, 0x4c, 0x00, // pushi 004c
- 0x39, 0x00, // pushi 00
- 0x87, 0x01, // lap 01
- 0x4b, 0x04, // send 04
- 0x18, // not
- 0x30, 0x2f, 0x00, // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop
- 0
+// Fixes bug: #5120
+const uint16 fanmadeSignatureInfiniteLoop[] = {
+ 0x38, SIG_UINT16 + 0x4c, 0x00, // pushi 004c
+ 0x39, 0x00, // pushi 00
+ 0x87, 0x01, // lap 01
+ 0x4b, 0x04, // send 04
+ SIG_MAGICDWORD,
+ 0x18, // not
+ 0x30, SIG_UINT16 + 0x2f, 0x00, // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop
+ SIG_END
};
const uint16 fanmadePatchInfiniteLoop[] = {
PATCH_ADDTOOFFSET | +10,
- 0x30, 0x32, 0x00, // bnt 0032 [06a8] --> pushi 004c
+ 0x30, SIG_UINT16 + 0x32, 0x00, // bnt 0032 [06a8] --> pushi 004c
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature fanmadeSignatures[] = {
- { 999, "infinite loop on typo", 1, PATCH_MAGICDWORD(0x18, 0x30, 0x2f, 0x00), -9, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
+// script, description, signature patch
+SciScriptPatcherEntry fanmadeSignatures[] = {
+ { true, 999, "infinite loop on typo", 1, 0, 0, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -285,21 +447,23 @@ const SciScriptSignature fanmadeSignatures[] = {
// was already playing in the sound driver. In our case we would also stop
// the sample from playing, so we patch it out
// The "score" code is already buggy and sets volume to 0 when playing
-const byte freddypharkasSignatureScoreDisposal[] = {
- 10,
- 0x67, 0x32, // pTos 32 (selector theAudCount)
- 0x78, // push1
- 0x39, 0x0d, // pushi 0d
- 0x43, 0x75, 0x02, // call kDoAudio
- 0x1c, // ne?
- 0x31, // bnt (-> to skip disposal)
- 0
+// Applies to at least: English PC-CD
+// Responsible method: unknown
+const uint16 freddypharkasSignatureScoreDisposal[] = {
+ 0x67, 0x32, // pTos 32 (selector theAudCount)
+ 0x78, // push1
+ SIG_MAGICDWORD,
+ 0x39, 0x0d, // pushi 0d
+ 0x43, 0x75, 0x02, // call kDoAudio
+ 0x1c, // ne?
+ 0x31, // bnt (-> to skip disposal)
+ SIG_END
};
const uint16 freddypharkasPatchScoreDisposal[] = {
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000
PATCH_END
};
@@ -309,24 +473,26 @@ const uint16 freddypharkasPatchScoreDisposal[] = {
// in IconBar::disable doing endless loops even in sierra sci, because there
// is no enabled icon left. We remove disabling of icon 8 (which is help),
// this fixes the issue.
-const byte freddypharkasSignatureCanisterHang[] = {
- 12,
- 0x38, 0xf1, 0x00, // pushi f1 (selector disable)
- 0x7a, // push2
- 0x39, 0x07, // pushi 07
- 0x39, 0x08, // pushi 08
- 0x81, 0x45, // lag 45
- 0x4a, 0x08, // send 08 - call IconBar::disable(7, 8)
- 0
+// Applies to at least: English PC-CD
+// Responsible method: rm235::init and sEnterFrom500::changeState
+const uint16 freddypharkasSignatureCanisterHang[] = {
+ 0x38, SIG_SELECTOR16 + SELECTOR_disable, // pushi disable
+ 0x7a, // push2
+ SIG_MAGICDWORD,
+ 0x39, 0x07, // pushi 07
+ 0x39, 0x08, // pushi 08
+ 0x81, 0x45, // lag 45
+ 0x4a, 0x08, // send 08 - call IconBar::disable(7, 8)
+ SIG_END
};
const uint16 freddypharkasPatchCanisterHang[] = {
PATCH_ADDTOOFFSET | +3,
- 0x78, // push1
+ 0x78, // push1
PATCH_ADDTOOFFSET | +2,
- 0x33, 0x00, // ldi 00 (waste 2 bytes)
+ 0x33, 0x00, // ldi 00 (waste 2 bytes)
PATCH_ADDTOOFFSET | +3,
- 0x06, // send 06 - call IconBar::disable(7)
+ 0x06, // send 06 - call IconBar::disable(7)
PATCH_END
};
@@ -338,135 +504,132 @@ const uint16 freddypharkasPatchCanisterHang[] = {
// ego, sometimes clicks also won't get registered. Strangely it's not nearly
// as bad as in our sci, but these differences may be caused by timing.
// We just reuse the active event, thus removing the duplicate kGetEvent call.
-const byte freddypharkasSignatureLadderEvent[] = {
- 21,
- 0x39, 0x6d, // pushi 6d (selector new)
- 0x76, // push0
- 0x38, 0xf5, 0x00, // pushi f5 (selector curEvent)
- 0x76, // push0
- 0x81, 0x50, // lag global[50]
- 0x4a, 0x04, // send 04 - read User::curEvent
- 0x4a, 0x04, // send 04 - call curEvent::new
- 0xa5, 0x00, // sat temp[0]
- 0x38, 0x94, 0x00, // pushi 94 (selector localize)
- 0x76, // push0
- 0x4a, 0x04, // send 04 - call curEvent::localize
- 0
+// Applies to at least: English PC-CD, German Floppy, English Mac
+// Responsible method: lowerLadder::doit and highLadder::doit
+const uint16 freddypharkasSignatureLadderEvent[] = {
+ 0x39, SIG_MAGICDWORD,
+ SIG_SELECTOR8 + SELECTOR_new, // pushi new
+ 0x76, // push0
+ 0x38, SIG_SELECTOR16 + SELECTOR_curEvent, // pushi curEvent
+ 0x76, // push0
+ 0x81, 0x50, // lag global[50]
+ 0x4a, 0x04, // send 04 - read User::curEvent
+ 0x4a, 0x04, // send 04 - call curEvent::new
+ 0xa5, 0x00, // sat temp[0]
+ 0x38, SIG_SELECTOR16 + SELECTOR_localize,
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - call curEvent::localize
+ SIG_END
};
const uint16 freddypharkasPatchLadderEvent[] = {
- 0x34, 0x00, 0x00, // ldi 0000 (waste 3 bytes, overwrites first 2 pushes)
+ 0x34, 0x00, 0x00, // ldi 0000 (waste 3 bytes, overwrites first 2 pushes)
PATCH_ADDTOOFFSET | +8,
- 0xa5, 0x00, // sat temp[0] (waste 2 bytes, overwrites 2nd send)
+ 0xa5, 0x00, // sat temp[0] (waste 2 bytes, overwrites 2nd send)
PATCH_ADDTOOFFSET | +2,
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000 (waste 6 bytes, overwrites last 3 opcodes)
+ 0x34, 0x00, 0x00, // ldi 0000
+ 0x34, 0x00, 0x00, // ldi 0000 (waste 6 bytes, overwrites last 3 opcodes)
PATCH_END
};
// In the Macintosh version of Freddy Pharkas, kRespondsTo is broken for
// property selectors. They hacked the script to work around the issue,
// so we revert the script back to using the values of the DOS script.
-const byte freddypharkasSignatureMacInventory[] = {
- 10,
- 0x39, 0x23, // pushi 23
- 0x39, 0x74, // pushi 74
- 0x78, // push1
- 0x38, 0x01, 0x74, // pushi 0174
- 0x85, 0x15, // lat 15
- 0
+// Applies to at least: English Mac
+// Responsible method: unknown
+const uint16 freddypharkasSignatureMacInventory[] = {
+ SIG_MAGICDWORD,
+ 0x39, 0x23, // pushi 23
+ 0x39, 0x74, // pushi 74
+ 0x78, // push1
+ 0x38, SIG_UINT16 + 0x74, 0x01, // pushi 0174 (on mac it's actually 0x01, 0x74)
+ 0x85, 0x15, // lat 15
+ SIG_END
};
const uint16 freddypharkasPatchMacInventory[] = {
- 0x39, 0x02, // pushi 02 (now matches the DOS version)
- 0x39, 0x74, // pushi 74
- 0x78, // push1
- 0x38, 0x01, 0x74, // pushi 0174
- 0x85, 0x15, // lat 15
- 0x4a, 0x06, // send 06
- 0x31, 0x08, // bnt 08
- 0x38, 0x01, 0x74, // pushi 0174
- 0x76, // push0
- 0x85, 0x15, // lat 15
- 0x4a, 0x04, // send 04
- 0x02, // add
- 0xa5, 0x12, // sat 12
- 0x39, 0x04, // pushi 04 (now matches the DOS version)
+ 0x39, 0x02, // pushi 02 (now matches the DOS version)
+ PATCH_ADDTOOFFSET +23,
+ 0x39, 0x04, // pushi 04 (now matches the DOS version)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature freddypharkasSignatures[] = {
- { 0, "CD: score early disposal", 1, PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- { 15, "Mac: broken inventory", 1, PATCH_MAGICDWORD(0x39, 0x23, 0x39, 0x74), 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
- { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
- { 320, "ladder event issue", 2, PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
+// script, description, signature patch
+SciScriptPatcherEntry freddypharkasSignatures[] = {
+ { true, 0, "CD: score early disposal", 1, 0, 0, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
+ { true, 15, "Mac: broken inventory", 1, 0, 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
+ { true, 235, "CD: canister pickup hang", 3, 0, 0, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
+ { true, 320, "ladder event issue", 2, 0, 0, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
// daySixBeignet::changeState (4) is called when the cop goes out and sets cycles to 220.
// this is not enough time to get to the door, so we patch that to 23 seconds
-const byte gk1SignatureDay6PoliceBeignet[] = {
- 4,
- 0x35, 0x04, // ldi 04
- 0x1a, // eq?
- 0x30, // bnt [next state check]
- +2, 5, // [skip 2 bytes, offset of bnt]
- 0x38, 0x93, 0x00, // pushi 93 (selector dispose)
- 0x76, // push0
- 0x72, // lofsa deskSarg
- +2, 9, // [skip 2 bytes, offset of lofsa]
- 0x4a, 0x04, 0x00, // send 04
- 0x34, 0xdc, 0x00, // ldi 220
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
- 0
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: daySixBeignet::changeState
+const uint16 gk1SignatureDay6PoliceBeignet[] = {
+ 0x35, 0x04, // ldi 04
+ 0x1a, // eq?
+ 0x30, SIG_ADDTOOFFSET +2, // bnt [next state check]
+ 0x38, SIG_SELECTOR16 + SELECTOR_dispose, // pushi dispose
+ 0x76, // push0
+ 0x72, SIG_ADDTOOFFSET +2, // lofsa deskSarg
+ 0x4a, SIG_UINT16 + 0x04, 0x00, // send 04
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16 + 0xdc, 0x00, // ldi 220
+ 0x65, SIG_ADDTOOFFSET +1, // aTop cycles (1a for PC, 1c for Mac)
+ 0x32, // jmp [end]
+ SIG_END
};
const uint16 gk1PatchDay6PoliceBeignet[] = {
- PATCH_ADDTOOFFSET | +16,
- 0x34, 0x17, 0x00, // ldi 23
- 0x65, 0x1c, // aTop seconds
+ PATCH_ADDTOOFFSET +16,
+ 0x34, PATCH_UINT16 + 0x17, 0x00, // ldi 23
+ 0x65, PATCH_GETORIGINALBYTEADJUST +20, +2, // aTop seconds (1c for PC, 1e for Mac)
PATCH_END
};
// sargSleeping::changeState (8) is called when the cop falls asleep and sets cycles to 220.
// this is not enough time to get to the door, so we patch it to 42 seconds
-const byte gk1SignatureDay6PoliceSleep[] = {
- 4,
- 0x35, 0x08, // ldi 08
- 0x1a, // eq?
- 0x31, // bnt [next state check]
- +1, 6, // [skip 1 byte, offset of bnt]
- 0x34, 0xdc, 0x00, // ldi 220
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: sargSleeping::changeState
+const uint16 gk1SignatureDay6PoliceSleep[] = {
+ 0x35, 0x08, // ldi 08
+ 0x1a, // eq?
+ 0x31, SIG_ADDTOOFFSET +1, // bnt [next state check]
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16 + 0xdc, 0x00, // ldi 220
+ 0x65, SIG_ADDTOOFFSET +1, // aTop cycles (1a for PC, 1c for Mac)
+ 0x32, // jmp [end]
0
};
const uint16 gk1PatchDay6PoliceSleep[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x34, 0x2a, 0x00, // ldi 42
- 0x65, 0x1c, // aTop seconds
+ PATCH_ADDTOOFFSET +5,
+ 0x34, SIG_UINT16 + 0x2a, 0x00, // ldi 42
+ 0x65, PATCH_GETORIGINALBYTEADJUST +9, +2, // aTop seconds (1c for PC, 1e for Mac)
PATCH_END
};
// startOfDay5::changeState (20h) - when gabriel goes to the phone the script will hang
-const byte gk1SignatureDay5PhoneFreeze[] = {
- 5,
- 0x35, 0x03, // ldi 03
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
- +2, 3, // [skip 2 bytes, offset of jmp]
- 0x3c, // dup
- 0x35, 0x21, // ldi 21
- 0
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: startOfDay5::changeState
+const uint16 gk1SignatureDay5PhoneFreeze[] = {
+ 0x4a,
+ SIG_MAGICDWORD, SIG_UINT16 + 0x0c, 0x00, // send 0c
+ 0x35, 0x03, // ldi 03
+ 0x65, SIG_ADDTOOFFSET +1, // aTop cycles
+ 0x32, SIG_ADDTOOFFSET +2, // jmp [end]
+ 0x3c, // dup
+ 0x35, 0x21, // ldi 21
+ SIG_END
};
const uint16 gk1PatchDay5PhoneFreeze[] = {
- 0x35, 0x06, // ldi 06
- 0x65, 0x20, // aTop ticks
+ PATCH_ADDTOOFFSET +3,
+ 0x35, 0x06, // ldi 01
+ 0x65, PATCH_GETORIGINALBYTEADJUST +6, +6, // aTop ticks
PATCH_END
};
@@ -478,63 +641,66 @@ const uint16 gk1PatchDay5PhoneFreeze[] = {
// comparison between a number an an object. In the CD version, the checks are
// in the correct order, thus the comparison is correct, thus we use the code
// from the CD version in the floppy one.
-const byte gk1SignatureInterrogationBug[] = {
- 43,
- 0x65, 0x4c, // aTop 4c
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x1e, // gt?
- 0x31, 0x08, // bnt 08 [05a0]
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x04, // sub
- 0x65, 0x50, // aTop 50
- 0x63, 0x50, // pToa 50
- 0x31, 0x15, // bnt 15 [05b9]
- 0x39, 0x0e, // pushi 0e
- 0x76, // push0
- 0x4a, 0x04, 0x00, // send 0004
- 0xa5, 0x00, // sat 00
- 0x38, 0x93, 0x00, // pushi 0093
- 0x76, // push0
- 0x63, 0x50, // pToa 50
- 0x4a, 0x04, 0x00, // send 0004
- 0x85, 0x00, // lat 00
- 0x65, 0x50, // aTop 50
- 0
+// Applies to at least: English Floppy
+// Responsible method: Interrogation::dispose
+// TODO: Check, if English Mac is affected too and if this patch applies
+const uint16 gk1SignatureInterrogationBug[] = {
+ SIG_MAGICDWORD,
+ 0x65, 0x4c, // aTop 4c
+ 0x67, 0x50, // pTos 50
+ 0x34, SIG_UINT16 + 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05a0]
+ 0x67, 0x50, // pTos 50
+ 0x34, SIG_UINT16 + 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, SIG_UINT16 + 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, SIG_SELECTOR16 + SELECTOR_dispose, // pushi dispose
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, SIG_UINT16 + 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ SIG_END
};
const uint16 gk1PatchInterrogationBug[] = {
- 0x65, 0x4c, // aTop 4c
- 0x63, 0x50, // pToa 50
- 0x31, 0x15, // bnt 15 [05b9]
- 0x39, 0x0e, // pushi 0e
- 0x76, // push0
- 0x4a, 0x04, 0x00, // send 0004
- 0xa5, 0x00, // sat 00
- 0x38, 0x93, 0x00, // pushi 0093
- 0x76, // push0
- 0x63, 0x50, // pToa 50
- 0x4a, 0x04, 0x00, // send 0004
- 0x85, 0x00, // lat 00
- 0x65, 0x50, // aTop 50
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x1e, // gt?
- 0x31, 0x08, // bnt 08 [05b9]
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x04, // sub
- 0x65, 0x50, // aTop 50
+ 0x65, 0x4c, // aTop 4c
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, SIG_SELECTOR16 + SELECTOR_dispose, // pushi dispose
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0x67, 0x50, // pTos 50
+ 0x34, PATCH_UINT16 + 0x10, 0x27, // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05b9]
+ 0x67, 0x50, // pTos 50
+ 0x34, PATCH_UINT16 + 0x10, 0x27, // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature gk1Signatures[] = {
- { 51, "interrogation bug", 1, PATCH_MAGICDWORD(0x65, 0x4c, 0x67, 0x50), 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
- { 212, "day 5 phone freeze", 1, PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
- { 230, "day 6 police beignet timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
- { 230, "day 6 police sleep timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+// script, description, signature patch
+SciScriptPatcherEntry gk1Signatures[] = {
+ { true, 51, "interrogation bug", 1, 0, 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
+ { true, 212, "day 5 phone freeze", 1, 0, 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+ { true, 230, "day 6 police beignet timer issue", 1, 0, 0, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+ { true, 230, "day 6 police sleep timer issue", 1, 0, 0, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -544,47 +710,47 @@ const SciScriptSignature gk1Signatures[] = {
// is later used to set master volume. This issue makes sierra sci set
// the volume to max. We fix the export, so volume won't get modified in
// those cases.
-const byte kq5SignatureCdHarpyVolume[] = {
- 34,
- 0x80, 0x91, 0x01, // lag global[191h]
- 0x18, // not
- 0x30, 0x2c, 0x00, // bnt [jump further] (jumping, if global 191h is 1)
- 0x35, 0x01, // ldi 01
- 0xa0, 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0x36, // push
- 0x35, 0x04, // ldi 04
- 0x20, // ge? (followed by bnt)
- 0
+const uint16 kq5SignatureCdHarpyVolume[] = {
+ SIG_MAGICDWORD,
+ 0x80, SIG_UINT16 + 0x91, 0x01, // lag global[191h]
+ 0x18, // not
+ 0x30, SIG_UINT16 + 0x2c, 0x00, // bnt [jump further] (jumping, if global 191h is 1)
+ 0x35, 0x01, // ldi 01
+ 0xa0, SIG_UINT16 + 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
+ 0x38, SIG_UINT16 + 0x7b, 0x01, // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
+ 0x38, SIG_UINT16 + 0x7b, 0x01, // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0x36, // push
+ 0x35, 0x04, // ldi 04
+ 0x20, // ge? (followed by bnt)
+ SIG_END
};
const uint16 kq5PatchCdHarpyVolume[] = {
- 0x38, 0x2f, 0x02, // pushi 022f (selector theVol) (3 new bytes)
- 0x76, // push0 (1 new byte)
- 0x51, 0x88, // class SpeakTimer (2 new bytes)
- 0x4a, 0x04, // send 04 (2 new bytes) -> read SpeakTimer::theVol
- 0xa5, 0x03, // sat temp[3] (2 new bytes) -> write to temp 3
- 0x80, 0x91, 0x01, // lag global[191h]
+ 0x38, PATCH_UINT16 + 0x2f, 0x02, // pushi 022f (selector theVol) (3 new bytes)
+ 0x76, // push0 (1 new byte)
+ 0x51, 0x88, // class SpeakTimer (2 new bytes)
+ 0x4a, 0x04, // send 04 (2 new bytes) -> read SpeakTimer::theVol
+ 0xa5, 0x03, // sat temp[3] (2 new bytes) -> write to temp 3
+ 0x80, PATCH_UINT16 + 0x91, 0x01, // lag global[191h]
// saving 1 byte due optimization
- 0x2e, 0x23, 0x00, // bt [jump further] (jumping, if global 191h is 1)
- 0x35, 0x01, // ldi 01
- 0xa0, 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
+ 0x2e, PATCH_UINT16 + 0x23, 0x00, // bt [jump further] (jumping, if global 191h is 1)
+ 0x35, 0x01, // ldi 01
+ 0xa0, PATCH_UINT16 + 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
+ 0x38, PATCH_UINT16 + 0x7b, 0x01, // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
// saving 8 bytes due removing of duplicate code
- 0x39, 0x04, // pushi 04 (saving 1 byte due swapping)
- 0x22, // lt? (because we switched values)
+ 0x39, 0x04, // pushi 04 (saving 1 byte due swapping)
+ 0x22, // lt? (because we switched values)
PATCH_END
};
@@ -596,30 +762,32 @@ const uint16 kq5PatchCdHarpyVolume[] = {
// Additionally its top,left,bottom,right properties are set to 0 rather
// than the right values. We fix the object by setting the right values.
// If they are all zero, this causes an impossible position check in
-// witch::cantBeHere and an infinite loop when entering room 22 (bug #3034714).
+// witch::cantBeHere and an infinite loop when entering room 22.
//
// This bug is accidentally not triggered in SSCI because the invalid number
// of variables effectively hides witchCage::doit, causing this position check
// to be bypassed entirely.
// See also the warning+comment in Object::initBaseObject
-const byte kq5SignatureWitchCageInit[] = {
- 16,
- 0x00, 0x00, // top
- 0x00, 0x00, // left
- 0x00, 0x00, // bottom
- 0x00, 0x00, // right
- 0x00, 0x00, // extra property #1
- 0x7a, 0x00, // extra property #2
- 0xc8, 0x00, // extra property #3
- 0xa3, 0x00, // extra property #4
- 0
+//
+// Fixes bug: #4964
+const uint16 kq5SignatureWitchCageInit[] = {
+ SIG_UINT16 + 0x00, 0x00, // top
+ SIG_UINT16 + 0x00, 0x00, // left
+ SIG_UINT16 + 0x00, 0x00, // bottom
+ SIG_UINT16 + 0x00, 0x00, // right
+ SIG_UINT16 + 0x00, 0x00, // extra property #1
+ SIG_MAGICDWORD,
+ SIG_UINT16 + 0x7a, 0x00, // extra property #2
+ SIG_UINT16 + 0xc8, 0x00, // extra property #3
+ SIG_UINT16 + 0xa3, 0x00, // extra property #4
+ SIG_END
};
const uint16 kq5PatchWitchCageInit[] = {
- 0x00, 0x00, // top
- 0x7a, 0x00, // left
- 0xc8, 0x00, // bottom
- 0xa3, 0x00, // right
+ PATCH_UINT16 + 0x00, 0x00, // top
+ PATCH_UINT16 + 0x7a, 0x00, // left
+ PATCH_UINT16 + 0xc8, 0x00, // bottom
+ PATCH_UINT16 + 0xa3, 0x00, // right
PATCH_END
};
@@ -637,31 +805,25 @@ const uint16 kq5PatchWitchCageInit[] = {
// changes to GameFeatures::detectsetCursorType() ) and breaking savegame
// compatibilty between the DOS and Windows CD versions of KQ5.
// TODO: Investigate these side effects more closely.
-const byte kq5SignatureWinGMSignals[] = {
- 9,
- 0x80, 0x90, 0x01, // lag 0x190
- 0x18, // not
- 0x30, 0x1b, 0x00, // bnt +0x001B
- 0x89, 0x57, // lsg 0x57
- 0
+const uint16 kq5SignatureWinGMSignals[] = {
+ SIG_MAGICDWORD,
+ 0x80, SIG_UINT16 + 0x90, 0x01, // lag 0x190
+ 0x18, // not
+ 0x30, SIG_UINT16 + 0x1b, 0x00, // bnt +0x001B
+ 0x89, 0x57, // lsg 0x57
+ SIG_END
};
const uint16 kq5PatchWinGMSignals[] = {
- 0x34, 0x01, 0x00, // ldi 0x0001
+ 0x34, PATCH_UINT16 + 0x01, 0x00, // ldi 0x0001
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature kq5Signatures[] = {
- { 0, "CD: harpy volume change", 1, PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, PATCH_MAGICDWORD(0x7a, 0x00, 0xc8, 0x00), -10, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- SCI_SIGNATUREENTRY_TERMINATOR
-};
-
-const SciScriptSignature kq5WinGMSignatures[] = {
- { 0, "CD: harpy volume change", 1, PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, PATCH_MAGICDWORD(0x7a, 0x00, 0xc8, 0x00), -10, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- { 124, "Win: GM Music signal checks", 4, PATCH_MAGICDWORD(0x80, 0x90, 0x01, 0x18), 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
+// script, description, signature patch
+SciScriptPatcherEntry kq5Signatures[] = {
+ { true, 0, "CD: harpy volume change", 1, 0, 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
+ { true, 200, "CD: witch cage init", 1, 0, 0, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
+ { false, 124, "Win: GM Music signal checks", 4, 0, 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -673,25 +835,203 @@ const SciScriptSignature kq5WinGMSignatures[] = {
// sound is played twice, squelching all other sounds. We just rip the
// unnecessary cryMusic::check method out, thereby stopping the sound from
// constantly restarting (since it's being looped anyway), thus the normal
-// game speech can work while the baby cry sound is heard. Fixes bug #3034579.
-const byte kq6SignatureDuplicateBabyCry[] = {
- 10,
- 0x83, 0x00, // lal 00
- 0x31, 0x1e, // bnt 1e [07f4]
- 0x78, // push1
- 0x39, 0x04, // pushi 04
- 0x43, 0x75, 0x02, // callk DoAudio[75] 02
- 0
+// game speech can work while the baby cry sound is heard.
+// Fixes bug: #4955
+const uint16 kq6SignatureDuplicateBabyCry[] = {
+ SIG_MAGICDWORD,
+ 0x83, 0x00, // lal 00
+ 0x31, 0x1e, // bnt 1e [07f4]
+ 0x78, // push1
+ 0x39, 0x04, // pushi 04
+ 0x43, 0x75, 0x02, // callk DoAudio[75] 02
+ SIG_END
};
const uint16 kq6PatchDuplicateBabyCry[] = {
- 0x48, // ret
+ 0x48, // ret
+ PATCH_END
+};
+
+// The inventory of King's Quest 6 is buggy. When it grows too large,
+// it will get split into 2 pages. Switching between those pages will
+// grow the stack, because it's calling itself per switch.
+// Which means after a while ScummVM will bomb out because the stack frame
+// will be too large. This patch fixes the buggy script.
+// Applies to at least: PC-CD, English PC floppy, German PC floppy, English Mac
+// Responsible method: KqInv::showSelf
+// Fixes bug: #5681
+const uint16 kq6SignatureInventoryStackFix[] = {
+ 0x67, 0x30, // pTos state
+ 0x34, SIG_UINT16 + 0x00, 0x20, // ldi 2000
+ 0x12, // and
+ 0x18, // not
+ 0x31, 0x04, // bnt [not first refresh]
+ 0x35, 0x00, // ldi 00
+ SIG_MAGICDWORD,
+ 0x65, 0x1e, // aTop curIcon
+ 0x67, 0x30, // pTos state
+ 0x34, SIG_UINT16 + 0xff, 0xdf, // ldi dfff
+ 0x12, // and
+ 0x65, 0x30, // aTop state
+ 0x38, SIG_SELECTOR16 + SELECTOR_show, // pushi "show" ("show" is e1h for KQ6CD)
+ 0x78, // push1
+ 0x87, 0x00, // lap param[0]
+ 0x31, 0x04, // bnt [use global for show]
+ 0x87, 0x01, // lap param[1]
+ 0x33, 0x02, // jmp [use param for show]
+ 0x81, 0x00, // lag global[0]
+ 0x36, // push
+ 0x54, 0x06, // self 06 (KqInv::show)
+ 0x31, SIG_ADDTOOFFSET + 1, // bnt [exit menu code] (0x08 for PC, 0x07 for mac)
+ 0x39, 0x39, // pushi 39
+ 0x76, // push0
+ 0x54, 0x04, // self 04 (KqInv::doit)
+ SIG_END // followed by jmp (0x32 for PC, 0x33 for mac)
+};
+
+const uint16 kq6PatchInventoryStackFix[] = {
+ 0x67, 0x30, // pTos state
+ 0x3c, // dup (1 more byte, needed for patch)
+ 0x3c, // dup (1 more byte, saves 1 byte later)
+ 0x34, PATCH_UINT16 + 0x00, 0x20, // ldi 2000
+ 0x12, // and
+ 0x2f, 0x02, // bt [not first refresh] - saves 3 bytes in total
+ 0x65, 0x1e, // aTop curIcon
+ 0x00, // neg (either 2000 or 0000 in acc, this will create dfff or ffff) - saves 2 bytes
+ 0x12, // and
+ 0x65, 0x30, // aTop state
+ 0x38, // pushi "show"
+ PATCH_GETORIGINALBYTE +22,
+ PATCH_GETORIGINALBYTE +23,
+ 0x78, // push1
+ 0x87, 0x00, // lap param[0]
+ 0x31, 0x04, // bnt [call show using global 0]
+ 0x8f, 0x01, // lsp param[1], save 1 byte total with lsg global[0] combined
+ 0x33, 0x02, // jmp [call show using param 1]
+ 0x89, 0x00, // lsg global[0], save 1 byte total, see above
+ 0x54, 0x06, // self 06 (call x::show)
+ 0x31, // bnt [menu exit code]
+ PATCH_GETORIGINALBYTEADJUST +39, +6,// dynamic offset must be 0x0E for PC and 0x0D for mac
+ 0x34, PATCH_UINT16 + 0x00, 0x20, // ldi 2000
+ 0x12, // and
+ 0x2f, 0x05, // bt [to return]
+ 0x39, 0x39, // pushi 39
+ 0x76, // push0
+ 0x54, 0x04, // self 04 (self::doit)
+ 0x48, // ret (saves 2 bytes for PC, 1 byte for mac)
+ PATCH_END
+};
+
+// Audio + subtitles support - SHARED! - used for King's Quest 6 and Laura Bow 2
+// this patch gets enabled, when the user selects "both" in the ScummVM "Speech + Subtitles" menu
+// We currently use global 98d to hold a kMemory pointer.
+// Patched method: Messager::sayNext / lb2Messager::sayNext (always use text branch)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = {
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ SIG_MAGICDWORD,
+ 0x31, 0x13, // bnt [audio call]
+ 0x38, SIG_SELECTOR16 + SELECTOR_modNum, // pushi modNum
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport1[] = {
+ PATCH_ADDTOOFFSET +5,
+ 0x33, 0x13, // jmp [audio call]
+ PATCH_END
+};
+
+// Patched method: Messager::sayNext / lb2Messager::sayNext (allocate audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = {
+ 0x7a, // push2
+ 0x78, // push1
+ 0x39, 0x0c, // pushi 0c
+ 0x43, SIG_MAGICDWORD, 0x72, 0x04, // kMemory
+ 0xa5, 0xc9, // sat global[c9]
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport2[] = {
+ PATCH_ADDTOOFFSET +7,
+ 0xa1, 98, // sag global[98d]
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature kq6Signatures[] = {
- { 481, "duplicate baby cry", 1, PATCH_MAGICDWORD(0x83, 0x00, 0x31, 0x1e), 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+// Patched method: Messager::sayNext / lb2Messager::sayNext (release audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = {
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ SIG_MAGICDWORD,
+ 0x8d, 0xc9, // lst temp[c9]
+ 0x43, 0x72, 0x04, // kMemory
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport3[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x89, 98, // lsg global[98d]
+ PATCH_END
+};
+
+// Patched method: Narrator::say (use audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = {
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ 0x38, SIG_SELECTOR16 + SELECTOR_startText, // pushi startText
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16 + SELECTOR_startAudio, // pushi startAudio
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = {
+ PATCH_ADDTOOFFSET +5,
+ 0x18, // not (never jump here)
+ 0x18, // not (never jump here)
+ PATCH_ADDTOOFFSET +19,
+ 0x89, 98, // lsp global[98d]
+ PATCH_END
+};
+
+// Patched method: Talker::display/Narrator::say (remove reset saved mouse cursor code)
+// code would screw over mouse cursor
+const uint16 kq6laurabow2CDSignatureAudioTextSupport5[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x82, // aTop saveCursor
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = {
+ 0x18, 0x18, 0x18, 0x18, // waste bytes, do nothing
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry kq6Signatures[] = {
+ { true, 481, "duplicate baby cry", 1, 0, 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+ { true, 907, "inventory stack fix", 1, 0, 0, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ // *** King's Quest 6 audio + text support - CURRENTLY DISABLED ***
+ // TODO: fix window placement (currently part of the text windows go off-screen)
+ // TODO: fix hi-res portraits mode graphic glitches
+ { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -704,40 +1044,111 @@ const SciScriptSignature kq6Signatures[] = {
// the function is undefined, thus kStrCat() that is called inside the function
// reads a random pointer and crashes. We patch all of the 5 function calls
// (one for each letter typed from "R", "O", "B", "I", "N") so that they are
-// the same as the English version. Fixes bug #3048054.
-const byte longbowSignatureShowHandCode[] = {
- 3,
- 0x78, // push1
- 0x78, // push1
- 0x72, // lofsa
- +2, 2, // skip 2 bytes, offset of lofsa (the letter typed)
- 0x36, // push
- 0x40, // call
- +2, 3, // skip 2 bytes, offset of call
- 0x02, // perform the call above with 2 parameters
- 0x36, // push
- 0x40, // call
- +2, 8, // skip 2 bytes, offset of call
- 0x02, // perform the call above with 2 parameters
- 0x38, 0x1c, 0x01, // pushi 011c (setMotion)
- 0x39, 0x04, // pushi 04 (x)
- 0x51, 0x1e, // class MoveTo
- 0
+// the same as the English version.
+// Applies to at least: German floppy
+// Responsible method: unknown
+// Fixes bug: #5264
+const uint16 longbowSignatureShowHandCode[] = {
+ 0x78, // push1
+ 0x78, // push1
+ 0x72, SIG_ADDTOOFFSET +2, // lofsa (letter, that was typed)
+ 0x36, // push
+ 0x40, SIG_ADDTOOFFSET +2, // call
+ 0x02, // perform the call above with 2 parameters
+ 0x36, // push
+ 0x40, SIG_ADDTOOFFSET +2, // call
+ SIG_MAGICDWORD,
+ 0x02, // perform the call above with 2 parameters
+ 0x38, SIG_SELECTOR16 + SELECTOR_setMotion, // pushi "setMotion" (0x11c in Longbow German)
+ 0x39, SIG_SELECTOR8 + SELECTOR_x, // pushi "x" (0x04 in Longbow German)
+ 0x51, 0x1e, // class MoveTo
+ SIG_END
};
const uint16 longbowPatchShowHandCode[] = {
- 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version)
- PATCH_ADDTOOFFSET | +3, // leave the lofsa call untouched
+ 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version)
+ PATCH_ADDTOOFFSET +3, // leave the lofsa call untouched
// The following will remove the duplicate call
- 0x32, 0x02, 0x00, // jmp 02 - skip 2 bytes (the remainder of the first call)
- 0x48, // ret (dummy, should never be reached)
- 0x48, // ret (dummy, should never be reached)
+ 0x32, PATCH_UINT16 + 0x02, 0x00, // jmp 02 - skip 2 bytes (the remainder of the first call)
+ 0x48, // ret (dummy, should never be reached)
+ 0x48, // ret (dummy, should never be reached)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature longbowSignatures[] = {
- { 210, "hand code crash", 5, PATCH_MAGICDWORD(0x02, 0x38, 0x1c, 0x01), -14, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+// script, description, signature patch
+SciScriptPatcherEntry longbowSignatures[] = {
+ { true, 210, "hand code crash", 5, 0, 0, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
+// Leisure Suit Larry 2
+// On the plane, Larry is able to wear the parachute. This grants 4 points.
+// In early versions of LSL2, it was possible to get "unlimited" points by
+// simply wearing it multiple times.
+// They fixed it in later versions by remembering, if the parachute was already
+// used before.
+// But instead of adding it properly, it seems they hacked the script / forgot
+// to replace script 0 as well, which holds information about how many global
+// variables are allocated at the start of the game.
+// The script tries to read an out-of-bounds global variable, which somewhat
+// "worked" in SSCI, but ScummVM/SCI doesn't allow that.
+// That's why those points weren't granted here at all.
+// We patch the script to use global 90, which seems to be unused in the whole game.
+// Applies to at least: English floppy
+// Responsible method: rm63Script::handleEvent
+// Fixes bug: #6346
+const uint16 larry2SignatureWearParachutePoints[] = {
+ 0x35, 0x01, // ldi 01
+ 0xa1, SIG_MAGICDWORD, 0x8e, // sag 8e
+ 0x80, SIG_UINT16 + 0xe0, 0x01, // lag 1e0
+ 0x18, // not
+ 0x30, SIG_UINT16 + 0x0f, 0x00, // bnt [don't give points]
+ 0x35, 0x01, // ldi 01
+ 0xa0, 0xe0, 0x01, // sag 1e0
+ SIG_END
+};
+
+const uint16 larry2PatchWearParachutePoints[] = {
+ PATCH_ADDTOOFFSET +4,
+ 0x80, PATCH_UINT16 + 0x5a, 0x00, // lag 5a (global 90)
+ PATCH_ADDTOOFFSET +6,
+ 0xa0, PATCH_UINT16 + 0x5a, 0x00, // sag 5a (global 90)
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry larry2Signatures[] = {
+ { true, 63, "plane: no points for wearing plane", 1, 0, 0, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
+// Leisure Suit Larry 5
+// In one of the conversations near the end (to be exact - room 380 and the text
+// about using champagne on Reverse Biaz - only used when you actually did that
+// in the game), the German text is too large, causing the textbox to get too large.
+// Because of that the talking head of Patti is drawn over the textbox. A translation oversight.
+// Applies to at least: German floppy
+// Responsible method: none, position of talker object on screen needs to get modified
+const uint16 larry5SignatureGermanEndingPattiTalker[] = {
+ SIG_MAGICDWORD,
+ SIG_UINT16 + 0x6e, 0x00, // object pattiTalker::x (110)
+ SIG_UINT16 + 0xb4, 0x00, // object pattiTalker::y (180)
+ SIG_ADDTOOFFSET + 469, // verify that it's really the German version
+ 0x59, 0x6f, 0x75, // (object name) "You"
+ 0x23, 0x47, 0x44, 0x75, // "#GDu"
+ SIG_END
+};
+
+const uint16 larry5PatchGermanEndingPattiTalker[] = {
+ PATCH_UINT16 + 0x5a, 0x00, // change pattiTalker::x to 90
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry larry5Signatures[] = {
+ { true, 380, "German-only: Enlarge Patti Textbox", 1, 0, 0, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -749,77 +1160,177 @@ const SciScriptSignature longbowSignatures[] = {
// doesn't happen anymore. We would otherwise get a crash
// calling for invalid views (this happens of course also
// in sierra sci)
-const byte larry6SignatureDeathDialog[] = {
- 7,
- 0x3e, 0x33, 0x01, // link 0133 (offset 0x20)
- 0x35, 0xff, // ldi ff
- 0xa3, 0x00, // sal 00
- +255, 0,
- +255, 0,
- +170, 12, // [skip 680 bytes]
- 0x8f, 0x01, // lsp 01 (offset 0x2cf)
- 0x7a, // push2
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
- 0x36, // push
- 0x43, 0x7c, 0x0e, // kMessage[7c] 0e
- +90, 10, // [skip 90 bytes]
- 0x38, 0xd6, 0x00, // pushi 00d6 (offset 0x335)
- 0x78, // push1
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
- 0x36, // push
- +76, 11, // [skip 76 bytes]
- 0x38, 0xcd, 0x00, // pushi 00cd (offset 0x38b)
- 0x39, 0x03, // pushi 03
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
+// Applies to at least: German PC-CD
+// Responsible method: unknown
+const uint16 larry6SignatureDeathDialog[] = {
+ SIG_MAGICDWORD,
+ 0x3e, SIG_UINT16 + 0x33, 0x01, // link 0133 (offset 0x20)
+ 0x35, 0xff, // ldi ff
+ 0xa3, 0x00, // sal 00
+ SIG_ADDTOOFFSET +680, // [skip 680 bytes]
+ 0x8f, 0x01, // lsp 01 (offset 0x2cf)
+ 0x7a, // push2
+ 0x5a, SIG_UINT16 + 0x04, 0x00, SIG_UINT16 + 0x0e, 0x01, // lea 0004 010e
+ 0x36, // push
+ 0x43, 0x7c, 0x0e, // kMessage[7c] 0e
+ SIG_ADDTOOFFSET +90, // [skip 90 bytes]
+ 0x38, SIG_UINT16 + 0xd6, 0x00, // pushi 00d6 (offset 0x335)
+ 0x78, // push1
+ 0x5a, SIG_UINT16 + 0x04, 0x00, SIG_UINT16 + 0x0e, 0x01, // lea 0004 010e
+ 0x36, // push
+ SIG_ADDTOOFFSET +76, // [skip 76 bytes]
+ 0x38, SIG_UINT16 + 0xcd, 0x00, // pushi 00cd (offset 0x38b)
+ 0x39, 0x03, // pushi 03
+ 0x5a, SIG_UINT16 + 0x04, 0x00, SIG_UINT16 + 0x0e, 0x01, // lea 0004 010e
0x36,
- 0
+ SIG_END
};
const uint16 larry6PatchDeathDialog[] = {
- 0x3e, 0x00, 0x02, // link 0200
- PATCH_ADDTOOFFSET | +687,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
- PATCH_ADDTOOFFSET | +98,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
- PATCH_ADDTOOFFSET | +82,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
+ 0x3e, 0x00, 0x02, // link 0200
+ PATCH_ADDTOOFFSET +687,
+ 0x5a, PATCH_UINT16 + 0x04, 0x00, PATCH_UINT16 + 0x40, 0x01, // lea 0004 0140
+ PATCH_ADDTOOFFSET +98,
+ 0x5a, PATCH_UINT16 + 0x04, 0x00, PATCH_UINT16 + 0x40, 0x01, // lea 0004 0140
+ PATCH_ADDTOOFFSET +82,
+ 0x5a, PATCH_UINT16 + 0x04, 0x00, PATCH_UINT16 + 0x40, 0x01, // lea 0004 0140
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature larry6Signatures[] = {
- { 82, "death dialog memory corruption", 1, PATCH_MAGICDWORD(0x3e, 0x33, 0x01, 0x35), 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
+// script, description, signature patch
+SciScriptPatcherEntry larry6Signatures[] = {
+ { true, 82, "death dialog memory corruption", 1, 0, 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
-// rm560::doit was supposed to close the painting, when Heimlich enters the
-// room. The code is buggy, so it actually closes the painting, when heimlich
-// is not in the room. We fix that.
-const byte laurabow2SignaturePaintingClosing[] = {
- 17,
- 0x4a, 0x04, // send 04 - read aHeimlich::room
- 0x36, // push
- 0x81, 0x0b, // lag global[11d] -> current room
- 0x1c, // ne?
- 0x31, 0x0e, // bnt [don't close]
- 0x35, 0x00, // ldi 00
- 0xa3, 0x00, // sal local[0]
- 0x38, 0x92, 0x00, // pushi 0092
- 0x78, // push1
- 0x72, // lofsa sDumpSafe
- 0
+// Laura Bow 2
+//
+// Moving away the painting in the room with the hidden safe is problematic
+// for the CD version of the game. safePic::doVerb gets triggered by the mouse-click.
+// This method sets local 0 as signal, which is only meant to get handled, when
+// the player clicks again to move the painting back. This signal is processed by
+// the room doit-script.
+// That doit-script checks safePic::cel to be not equal 0 and would then skip over
+// the "close painting" trigger code. On very fast computers this script may
+// get called too early (which is the case when running under ScummVM and when
+// running the game using Sierra SCI in DOS-Box with cycles 15000) and thinks
+// that it's supposed to move the painting back. Which then results in the painting
+// getting moved to its original position immediately (which means it won't be possible
+// to access the safe behind it).
+//
+// We patch the script, so that we check for cel to be not equal 4 (the final cel) and
+// we also reset the safePic-signal immediately as well.
+//
+// In the floppy version Laura's coordinates are checked directly in rm560::doit
+// and as soon as she moves, the painting will automatically move to its original position.
+// This is not the case for the CD version of the game. The painting will only "move" back,
+// when the player actually exits the room and re-enters.
+//
+// Applies to at least: English PC-CD
+// Responsible method: rm560::doit
+// Fixes bug: #6460
+const uint16 laurabow2CDSignaturePaintingClosing[] = {
+ 0x39, 0x04, // pushi 04 (cel)
+ 0x76, // push0
+ SIG_MAGICDWORD,
+ 0x7a, // push2
+ 0x38, SIG_UINT16 + 0x31, 0x02, // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x18, // not
+ 0x31, 0x21, // bnt [exit]
+ 0x38, SIG_UINT16 + 0x83, 0x02, // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
+ 0x36, // push
+ 0x81, 0x0b, // lag global[b] (current room)
+ 0x1c, // ne?
+ 0x31, 0x0e, // bnt [exit]
+ 0x35, 0x00, // ldi 00
+ 0xa3, 0x00, // sal local[0] -> reset safePic signal
+ SIG_END
+};
+
+const uint16 laurabow2CDPatchPaintingClosing[] = {
+ PATCH_ADDTOOFFSET +2,
+ 0x3c, // dup (1 additional byte)
+ 0x76, // push0
+ 0x3c, // dup (1 additional byte)
+ 0xab, 0x00, // ssl local[0] -> reset safePic signal
+ 0x7a, // push2
+ 0x38, PATCH_UINT16 + 0x31, 0x02, // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x1a, // eq?
+ 0x31, 0x1d, // bnt [exit]
+ 0x38, PATCH_UINT16 + 0x83, 0x02, // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
+ 0x36, // push
+ 0x81, 0x0b, // lag global[b] (current room)
+ 0x1a, // eq? (2 opcodes changed, to save 2 bytes)
+ 0x2f, 0x0a, // bt [exit]
+ PATCH_END
};
-const uint16 laurabow2PatchPaintingClosing[] = {
- PATCH_ADDTOOFFSET | +6,
- 0x2f, 0x0e, // bt [don't close]
+// In the CD version the system menu is disabled for certain rooms. LB2::handsOff is called,
+// when leaving the room (and in other cases as well). This method remembers the disabled
+// icons of the icon bar. In the new room LB2::handsOn will get called, which then enables
+// all icons, but also disabled the ones, that were disabled before.
+//
+// Because of this behaviour certain rooms, that should have the system menu enabled, have
+// it disabled, when entering those rooms from rooms, where the menu is supposed to be
+// disabled.
+//
+// We patch this by injecting code into LB2::newRoom (which is called right after a room change)
+// and reset the global variable there, that normally holds the disabled buttons.
+//
+// This patch may cause side-effects and it's difficult to test, because it affects every room
+// in the game. At least for the intro, the speakeasy and plenty of rooms in the beginning it
+// seems to work correctly.
+//
+// Applies to at least: English PC-CD
+// Responsible method: LB2::newRoom, LB2::handsOff, LB2::handsOn
+// Fixes bug: #6440
+const uint16 laurabow2CDSignatureFixProblematicIconBar[] = {
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16 + 0xf1, 0x00, // pushi 00f1 (disable) - hardcoded, we only want to patch the CD version
+ 0x76, // push0
+ 0x81, 0x45, // lag global[45]
+ 0x4a, 0x04, // send 04
+ SIG_END
+};
+
+const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
+ 0x35, 0x00, // ldi 00
+ 0xa1, 0x74, // sag 74h
+ 0x35, 0x00, // ldi 00 (waste bytes)
+ 0x35, 0x00, // ldi 00
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature laurabow2Signatures[] = {
- { 560, "painting closing immediately", 1, PATCH_MAGICDWORD(0x36, 0x81, 0x0b, 0x1c), -2, laurabow2SignaturePaintingClosing, laurabow2PatchPaintingClosing },
+
+// script, description, signature patch
+SciScriptPatcherEntry laurabow2Signatures[] = {
+ { true, 560, "CD: painting closing immediately", 1, 0, 0, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
+ { true, 0, "CD: fix problematic icon bar", 1, 0, 0, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -828,29 +1339,27 @@ const SciScriptSignature laurabow2Signatures[] = {
// MG::replay somewhat calculates the savedgame-id used when saving again
// this doesn't work right and we remove the code completely.
// We set the savedgame-id directly right after restoring in kRestoreGame.
-const byte mothergoose256SignatureReplay[] = {
- 6,
- 0x36, // push
- 0x35, 0x20, // ldi 20
- 0x04, // sub
- 0xa1, 0xb3, // sag global[b3]
- 0
+const uint16 mothergoose256SignatureReplay[] = {
+ 0x36, // push
+ 0x35, SIG_MAGICDWORD, 0x20, // ldi 20
+ 0x04, // sub
+ 0xa1, 0xb3, // sag global[b3]
+ SIG_END
};
const uint16 mothergoose256PatchReplay[] = {
- 0x34, 0x00, 0x00, // ldi 0000 (dummy)
- 0x34, 0x00, 0x00, // ldi 0000 (dummy)
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 (dummy)
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 (dummy)
PATCH_END
};
// when saving, it also checks if the savegame ID is below 13.
// we change this to check if below 113 instead
-const byte mothergoose256SignatureSaveLimit[] = {
- 5,
- 0x89, 0xb3, // lsg global[b3]
- 0x35, 0x0d, // ldi 0d
- 0x20, // ge?
- 0
+const uint16 mothergoose256SignatureSaveLimit[] = {
+ 0x89, SIG_MAGICDWORD, 0xb3, // lsg global[b3]
+ 0x35, 0x0d, // ldi 0d
+ 0x20, // ge?
+ SIG_END
};
const uint16 mothergoose256PatchSaveLimit[] = {
@@ -859,11 +1368,74 @@ const uint16 mothergoose256PatchSaveLimit[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature mothergoose256Signatures[] = {
- { 0, "replay save issue", 1, PATCH_MAGICDWORD(0x20, 0x04, 0xa1, 0xb3), -2, mothergoose256SignatureReplay, mothergoose256PatchReplay },
- { 0, "save limit dialog (SCI1.1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
- { 994, "save limit dialog (SCI1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+// script, description, signature patch
+SciScriptPatcherEntry mothergoose256Signatures[] = {
+ { true, 0, "replay save issue", 1, 0, 0, mothergoose256SignatureReplay, mothergoose256PatchReplay },
+ { true, 0, "save limit dialog (SCI1.1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { true, 994, "save limit dialog (SCI1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
+// Police Quest 1 VGA
+// When at the police station, you can put or get your gun from your locker.
+// The script, that handles this, is buggy. It disposes the gun as soon as
+// you click, but then waits 2 seconds before it also closes the locker.
+// Problem is that it's possible to click again, which then results in a
+// disposed object getting accessed. This happened to work by pure luck in
+// SSCI.
+// This patch changes the code, so that the gun is actually given away
+// when the 2 seconds have passed and the locker got closed.
+// Applies to at least: English floppy
+// Responsible method: putGun::changeState (script 341)
+// Fixes bug: #5705 / #6400
+const uint16 pq1vgaSignaturePutGunInLockerBug[] = {
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x25, // bnt [next state check]
+ SIG_ADDTOOFFSET +22, // [skip 22 bytes]
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16 + SELECTOR_put, // pushi "put"
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06 - ego::put(0)
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
+ 0x33, 0x0e, // jmp [end of method]
+ 0x3c, // dup --- next state check target
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x08, // bnt [end of method]
+ 0x39, SIG_SELECTOR8 + SELECTOR_dispose, // pushi "dispose"
+ 0x76, // push0
+ 0x72, SIG_UINT16 + 0x88, 0x00, // lofsa 0088
+ 0x4a, 0x04, // send 04 - locker::dispose
+ SIG_END
+};
+
+const uint16 pq1vgaPatchPutGunInLockerBug[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x31, 0x1c, // bnt [next state check]
+ PATCH_ADDTOOFFSET +22,
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
+ 0x33, 0x17, // jmp [end of method]
+ 0x3c, // dup --- next state check target
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x11, // bnt [end of method]
+ 0x38, PATCH_SELECTOR16 + SELECTOR_put, // pushi "put"
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06 - ego::put(0)
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry pq1vgaSignatures[] = {
+ { true, 341, "put gun in locker bug", 1, 0, 0, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -876,43 +1448,45 @@ const SciScriptSignature mothergoose256Signatures[] = {
// not nearly as bad as in our sci, but these differences may be caused by
// timing.
// We just reuse the active event, thus removing the duplicate kGetEvent call.
-const byte qfg1vgaSignatureFightEvents[] = {
- 25,
- 0x39, 0x6d, // pushi 6d (selector new)
- 0x76, // push0
- 0x51, 0x07, // class Event
- 0x4a, 0x04, // send 04 - call Event::new
- 0xa5, 0x00, // sat temp[0]
- 0x78, // push1
- 0x76, // push0
- 0x4a, 0x04, // send 04 - read Event::x
- 0xa5, 0x03, // sat temp[3]
- 0x76, // push0 (selector y)
- 0x76, // push0
- 0x85, 0x00, // lat temp[0]
- 0x4a, 0x04, // send 04 - read Event::y
- 0x36, // push
- 0x35, 0x0a, // ldi 0a
- 0x04, // sub (poor mans localization) ;-)
- 0
+// Applies to at least: English floppy
+// Responsible method: pointBox::doit
+const uint16 qfg1vgaSignatureFightEvents[] = {
+ 0x39, SIG_MAGICDWORD,
+ SIG_SELECTOR8 + SELECTOR_new, // pushi "new"
+ 0x76, // push0
+ 0x51, 0x07, // class Event
+ 0x4a, 0x04, // send 04 - call Event::new
+ 0xa5, 0x00, // sat temp[0]
+ 0x78, // push1
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - read Event::x
+ 0xa5, 0x03, // sat temp[3]
+ 0x76, // push0 (selector y)
+ 0x76, // push0
+ 0x85, 0x00, // lat temp[0]
+ 0x4a, 0x04, // send 04 - read Event::y
+ 0x36, // push
+ 0x35, 0x0a, // ldi 0a
+ 0x04, // sub (poor mans localization) ;-)
+ SIG_END
};
const uint16 qfg1vgaPatchFightEvents[] = {
- 0x38, 0x5a, 0x01, // pushi 15a (selector curEvent)
- 0x76, // push0
- 0x81, 0x50, // lag global[50]
- 0x4a, 0x04, // send 04 - read User::curEvent -> needs one byte more than previous code
- 0xa5, 0x00, // sat temp[0]
- 0x78, // push1
- 0x76, // push0
- 0x4a, 0x04, // send 04 - read Event::x
- 0xa5, 0x03, // sat temp[3]
- 0x76, // push0 (selector y)
- 0x76, // push0
- 0x85, 0x00, // lat temp[0]
- 0x4a, 0x04, // send 04 - read Event::y
- 0x39, 0x00, // pushi 00
- 0x02, // add (waste 3 bytes) - we don't need localization, User::doit has already done it
+ 0x38, PATCH_SELECTOR16 + SELECTOR_curEvent, // pushi 15a (selector curEvent)
+ 0x76, // push0
+ 0x81, 0x50, // lag global[50]
+ 0x4a, 0x04, // send 04 - read User::curEvent -> needs one byte more than previous code
+ 0xa5, 0x00, // sat temp[0]
+ 0x78, // push1
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - read Event::x
+ 0xa5, 0x03, // sat temp[3]
+ 0x76, // push0 (selector y)
+ 0x76, // push0
+ 0x85, 0x00, // lat temp[0]
+ 0x4a, 0x04, // send 04 - read Event::y
+ 0x39, 0x00, // pushi 00
+ 0x02, // add (waste 3 bytes) - we don't need localization, User::doit has already done it
PATCH_END
};
@@ -923,66 +1497,150 @@ const uint16 qfg1vgaPatchFightEvents[] = {
// window text, which erases the window header text because of its length. To
// fix that, we allocate more temp space and move the pointer used for the
// window header a little bit, wherever it's used in script 814.
-// Fixes bug #3568431.
+// Fixes bug: #6139.
// Patch 1: Increase temp space
-const byte qfg1vgaSignatureTempSpace[] = {
- 4,
- 0x3f, 0xba, // link 0xba
- 0x87, 0x00, // lap 0
- 0
+const uint16 qfg1vgaSignatureTempSpace[] = {
+ SIG_MAGICDWORD,
+ 0x3f, 0xba, // link 0xba
+ 0x87, 0x00, // lap 0
+ SIG_END
};
const uint16 qfg1vgaPatchTempSpace[] = {
- 0x3f, 0xca, // link 0xca
+ 0x3f, 0xca, // link 0xca
PATCH_END
};
// Patch 2: Move the pointer used for the window header a little bit
-const byte qfg1vgaSignatureDialogHeader[] = {
- 4,
- 0x5b, 0x04, 0x80, // lea temp[0x80]
- 0x36, // push
- 0
+const uint16 qfg1vgaSignatureDialogHeader[] = {
+ SIG_MAGICDWORD,
+ 0x5b, 0x04, 0x80, // lea temp[0x80]
+ 0x36, // push
+ SIG_END
};
const uint16 qfg1vgaPatchDialogHeader[] = {
- 0x5b, 0x04, 0x90, // lea temp[0x90]
+ 0x5b, 0x04, 0x90, // lea temp[0x90]
PATCH_END
};
// 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.
-const byte qfg1vgaSignatureMoveToCrusher[] = {
- 9,
- 0x51, 0x1f, // class Motion
- 0x36, // push
- 0x39, 0x4f, // pushi 4f (79 - x)
- 0x38, 0xa5, 0x00, // pushi 00a5 (165 - y)
- 0x7c, // pushSelf
- 0
+// Fixes bug: #6180
+const uint16 qfg1vgaSignatureMoveToCrusher[] = {
+ SIG_MAGICDWORD,
+ 0x51, 0x1f, // class Motion
+ 0x36, // push
+ 0x39, 0x4f, // pushi 4f (79 - x)
+ 0x38, SIG_UINT16 + 0xa5, 0x00, // pushi 00a5 (165 - y)
+ 0x7c, // pushSelf
+ SIG_END
};
const uint16 qfg1vgaPatchMoveToCrusher[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x39, 0x55, // pushi 55 (85 - x)
+ PATCH_ADDTOOFFSET +3,
+ 0x39, 0x55, // pushi 55 (85 - 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 },
- { 216, "weapon master event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 814, "window text temp space", 1, PATCH_MAGICDWORD(0x3f, 0xba, 0x87, 0x00), 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
- { 814, "dialog header offset", 3, PATCH_MAGICDWORD(0x5b, 0x04, 0x80, 0x36), 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
- { 331, "moving to crusher", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
+// 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: #6248
+const uint16 qfg1vgaSignatureMoveToCastleGate[] = {
+ SIG_MAGICDWORD,
+ 0x51, 0x1f, // class MoveTo
+ 0x36, // push
+ 0x39, 0x6f, // pushi 6f (111 - x)
+ 0x3c, // dup (111 - y)
+ 0x7c, // pushSelf
+ SIG_END
+};
+
+const uint16 qfg1vgaPatchMoveToCastleGate[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x39, 0x72, // pushi 72 (114 - x)
+ PATCH_END
+};
+
+// Typo in the original Sierra scripts
+// Looking at a cheetaur resulted in a text about a Saurus Rex
+// The code treats both monster types the same.
+// Applies to at least: English floppy
+// Responsible method: smallMonster::doVerb
+// Fixes bug #6249
+const uint16 qfg1vgaSignatureCheetaurDescription[] = {
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16 + 0xb8, 0x01, // ldi 01b8
+ 0x1a, // eq?
+ 0x31, 0x16, // bnt 16
+ 0x38, SIG_UINT16 + 0x27, 0x01, // pushi 0127
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x03, // pushi 03
+ 0x78, // push1
+ 0x39, 0x12, // pushi 12 -> monster type Saurus Rex
+ SIG_END
+};
+
+const uint16 qfg1vgaPatchCheetaurDescription[] = {
+ PATCH_ADDTOOFFSET +14,
+ 0x39, 0x11, // pushi 11 -> monster type cheetaur
+ PATCH_END
+};
+
+// In the "funny" room (Yorick's room) in QfG1 VGA, pulling the chain and
+// then pressing the button on the right side of the room results in
+// a broken game. This also happens in SSCI.
+// Problem is that the Sierra programmers forgot to disable the door, that
+// gets opened by pulling the chain. So when ego falls down and then
+// rolls through the door, one method thinks that the player walks through
+// it and acts that way and the other method is still doing the roll animation.
+// Local 5 of that room is a timer, that closes the door (object door11).
+// Setting it to 1 during happyFace::changeState(0) stops door11::doit from
+// calling goTo6::init, so the whole issue is stopped from happening.
+// Applies to at least: English floppy
+// Responsible method: happyFace::changeState, door11::doit
+// Fixes bug #6181
+const uint16 qfg1vgaSignatureFunnyRoomFix[] = {
+ 0x65, 0x14, // aTop 14 (state)
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x30, SIG_UINT16 + 0x25, 0x00, // bnt 0025 [-> next state]
+ SIG_MAGICDWORD,
+ 0x35, 0x01, // ldi 01
+ 0xa3, 0x4e, // sal 4e
+ SIG_END
+};
+
+const uint16 qfg1vgaPatchFunnyRoomFix[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x2e, PATCH_UINT16 + 0x29, 0x00, // bt 0029 [-> next state] - saves 4 bytes
+ 0x35, 0x01, // ldi 01
+ 0xa3, 0x4e, // sal 4e
+ 0xa3, 0x05, // sal 05 (sets local 5 to 1)
+ 0xa3, 0x05, // and again to make absolutely sure (actually to waste 2 bytes)
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry qfg1vgaSignatures[] = {
+ { true, 215, "fight event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 216, "weapon master event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 814, "window text temp space", 1, 0, 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
+ { true, 814, "dialog header offset", 3, 0, 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
+ { true, 331, "moving to crusher", 1, 0, 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
+ { true, 41, "moving to castle gate", 1, 0, 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
+ { true, 210, "cheetaur description fixed", 1, 0, 0, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
+ { true, 96, "funny room script bug fixed", 1, 0, 0, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -998,58 +1656,56 @@ const SciScriptSignature qfg1vgaSignatures[] = {
// deleted entries. We don't allow the user to change the directory, thus the
// contents of the file list are constant, so we can avoid the constant file
// and text entry refreshes whenever a button is pressed, and prevent possible
-// crashes because of these constant quick object reallocations. Fixes bug
-// #3037996.
-const byte qfg2SignatureImportDialog[] = {
- 16,
- 0x63, 0x20, // pToa text
- 0x30, 0x0b, 0x00, // bnt [next state]
- 0x7a, // push2
- 0x39, 0x03, // pushi 03
- 0x36, // push
- 0x43, 0x72, 0x04, // callk Memory 4
- 0x35, 0x00, // ldi 00
- 0x65, 0x20, // aTop text
- 0
+// crashes because of these constant quick object reallocations.
+// Fixes bug: #5096
+const uint16 qfg2SignatureImportDialog[] = {
+ 0x63, SIG_MAGICDWORD, 0x20, // pToa text
+ 0x30, SIG_UINT16 + 0x0b, 0x00, // bnt [next state]
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ 0x36, // push
+ 0x43, 0x72, 0x04, // callk Memory 4
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x20, // aTop text
+ SIG_END
};
const uint16 qfg2PatchImportDialog[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x48, // ret
+ PATCH_ADDTOOFFSET +5,
+ 0x48, // ret
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature qfg2Signatures[] = {
- { 944, "import dialog continuous calls", 1, PATCH_MAGICDWORD(0x20, 0x30, 0x0b, 0x00), -1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
+// script, description, signature patch
+SciScriptPatcherEntry qfg2Signatures[] = {
+ { true, 944, "import dialog continuous calls", 1, 0, 0, qfg2SignatureImportDialog, qfg2PatchImportDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
// Patch for the import screen in QFG3, same as the one for QFG2 above
-const byte qfg3SignatureImportDialog[] = {
- 15,
- 0x63, 0x2a, // pToa text
- 0x31, 0x0b, // bnt [next state]
- 0x7a, // push2
- 0x39, 0x03, // pushi 03
- 0x36, // push
- 0x43, 0x72, 0x04, // callk Memory 4
- 0x35, 0x00, // ldi 00
- 0x65, 0x2a, // aTop text
- 0
+const uint16 qfg3SignatureImportDialog[] = {
+ 0x63, SIG_MAGICDWORD, 0x2a, // pToa text
+ 0x31, 0x0b, // bnt [next state]
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ 0x36, // push
+ 0x43, 0x72, 0x04, // callk Memory 4
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x2a, // aTop text
+ SIG_END
};
const uint16 qfg3PatchImportDialog[] = {
- PATCH_ADDTOOFFSET | +4,
- 0x48, // ret
+ PATCH_ADDTOOFFSET +4,
+ 0x48, // ret
PATCH_END
};
// ===========================================================================
-// Patch for the Woo dialog option in Uhura's conversation. Bug #3040722
+// Patch for the Woo dialog option in Uhura's conversation.
// Problem: The Woo dialog option (0xffb5) is negative, and therefore
// treated as an option opening a submenu. This leads to uhuraTell::doChild
// being called, which calls hero::solvePuzzle and then proceeds with
@@ -1061,38 +1717,40 @@ const uint16 qfg3PatchImportDialog[] = {
// hero::solvePuzzle (0xfffc) which does a ret afterwards without going to
// Teller::doChild. We jump to this call of hero::solvePuzzle to get that same
// behaviour.
-
-const byte qfg3SignatureWooDialog[] = {
- 30,
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0xb6, // ldi b6
- 0x1a, // eq?
- 0x2f, 0x05, // bt 05
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0x9b, // ldi 9b
- 0x1a, // eq?
- 0x31, 0x0c, // bnt 0c
- 0x38, 0x97, 0x02, // pushi 0297
- 0x7a, // push2
- 0x38, 0x0c, 0x01, // pushi 010c
- 0x7a, // push2
- 0x81, 0x00, // lag 00
- 0x4a, 0x08, // send 08
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0xb5, // ldi b5
- 0
+// Applies to at least: English, German, Italian, French, Spanish Floppy
+// Responsible method: unknown
+// Fixes bug: #5172
+const uint16 qfg3SignatureWooDialog[] = {
+ SIG_MAGICDWORD,
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0xb6, // ldi b6
+ 0x1a, // eq?
+ 0x2f, 0x05, // bt 05
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0x9b, // ldi 9b
+ 0x1a, // eq?
+ 0x31, 0x0c, // bnt 0c
+ 0x38, SIG_SELECTOR16 + SELECTOR_solvePuzzle, // pushi 0297
+ 0x7a, // push2
+ 0x38, SIG_UINT16 + 0x0c, 0x01, // pushi 010c
+ 0x7a, // push2
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x08, // send 08
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0xb5, // ldi b5
+ SIG_END
};
const uint16 qfg3PatchWooDialog[] = {
- PATCH_ADDTOOFFSET | +0x29,
- 0x33, 0x11, // jmp to 0x6a2, the call to hero::solvePuzzle for 0xFFFC
+ PATCH_ADDTOOFFSET +0x29,
+ 0x33, 0x11, // jmp to 0x6a2, the call to hero::solvePuzzle for 0xFFFC
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature qfg3Signatures[] = {
- { 944, "import dialog continuous calls", 1, PATCH_MAGICDWORD(0x2a, 0x31, 0x0b, 0x7a), -1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
- { 440, "dialog crash when asking about Woo", 1, PATCH_MAGICDWORD(0x67, 0x12, 0x35, 0xb5), -26, qfg3SignatureWooDialog, qfg3PatchWooDialog },
+// script, description, signature patch
+SciScriptPatcherEntry qfg3Signatures[] = {
+ { true, 944, "import dialog continuous calls", 1, 0, 0, qfg3SignatureImportDialog, qfg3PatchImportDialog },
+ { true, 440, "dialog crash when asking about Woo", 1, 0, 0, qfg3SignatureWooDialog, qfg3PatchWooDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1102,31 +1760,21 @@ const SciScriptSignature qfg3Signatures[] = {
// adds it to nest::x. The problem is that the script also checks if x exceeds
// we never reach that of course, so the pterodactyl-flight will go endlessly
// we could either calculate property count differently somehow fixing this
-// but I think just patching it out is cleaner (bug #3037938)
-const byte sq4FloppySignatureEndlessFlight[] = {
- 8,
- 0x39, 0x04, // pushi 04 (selector x)
- 0x78, // push1
- 0x67, 0x08, // pTos 08 (property x)
- 0x63, 0x44, // pToa 44 (invalid property)
- 0x02, // add
- 0
-};
-
-// Similar to the above, for the German version (bug #3110215)
-const byte sq4FloppySignatureEndlessFlightGerman[] = {
- 8,
- 0x39, 0x04, // pushi 04 (selector x)
- 0x78, // push1
- 0x67, 0x08, // pTos 08 (property x)
- 0x63, 0x4c, // pToa 4c (invalid property)
- 0x02, // add
- 0
+// but I think just patching it out is cleaner.
+// Fixes bug: #5093
+const uint16 sq4FloppySignatureEndlessFlight[] = {
+ 0x39, 0x04, // pushi 04 (selector x)
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x67, 0x08, // pTos 08 (property x)
+ 0x63, SIG_ADDTOOFFSET + 1, // pToa (invalid property) - 44h for English floppy, 4ch for German floppy
+ 0x02, // add
+ SIG_END
};
const uint16 sq4FloppyPatchEndlessFlight[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x35, 0x03, // ldi 03 (which would be the content of the property)
+ PATCH_ADDTOOFFSET +5,
+ 0x35, 0x03, // ldi 03 (which would be the content of the property)
PATCH_END
};
@@ -1136,40 +1784,40 @@ const uint16 sq4FloppyPatchEndlessFlight[] = {
// Patch 1: iconTextSwitch::show, called when the text options button is shown.
// This is patched to add the "Both" text resource (i.e. we end up with
// "Speech", "Text" and "Both")
-const byte sq4CdSignatureTextOptionsButton[] = {
- 11,
- 0x35, 0x01, // ldi 0x01
- 0xa1, 0x53, // sag 0x53
- 0x39, 0x03, // pushi 0x03
- 0x78, // push1
- 0x39, 0x09, // pushi 0x09
- 0x54, 0x06, // self 0x06
- 0
+const uint16 sq4CdSignatureTextOptionsButton[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x01, // ldi 0x01
+ 0xa1, 0x53, // sag 0x53
+ 0x39, 0x03, // pushi 0x03
+ 0x78, // push1
+ 0x39, 0x09, // pushi 0x09
+ 0x54, 0x06, // self 0x06
+ SIG_END
};
const uint16 sq4CdPatchTextOptionsButton[] = {
- PATCH_ADDTOOFFSET | +7,
- 0x39, 0x0b, // pushi 0x0b
+ PATCH_ADDTOOFFSET +7,
+ 0x39, 0x0b, // pushi 0x0b
PATCH_END
};
// Patch 2: Adjust a check in babbleIcon::init, which handles the babble icon
// (e.g. the two guys from Andromeda) shown when dying/quitting.
-// Fixes bug #3538418.
-const byte sq4CdSignatureBabbleIcon[] = {
- 7,
- 0x89, 0x5a, // lsg 5a
- 0x35, 0x02, // ldi 02
- 0x1a, // eq?
- 0x31, 0x26, // bnt 26 [02a7]
- 0
+// Fixes bug: #6068
+const uint16 sq4CdSignatureBabbleIcon[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg 5a
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x26, // bnt 26 [02a7]
+ SIG_END
};
const uint16 sq4CdPatchBabbleIcon[] = {
- 0x89, 0x5a, // lsg 5a
- 0x35, 0x01, // ldi 01
- 0x1a, // eq?
- 0x2f, 0x26, // bt 26 [02a7]
+ 0x89, 0x5a, // lsg 5a
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x2f, 0x26, // bt 26 [02a7]
PATCH_END
};
@@ -1177,111 +1825,198 @@ const uint16 sq4CdPatchBabbleIcon[] = {
// when the text options button is clicked: "Speech", "Text" and "Both".
// Refer to the patch above for additional details.
// iconTextSwitch::doit (called when the text options button is clicked)
-const byte sq4CdSignatureTextOptions[] = {
- 32,
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
- 0x3c, // dup
- 0x35, 0x01, // ldi 0x01
- 0x1a, // eq? (global 90 == 1)
- 0x31, 0x06, // bnt 0x06 (0x0691)
- 0x35, 0x02, // ldi 0x02
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x33, 0x0a, // jmp 0x0a (0x69b)
- 0x3c, // dup
- 0x35, 0x02, // ldi 0x02
- 0x1a, // eq? (global 90 == 2)
- 0x31, 0x04, // bnt 0x04 (0x069b)
- 0x35, 0x01, // ldi 0x01
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x3a, // toss
- 0x38, 0xd9, 0x00, // pushi 0x00d9
- 0x76, // push0
- 0x54, 0x04, // self 0x04
- 0x48, // ret
- 0
+const uint16 sq4CdSignatureTextOptions[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 0x01
+ 0x1a, // eq? (global 90 == 1)
+ 0x31, 0x06, // bnt 0x06 (0x0691)
+ 0x35, 0x02, // ldi 0x02
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x33, 0x0a, // jmp 0x0a (0x69b)
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 0x02
+ 0x1a, // eq? (global 90 == 2)
+ 0x31, 0x04, // bnt 0x04 (0x069b)
+ 0x35, 0x01, // ldi 0x01
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x3a, // toss
+ 0x38, SIG_SELECTOR16 + SELECTOR_show, // pushi 0x00d9
+ 0x76, // push0
+ 0x54, 0x04, // self 0x04
+ 0x48, // ret
+ SIG_END
};
const uint16 sq4CdPatchTextOptions[] = {
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
- 0x3c, // dup
- 0x35, 0x03, // ldi 0x03 (acc = 3)
- 0x1a, // eq? (global 90 == 3)
- 0x2f, 0x07, // bt 0x07
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack again)
- 0x35, 0x01, // ldi 0x01 (acc = 1)
- 0x02, // add: acc = global 90 (on stack) + 1 (previous acc value)
- 0x33, 0x02, // jmp 0x02
- 0x35, 0x01, // ldi 0x01 (reset acc to 1)
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x33, 0x03, // jmp 0x03 (jump over the wasted bytes below)
- 0x34, 0x00, 0x00, // ldi 0x0000 (waste 3 bytes)
- 0x3a, // toss
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
+ 0x3c, // dup
+ 0x35, 0x03, // ldi 0x03 (acc = 3)
+ 0x1a, // eq? (global 90 == 3)
+ 0x2f, 0x07, // bt 0x07
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack again)
+ 0x35, 0x01, // ldi 0x01 (acc = 1)
+ 0x02, // add: acc = global 90 (on stack) + 1 (previous acc value)
+ 0x33, 0x02, // jmp 0x02
+ 0x35, 0x01, // ldi 0x01 (reset acc to 1)
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x33, 0x03, // jmp 0x03 (jump over the wasted bytes below)
+ 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0x0000 (waste 3 bytes)
+ 0x3a, // toss
// (the rest of the code is the same)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature sq4Signatures[] = {
- { 298, "Floppy: endless flight", 1, PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x44), -3, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
- { 298, "Floppy (German): endless flight", 1, PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x4c), -3, sq4FloppySignatureEndlessFlightGerman, sq4FloppyPatchEndlessFlight },
- { 818, "CD: Speech and subtitles option", 1, PATCH_MAGICDWORD(0x89, 0x5a, 0x3c, 0x35), 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
- { 0, "CD: Babble icon speech and subtitles fix", 1, PATCH_MAGICDWORD(0x89, 0x5a, 0x35, 0x02), 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
- { 818, "CD: Speech and subtitles option button", 1, PATCH_MAGICDWORD(0x35, 0x01, 0xa1, 0x53), 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
+// script, description, signature patch
+SciScriptPatcherEntry sq4Signatures[] = {
+ { true, 298, "Floppy: endless flight", 1, 0, 0, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
+ { true, 818, "CD: Speech and subtitles option", 1, 0, 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
+ { true, 0, "CD: Babble icon speech and subtitles fix", 1, 0, 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
+ { true, 818, "CD: Speech and subtitles option button", 1, 0, 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
SCI_SIGNATUREENTRY_TERMINATOR
};
-const byte sq1vgaSignatureEgoShowsCard[] = {
- 25,
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to set timesShownID)
- 0x78, // push1
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to get timesShownID)
- 0x76, // push0
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x04, // send 0x04 (get timesShownID)
- 0x36, // push
- 0x35, 0x01, // ldi 1
- 0x02, // add
- 0x36, // push
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x06, // send 0x06 (set timesShownID)
- 0x36, // push (wrong, acc clobbered by class, above)
- 0x35, 0x03, // ldi 0x03
- 0x22, // lt?
- 0};
+// ===========================================================================
+// When you leave Ulence Flats, another timepod is supposed to appear.
+// On fast machines, that timepod appears fully immediately and then
+// starts to appear like it should be. That first appearance is caused
+// by the scripts setting an invalid cel number and the machine being
+// so fast that there is no time for another script to actually fix
+// the cel number. On slower machines, the cel number gets fixed
+// by the cycler and that's why only fast machines are affected.
+// The same issue happens in Sierra SCI.
+// We simply set the correct starting cel number to fix the bug.
+// Responsible method: robotIntoShip::changeState(9)
+const uint16 sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = {
+ 0x39,
+ SIG_MAGICDWORD, SIG_SELECTOR8 + SELECTOR_cel, // pushi "cel"
+ 0x78, // push1
+ 0x39, 0x0a, // pushi 0x0a (set ship::cel to 10)
+ 0x38, SIG_UINT16 + 0xa0, 0x00, // pushi 0x00a0 (ship::setLoop)
+ SIG_END
+};
+
+const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x39, 0x09, // pushi 0x09 (set ship::cel to 9)
+ PATCH_END
+};
+
+const uint16 sq1vgaSignatureEgoShowsCard[] = {
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID"
+ 0x78, // push1
+ 0x38, SIG_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID"
+ 0x76, // push0
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x04, // send 0x04 (get timesShownID)
+ 0x36, // push
+ 0x35, 0x01, // ldi 1
+ 0x02, // add
+ 0x36, // push
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x06, // send 0x06 (set timesShownID)
+ 0x36, // push (wrong, acc clobbered by class, above)
+ 0x35, 0x03, // ldi 0x03
+ 0x22, // lt?
+ SIG_END
+};
// Note that this script patch is merely a reordering of the
// instructions in the original script.
const uint16 sq1vgaPatchEgoShowsCard[] = {
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to get timesShownID)
- 0x76, // push0
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x04, // send 0x04 (get timesShownID)
- 0x36, // push
- 0x35, 0x01, // ldi 1
- 0x02, // add
- 0x36, // push (this push corresponds to the wrong one above)
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to set timesShownID)
- 0x78, // push1
- 0x36, // push
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x06, // send 0x06 (set timesShownID)
- 0x35, 0x03, // ldi 0x03
- 0x22, // lt?
- PATCH_END};
-
-
-// script, description, magic DWORD, adjust
-const SciScriptSignature sq1vgaSignatures[] = {
- { 58, "Sarien armory droid zapping ego first time", 1, PATCH_MAGICDWORD( 0x72, 0x88, 0x15, 0x36 ), -70,
- sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
+ 0x38, PATCH_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID"
+ 0x76, // push0
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x04, // send 0x04 (get timesShownID)
+ 0x36, // push
+ 0x35, 0x01, // ldi 1
+ 0x02, // add
+ 0x36, // push (this push corresponds to the wrong one above)
+ 0x38, PATCH_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID"
+ 0x78, // push1
+ 0x36, // push
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x06, // send 0x06 (set timesShownID)
+ 0x35, 0x03, // ldi 0x03
+ 0x22, // lt?
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry sq1vgaSignatures[] = {
+ { true, 45, "Ulence Flats: timepod graphic glitch", 1, 0, 0, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
+ { true, 58, "Sarien armory droid zapping ego first time", 1, 0, 0, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
SCI_SIGNATUREENTRY_TERMINATOR};
+// ===========================================================================
+// The toolbox in sq5 is buggy. When you click on the upper part of the "put
+// in inventory"-button (some items only - for example the hole puncher - at the
+// upper left), points will get awarded correctly and the item will get put into
+// the player's inventory, but you will then get a "not here" message and the
+// item will also remain to be the current mouse cursor.
+// The bug report also says that items may get lost. I wasn't able to reproduce
+// that part.
+// This is caused by the mouse-click event getting reprocessed (which wouldn't
+// be a problem by itself) and during this reprocessing coordinates are not
+// processed the same as during the first click (script 226 includes a local
+// subroutine, which checks coordinates in a hardcoded way w/o port-adjustment).
+// Because of this, the hotspot for the button is lower than it should be, which
+// then results in the game thinking that the user didn't click on the button
+// and also results in the previously mentioned message.
+// This happened in Sierra SCI as well (of course).
+// We fix it by combining state 0 + 1 of takeTool::changeState and so stopping
+// the event to get reprocessed. This was the only way possible, because everything
+// else is done in SCI system scripts and I don't want to touch those.
+// Applies to at least: English/German/French PC floppy
+// Responsible method: takeTool::changeState
+// Fixes bug: #6457
+const uint16 sq5SignatureToolboxFix[] = {
+ 0x31, 0x13, // bnt [check for state 1]
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16 + 0xaa, 0x00, // pushi 00aa
+ 0x39, 0x05, // pushi 05
+ 0x39, 0x16, // pushi 16
+ 0x76, // push0
+ 0x39, 0x03, // pushi 03
+ 0x76, // push0
+ 0x7c, // pushSelf
+ 0x81, 0x5b, // lag 5b
+ 0x4a, 0x0e, // send 0e
+ 0x32, SIG_UINT16 + 0x88, 0x00, // jmp [end-of-method]
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x28, // bnt [check for state 2]
+ SIG_END
+};
+
+const uint16 sq5PatchToolboxFix[] = {
+ 0x31, 0x41, // bnt [check for state 2]
+ PATCH_ADDTOOFFSET +16, // skip to jmp offset
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x14, // aTop [state]
+ 0x36, 0x00, 0x00, // ldi 0000 (waste 3 bytes)
+ 0x35, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_END
+};
+
+// script, description, signature patch
+SciScriptPatcherEntry sq5Signatures[] = {
+ { true, 226, "toolbox fix", 1, 0, 0, sq5SignatureToolboxFix, sq5PatchToolboxFix },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+
// will actually patch previously found signature area
-void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) {
+void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) {
+ const uint16 *patchData = patchEntry->patchData;
byte orgData[PATCH_VALUELIMIT];
int32 offset = signatureOffset;
- uint16 patchWord = *patch;
+ uint16 patchWord = *patchEntry->patchData;
+ uint16 patchSelector = 0;
// Copy over original bytes from script
uint32 orgDataSize = scriptSize - offset;
@@ -1290,74 +2025,179 @@ void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scri
memcpy(&orgData, &scriptData[offset], orgDataSize);
while (patchWord != PATCH_END) {
+ uint16 patchCommand = patchWord & PATCH_COMMANDMASK;
uint16 patchValue = patchWord & PATCH_VALUEMASK;
- switch (patchWord & PATCH_COMMANDMASK) {
- case PATCH_ADDTOOFFSET:
+ switch (patchCommand) {
+ case PATCH_ADDTOOFFSET: {
// add value to offset
- offset += patchValue & ~PATCH_ADDTOOFFSET;
+ offset += patchValue;
break;
- case PATCH_GETORIGINALBYTE:
+ }
+ case PATCH_GETORIGINALBYTE: {
// get original byte from script
if (patchValue >= orgDataSize)
- error("patching: can not get requested original byte from script");
+ error("Script-Patcher: can not get requested original byte from script");
scriptData[offset] = orgData[patchValue];
offset++;
break;
- case PATCH_ADJUSTWORD: {
- // Adjust word right before current position
- byte *adjustPtr = &scriptData[offset - 2];
- uint16 adjustWord = READ_LE_UINT16(adjustPtr);
- adjustWord += patchValue;
- WRITE_LE_UINT16(adjustPtr, adjustWord);
+ }
+ case PATCH_GETORIGINALBYTEADJUST: {
+ // get original byte from script and adjust it
+ if (patchValue >= orgDataSize)
+ error("Script-Patcher: can not get requested original byte from script");
+ byte orgByte = orgData[patchValue];
+ int16 adjustValue;
+ patchData++; adjustValue = (int16)(*patchData);
+ scriptData[offset] = orgByte + adjustValue;
+ offset++;
+ break;
+ }
+ case PATCH_UINT16:
+ case PATCH_SELECTOR16: {
+ byte byte1;
+ byte byte2;
+
+ switch (patchCommand) {
+ case PATCH_UINT16: {
+ byte1 = patchValue & PATCH_BYTEMASK;
+ patchData++; patchWord = *patchData;
+ if (patchWord & PATCH_COMMANDMASK)
+ error("Script-Patcher: Patch inconsistent");
+ byte2 = patchWord & PATCH_BYTEMASK;
+ break;
+ }
+ case PATCH_SELECTOR16: {
+ patchSelector = selectorTable[patchValue].id;
+ byte1 = patchSelector & 0xFF;
+ byte2 = patchSelector >> 8;
+ break;
+ }
+ default:
+ byte1 = 0; byte2 = 0;
+ }
+ if (!isMacSci11) {
+ scriptData[offset++] = byte1;
+ scriptData[offset++] = byte2;
+ } else {
+ // SCI1.1+ on macintosh had uint16s in script in BE-order
+ scriptData[offset++] = byte2;
+ scriptData[offset++] = byte1;
+ }
break;
}
- case PATCH_ADJUSTWORD_NEG: {
- // Adjust word right before current position (negative way)
- byte *adjustPtr = &scriptData[offset - 2];
- uint16 adjustWord = READ_LE_UINT16(adjustPtr);
- adjustWord -= patchValue;
- WRITE_LE_UINT16(adjustPtr, adjustWord);
+ case PATCH_SELECTOR8: {
+ patchSelector = selectorTable[patchValue].id;
+ if (patchSelector & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector");
+ scriptData[offset] = patchSelector & 0xFF;
+ offset++;
break;
}
- default:
- scriptData[offset] = patchValue & 0xFF;
+ case PATCH_BYTE:
+ scriptData[offset] = patchValue & PATCH_BYTEMASK;
offset++;
}
- patch++;
- patchWord = *patch;
+ patchData++;
+ patchWord = *patchData;
}
}
// will return -1 if no match was found, otherwise an offset to the start of the signature match
-int32 Script::findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize) {
+int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) {
if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay
return -1;
- const uint32 magicDWord = signature->magicDWord; // is platform-specific BE/LE form, so that the later match will work
+ const uint32 magicDWord = patchEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work
const uint32 searchLimit = scriptSize - 3;
uint32 DWordOffset = 0;
// first search for the magic DWORD
while (DWordOffset < searchLimit) {
if (magicDWord == READ_UINT32(scriptData + DWordOffset)) {
// magic DWORD found, check if actual signature matches
- uint32 offset = DWordOffset + signature->magicOffset;
+ uint32 offset = DWordOffset + patchEntry->magicOffset;
uint32 byteOffset = offset;
- const byte *signatureData = signature->data;
- byte matchAdjust = 1;
- while (matchAdjust) {
- byte matchBytesCount = *signatureData++;
- if ((byteOffset + matchBytesCount) > scriptSize) // Out-Of-Bounds?
+ const uint16 *signatureData = patchEntry->signatureData;
+ uint16 sigSelector = 0;
+
+ uint16 sigWord = *signatureData;
+ while (sigWord != SIG_END) {
+ uint16 sigCommand = sigWord & SIG_COMMANDMASK;
+ uint16 sigValue = sigWord & SIG_VALUEMASK;
+ switch (sigCommand) {
+ case SIG_ADDTOOFFSET: {
+ // add value to offset
+ byteOffset += sigValue;
+ break;
+ }
+ case SIG_UINT16:
+ case SIG_SELECTOR16: {
+ if ((byteOffset + 1) < scriptSize) {
+ byte byte1;
+ byte byte2;
+
+ switch (sigCommand) {
+ case SIG_UINT16: {
+ byte1 = sigValue & SIG_BYTEMASK;
+ signatureData++; sigWord = *signatureData;
+ if (sigWord & SIG_COMMANDMASK)
+ error("Script-Patcher: signature inconsistent\nFaulty patch: '%s'", patchEntry->description);
+ byte2 = sigWord & SIG_BYTEMASK;
+ break;
+ }
+ case SIG_SELECTOR16: {
+ sigSelector = selectorTable[sigValue].id;
+ byte1 = sigSelector & 0xFF;
+ byte2 = sigSelector >> 8;
+ break;
+ }
+ default:
+ byte1 = 0; byte2 = 0;
+ }
+ if (!isMacSci11) {
+ if ((scriptData[byteOffset] != byte1) || (scriptData[byteOffset + 1] != byte2))
+ sigWord = SIG_MISMATCH;
+ } else {
+ // SCI1.1+ on macintosh had uint16s in script in BE-order
+ if ((scriptData[byteOffset] != byte2) || (scriptData[byteOffset + 1] != byte1))
+ sigWord = SIG_MISMATCH;
+ }
+ byteOffset += 2;
+ } else {
+ sigWord = SIG_MISMATCH;
+ }
break;
- if (memcmp(signatureData, &scriptData[byteOffset], matchBytesCount)) // Byte-Mismatch?
+ }
+ case SIG_SELECTOR8: {
+ if (byteOffset < scriptSize) {
+ sigSelector = selectorTable[sigValue].id;
+ if (sigSelector & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", patchEntry->description);
+ if (scriptData[byteOffset] != (sigSelector & 0xFF))
+ sigWord = SIG_MISMATCH;
+ byteOffset++;
+ } else {
+ sigWord = SIG_MISMATCH; // out of bounds
+ }
+ break;
+ }
+ case SIG_BYTE:
+ if (byteOffset < scriptSize) {
+ if (scriptData[byteOffset] != sigWord)
+ sigWord = SIG_MISMATCH;
+ byteOffset++;
+ } else {
+ sigWord = SIG_MISMATCH; // out of bounds
+ }
+ }
+
+ if (sigWord == SIG_MISMATCH)
break;
- // those bytes matched, adjust offsets accordingly
- signatureData += matchBytesCount;
- byteOffset += matchBytesCount;
- // get offset...
- matchAdjust = *signatureData++;
- byteOffset += matchAdjust;
+
+ signatureData++;
+ sigWord = *signatureData;
}
- if (!matchAdjust) // all matches worked?
+
+ if (sigWord == SIG_END) // signature fully matched?
return offset;
}
DWordOffset++;
@@ -1366,9 +2206,164 @@ int32 Script::findSignature(const SciScriptSignature *signature, const byte *scr
return -1;
}
-void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
- const SciScriptSignature *signatureTable = NULL;
- switch (g_sci->getGameId()) {
+// This method calculates the magic DWORD for each entry in the signature table
+// and it also initializes the selector table for selectors used in the signatures/patches of the current game
+void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11) {
+ SciScriptPatcherEntry *curEntry = patchTable;
+ SciScriptPatcherSelector *curSelector = NULL;
+ int step;
+ int magicOffset;
+ byte magicDWord[4];
+ int magicDWordLeft = 0;
+ const uint16 *curData;
+ uint16 curWord;
+ uint16 curCommand;
+ uint32 curValue;
+ byte byte1;
+ byte byte2;
+
+ while (curEntry->signatureData) {
+ // process signature
+ memset(magicDWord, 0, sizeof(magicDWord));
+
+ for (step = 0; step < 2; step++) {
+ switch (step) {
+ case 0: curData = curEntry->signatureData; break;
+ case 1: curData = curEntry->patchData; break;
+ }
+
+ curWord = *curData;
+ magicOffset = 0;
+ while (curWord != SIG_END) {
+ curCommand = curWord & SIG_COMMANDMASK;
+ curValue = curWord & SIG_VALUEMASK;
+ switch (curCommand) {
+ case SIG_MAGICDWORD: {
+ if (step == 0) {
+ if ((curEntry->magicDWord) || (magicDWordLeft))
+ error("Script-Patcher: Magic-DWORD specified multiple times in signature\nFaulty patch: '%s'", curEntry->description);
+ magicDWordLeft = 4;
+ curEntry->magicOffset = magicOffset;
+ }
+ break;
+ }
+ case SIG_ADDTOOFFSET: {
+ magicOffset -= curValue;
+ if (magicDWordLeft)
+ error("Script-Patcher: Magic-DWORD contains AddToOffset command\nFaulty patch: '%s'", curEntry->description);
+ break;
+ }
+ case SIG_UINT16:
+ case SIG_SELECTOR16: {
+ // UINT16 or 1
+ switch (curCommand) {
+ case SIG_UINT16: {
+ curData++; curWord = *curData;
+ if (curWord & SIG_COMMANDMASK)
+ error("Script-Patcher: signature entry inconsistent\nFaulty patch: '%s'", curEntry->description);
+ if (!isMacSci11) {
+ byte1 = curValue;
+ byte2 = curWord & SIG_BYTEMASK;
+ } else {
+ byte1 = curWord & SIG_BYTEMASK;
+ byte2 = curValue;
+ }
+ break;
+ }
+ case SIG_SELECTOR16: {
+ curSelector = &selectorTable[curValue];
+ if (curSelector->id == -1)
+ curSelector->id = g_sci->getKernel()->findSelector(curSelector->name);
+ if (!isMacSci11) {
+ byte1 = curSelector->id & 0x00FF;
+ byte2 = curSelector->id >> 8;
+ } else {
+ byte1 = curSelector->id >> 8;
+ byte2 = curSelector->id & 0x00FF;
+ }
+ break;
+ }
+ }
+ magicOffset -= 2;
+ if (magicDWordLeft) {
+ // Remember current word for Magic DWORD
+ magicDWord[4 - magicDWordLeft] = byte1;
+ magicDWordLeft--;
+ if (magicDWordLeft) {
+ magicDWord[4 - magicDWordLeft] = byte2;
+ magicDWordLeft--;
+ }
+ if (!magicDWordLeft) {
+ curEntry->magicDWord = READ_LE_UINT32(magicDWord);
+ }
+ }
+ break;
+ }
+ case SIG_BYTE:
+ case SIG_SELECTOR8: {
+ if (curCommand == SIG_SELECTOR8) {
+ curSelector = &selectorTable[curValue];
+ if (curSelector->id == -1) {
+ curSelector->id = g_sci->getKernel()->findSelector(curSelector->name);
+ if (curSelector->id != -1) {
+ if (curSelector->id & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", curEntry->description);
+ }
+ }
+ curValue = curSelector->id;
+ }
+ magicOffset--;
+ if (magicDWordLeft) {
+ // Remember current byte for Magic DWORD
+ magicDWord[4 - magicDWordLeft] = (byte)curValue;
+ magicDWordLeft--;
+ if (!magicDWordLeft) {
+ curEntry->magicDWord = READ_LE_UINT32(magicDWord);
+ }
+ }
+ }
+ }
+ curData++;
+ curWord = *curData;
+ }
+ }
+ if (magicDWordLeft)
+ error("Script-Patcher: Magic-DWORD beyond End-Of-Signature\nFaulty patch: '%s'", curEntry->description);
+ if (!curEntry->magicDWord)
+ error("Script-Patcher: Magic-DWORD not specified in signature\nFaulty patch: '%s'", curEntry->description);
+
+ curEntry++;
+ }
+}
+
+// This method enables certain patches
+// It's used for patches, which are not meant to get applied all the time
+void Script::patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription) {
+ SciScriptPatcherEntry *curEntry = patchTable;
+ int searchDescriptionLen = strlen( searchDescription );
+ int matchCount = 0;
+
+ while (curEntry->signatureData) {
+ if (strncmp(curEntry->description, searchDescription, searchDescriptionLen) == 0) {
+ // match found, enable patch
+ curEntry->active = true;
+ matchCount++;
+ }
+ curEntry++;
+ }
+
+ if (!matchCount)
+ error("Script-Patcher: no patch found to enable");
+}
+
+void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
+ SciScriptPatcherEntry *signatureTable = NULL;
+ const Sci::SciGameId gameId = g_sci->getGameId();
+
+ switch (gameId) {
+ case GID_CAMELOT:
+ signatureTable = camelotSignatures;
+ break;
case GID_ECOQUEST:
signatureTable = ecoquest1Signatures;
break;
@@ -1385,11 +2380,7 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
signatureTable = gk1Signatures;
break;
case GID_KQ5:
- // See the explanation in the kq5SignatureWinGMSignals comment
- if (g_sci->_features->useAltWinGMSound())
- signatureTable = kq5WinGMSignatures;
- else
- signatureTable = kq5Signatures;
+ signatureTable = kq5Signatures;
break;
case GID_KQ6:
signatureTable = kq6Signatures;
@@ -1400,12 +2391,21 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
case GID_LONGBOW:
signatureTable = longbowSignatures;
break;
+ case GID_LSL2:
+ signatureTable = larry2Signatures;
+ break;
+ case GID_LSL5:
+ signatureTable = larry5Signatures;
+ break;
case GID_LSL6:
signatureTable = larry6Signatures;
break;
case GID_MOTHERGOOSE256:
signatureTable = mothergoose256Signatures;
break;
+ case GID_PQ1:
+ signatureTable = pq1vgaSignatures;
+ break;
case GID_QFG1VGA:
signatureTable = qfg1vgaSignatures;
break;
@@ -1421,21 +2421,53 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
case GID_SQ4:
signatureTable = sq4Signatures;
break;
+ case GID_SQ5:
+ signatureTable = sq5Signatures;
+ break;
default:
break;
}
if (signatureTable) {
- while (signatureTable->data) {
- if (scriptNr == signatureTable->scriptNr) {
+ bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
+
+ if (!signatureTable->magicDWord) {
+ // Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary)
+ if (!g_sci->getKernel()->selectorNamesAvailable())
+ return;
+
+ // signature table needs to get initialized (Magic DWORD set, selector table set)
+ patcherInitSignature(signatureTable, isMacSci11);
+
+ // Do additional game-specific initialization
+ switch (gameId) {
+ case GID_KQ5:
+ if (g_sci->_features->useAltWinGMSound()) {
+ // See the explanation in the kq5SignatureWinGMSignals comment
+ patcherEnablePatch(signatureTable, "Win: GM Music signal checks");
+ }
+ break;
+ case GID_LAURABOW2:
+ if (g_sci->speechAndSubtitlesEnabled()) {
+ // Enables Audio + subtitles patches for Laura Bow 2, when "Text and Speech: Both" is selected
+ patcherEnablePatch(signatureTable, "CD: audio + text support");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ while (signatureTable->signatureData) {
+ if ( (scriptNr == signatureTable->scriptNr) && (signatureTable->active) ) {
int32 foundOffset = 0;
int16 applyCount = signatureTable->applyCount;
do {
- foundOffset = findSignature(signatureTable, scriptData, scriptSize);
+ foundOffset = patcherFindSignature(signatureTable, scriptData, scriptSize, isMacSci11);
if (foundOffset != -1) {
// found, so apply the patch
- debugC(kDebugLevelScripts, "matched and patched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
- applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
+ debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
+ patcherApplyPatch(signatureTable, scriptData, scriptSize, foundOffset, isMacSci11);
}
applyCount--;
} while ((foundOffset != -1) && (applyCount));
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 97e33f256b..a059bee74e 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -262,8 +262,14 @@ const char *SegManager::getObjectName(reg_t pos) {
const char *name = 0;
if (nameReg.getSegment())
name = derefString(nameReg);
- if (!name)
- return "<invalid name>";
+ if (!name) {
+ // Crazy Nick Laura Bow is missing some object names needed for the static
+ // selector vocabulary
+ if (g_sci->getGameId() == GID_CNICK_LAURABOW && pos == make_reg(1, 0x2267))
+ return "Character";
+ else
+ return "<invalid name>";
+ }
return name;
}
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 074d3f6b0a..0667b75651 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -224,7 +224,7 @@ public:
* Allocate a fresh chunk of the hunk
* @param[in] size Number of bytes to allocate for the hunk entry
* @param[in] hunk_type A descriptive string for the hunk entry, for
- * debugging purposes
+ * debugging purposes
* @return The offset of the freshly allocated hunk entry
*/
reg_t allocateHunkEntry(const char *hunk_type, int size);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index ef8f165084..d7c2fdc0eb 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -200,11 +200,18 @@ static void write_var(EngineState *s, int type, int index, reg_t value) {
s->variables[type][index] = value;
- // If the game is trying to change its speech/subtitle settings, apply the ScummVM audio
- // options first, if they haven't been applied yet
- if (type == VAR_GLOBAL && index == 90 && !g_sci->getEngineState()->_syncedAudioOptions) {
- g_sci->syncIngameAudioOptions();
- g_sci->getEngineState()->_syncedAudioOptions = true;
+ if (type == VAR_GLOBAL && index == 90) {
+ // The game is trying to change its speech/subtitle settings
+ if (!g_sci->getEngineState()->_syncedAudioOptions || s->variables[VAR_GLOBAL][4] == TRUE_REG) {
+ // ScummVM audio options haven't been applied yet, so apply them.
+ // We also force the ScummVM audio options when loading a game from
+ // the launcher.
+ g_sci->syncIngameAudioOptions();
+ g_sci->getEngineState()->_syncedAudioOptions = true;
+ } else {
+ // Update ScummVM's audio options
+ g_sci->updateScummVMAudioOptions();
+ }
}
}
}
diff --git a/engines/sci/engine/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 6af6326042..6fdff1ce91 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,9 +51,16 @@ 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
+ { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname520>", -1, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled - bug #3615121 (same as the theDoubleCube::make workaround for Hoyle 3)
+ { GID_CNICK_KQ, 300, 303, 0, "theDoubleCube", "<noname519>", -1, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled (same as the theDoubleCube::accept workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // Yatch, like in hoyle 3 - temps 504 and 505 - bug #3615119
+ { GID_CNICK_LAURABOW, -1, 700, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu - bug #3615118 (same as the gcWindow workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW,100, 100, 0, NULL, "<noname144>", -1, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #3615129 (same as the dominoHand2 workaround for Hoyle 3)
+ { GID_CNICK_LAURABOW,100, 110, 0, NULL, "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #3615130
{ GID_CNICK_LONGBOW, 0, 0, 0, "RH Budget", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // when starting the game
{ GID_ECOQUEST, -1, -1, 0, NULL, "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // almost clicking anywhere triggers this in almost all rooms
{ GID_FANMADE, 516, 979, 0, "", "export 0", -1, 20, { WORKAROUND_FAKE, 0 } }, // Happens in Grotesteing after the logos
@@ -71,12 +79,17 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_HOYLE3, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // when starting checkers or dominoes, first time a character says something - temps 504 and 505
{ GID_HOYLE3, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering control menu
{ GID_HOYLE3, 100, 100, 0, "dominoHand2", "cue", -1, 1, { WORKAROUND_FAKE, 0 } }, // while playing domino - bug #3036918
+ { GID_HOYLE3, 100, 110, 0, "OKButton", "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when changing the "Dominoes per hand" setting - bug #3615130
+ { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "make", -1, 5, { WORKAROUND_FAKE, 0 } }, // while playing backgammon with doubling enabled
+ { GID_HOYLE3, 300, 303, 0, "theDoubleCube", "accept", -1, 9, { WORKAROUND_FAKE, 0 } }, // when accepting a double, while playing backgammon with doubling enabled
{ GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #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
@@ -97,6 +110,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle
{ GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc)
{ GID_KQ6, -1, 907, 0, "tomato", "doVerb", -1, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #3059544
+ { GID_KQ6, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
{ GID_KQ7, -1, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
{ GID_LAURABOW, 37, 0, 0, "CB1", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs (bug #3037694)
{ GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985)
@@ -104,6 +118,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #3035068, #3036274
{ GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
{ GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291
+ { GID_LAURABOW2, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
{ GID_LONGBOW, -1, 0, 0, "Longbow", "restart", -1, 0, { WORKAROUND_FAKE, 0 } }, // When canceling a restart game - bug #3046200
{ GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room
{ GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #3036601
@@ -167,6 +182,9 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens)
{ GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD: called when rummaging in Software Excess bargain bin
{ GID_SQ4, -1, 928, -1, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // CD: happens in the options dialog and in-game when speech and subtitles are used simultaneously
+ { GID_SQ4, -1, 708, -1, "exitBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "close" button in the sq4 hintbook - bug #6447
+ { GID_SQ4, -1, 708, -1, "prevBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "previous" button in the sq4 hintbook - bug #6447
+ { GID_SQ4, -1, 708, -1, "nextBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "next" button in the sq4 hintbook - bug #6447
{ GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #3038563
{ GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100)
{ GID_SQ6, -1, 64950, -1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu, when entering the Orion's Belt bar (room 300), and perhaps other places
@@ -208,6 +226,7 @@ const SciWorkaroundEntry kDeviceInfo_workarounds[] = {
{ GID_FANMADE, -1, 994, 1, "Game", "save", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
{ GID_FANMADE, -1, 994, 1, "Game", "save", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
{ GID_FANMADE, -1, 994, 1, "Game", "save", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back)
+ { GID_FANMADE, -1, 994, 0, "Black", "save", 0xa, 0, { WORKAROUND_IGNORE, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Black Cauldron Remake)
{ GID_FANMADE, -1, 994, 1, "Game", "save", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them)
{ GID_FANMADE, -1, 994, 1, "Game", "restore", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
{ GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
@@ -249,6 +268,7 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = {
{ GID_KQ6, 105, 989, 0, "globalSound", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // floppy: during intro, parameter 4 is an object
{ GID_KQ6, 460, 989, 0, "globalSound2", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // after pulling the black widow's web on the isle of wonder, parameter 4 is an object - bug #3034567
{ GID_QFG4, -1, 64989, 0, "longSong", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // CD version: many places, parameter 4 is an object (longSong)
+ { GID_SQ5, 800, 989, 0, "sq5Music1", "fade", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when cutting the wrong part of Goliath with the laser - bug #3614145
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -359,6 +379,13 @@ const SciWorkaroundEntry kNewWindow_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+const SciWorkaroundEntry kReadNumber_workarounds[] = {
+ { GID_CNICK_LAURABOW,100, 101, 0, "dominoes.opt", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #3615120
+ { GID_HOYLE3, 100, 101, 0, "dominoes.opt", "doit", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // When dominoes.opt is present, the game scripts call kReadNumber with an extra integer parameter - bug #3615120
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, call,index, workaround
const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[] = {
{ GID_QFG4, 100, 100, 0, "doMovie", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // after the Sierra logo, no flags are passed, thus the call is meaningless - bug #3034506
SCI_WORKAROUNDENTRY_TERMINATOR
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 59054ae552..d5e91b70ec 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -88,6 +88,7 @@ extern const SciWorkaroundEntry kIsObject_workarounds[];
extern const SciWorkaroundEntry kMemory_workarounds[];
extern const SciWorkaroundEntry kMoveCursor_workarounds[];
extern const SciWorkaroundEntry kNewWindow_workarounds[];
+extern const SciWorkaroundEntry kReadNumber_workarounds[];
extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[];
extern const SciWorkaroundEntry kSetCursor_workarounds[];
extern const SciWorkaroundEntry kSetPort_workarounds[];
diff --git a/engines/sci/graphics/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..8ad4f535f9 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
@@ -656,6 +658,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
case 35:
case 381:
case 376:
+ //case 390: // in the blacklisted NRS patch 1.2 (bug #3615060)
return;
default:
break;
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index 527e2ae973..6d9dc03195 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -116,7 +116,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
setPort(_wmgrPort);
// SCI0 games till kq4 (.502 - not including) did not adjust against _wmgrPort in kNewWindow
// We leave _wmgrPort top at 0, so the adjustment wont get done
- if (!g_sci->_features->usesOldGfxFunctions()) {
+ if (!_usesOldGfxFunctions) {
setOrigin(0, offTop);
_wmgrPort->rect.bottom = _screen->getHeight() - offTop;
} else {
@@ -131,7 +131,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te
_picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
// For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead
// Because of the menu/status bar
- if (g_sci->_features->usesOldGfxFunctions())
+ if (_usesOldGfxFunctions)
_picWind->top = offTop;
kernelInitPriorityBands();
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 74503c0c77..0df163dd7b 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();
}
@@ -286,11 +286,15 @@ void GfxScreen::putPixelOnDisplay(int x, int y, byte color) {
* with flood fill, due to small difference in the Bresenham logic.
*/
void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) {
- int16 left = startPoint.x;
- int16 top = startPoint.y;
- int16 right = endPoint.x;
- int16 bottom = endPoint.y;
-
+ int16 maxWidth = _width - 1;
+ int16 maxHeight = _height - 1;
+ // we need to clip values here, lsl3 room 620 background picture draws a line from 0, 199 t 320, 199
+ // otherwise we would get heap corruption.
+ int16 left = CLIP<int16>(startPoint.x, 0, maxWidth);
+ int16 top = CLIP<int16>(startPoint.y, 0, maxHeight);
+ int16 right = CLIP<int16>(endPoint.x, 0, maxWidth);
+ int16 bottom = CLIP<int16>(endPoint.y, 0, maxHeight);
+
//set_drawing_flag
byte drawMask = getDrawingMask(color, priority, control);
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 4baf39c67f..6fa51754a4 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -498,7 +498,7 @@ protected:
void readWaveAudioPatches();
void processWavePatch(ResourceId resourceId, Common::String name);
- /**
+ /**
* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2).
* Old SCI versions used two word header for script blocks (first word equal
* to 0x82, meaning of the second one unknown). New SCI versions used one
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index c1aadc3622..065565d8de 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -112,6 +112,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelDclInflate, "DCL", "DCL inflate debugging");
DebugMan.addDebugChannel(kDebugLevelVM, "VM", "VM debugging");
DebugMan.addDebugChannel(kDebugLevelScripts, "Scripts", "Notifies when scripts are unloaded");
+ DebugMan.addDebugChannel(kDebugLevelScriptPatcher, "ScriptPatcher", "Notifies when scripts are patched");
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
@@ -224,6 +225,7 @@ Common::Error SciEngine::run() {
_gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
_kernel = new Kernel(_resMan, segMan);
+ _kernel->init();
_features = new GameFeatures(segMan, _kernel);
// Only SCI0, SCI01 and SCI1 EGA games used a parser
@@ -881,8 +883,18 @@ void SciEngine::syncSoundSettings() {
}
}
+// used by Script Patcher. Used to find out, if Laura Bow 2 needs patching for Speech+Subtitles - or not
+bool SciEngine::speechAndSubtitlesEnabled() {
+ bool subtitlesOn = ConfMan.getBool("subtitles");
+ bool speechOn = !ConfMan.getBool("speech_mute");
+
+ if (subtitlesOn && speechOn)
+ return true;
+ return false;
+}
+
void SciEngine::syncIngameAudioOptions() {
- // Now, sync the in-game speech/subtitles settings for SCI1.1 CD games
+ // Sync the in-game speech/subtitles settings for SCI1.1 CD games
if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
bool subtitlesOn = ConfMan.getBool("subtitles");
bool speechOn = !ConfMan.getBool("speech_mute");
@@ -893,16 +905,19 @@ void SciEngine::syncIngameAudioOptions() {
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
} else if (subtitlesOn && speechOn) {
// Is it a game that supports simultaneous speech and subtitles?
- if (getGameId() == GID_SQ4
- || getGameId() == GID_FREDDYPHARKAS
- || getGameId() == GID_ECOQUEST
- || getGameId() == GID_LSL6
+ switch (_gameId) {
+ case GID_SQ4:
+ case GID_FREDDYPHARKAS:
+ case GID_ECOQUEST:
+ case GID_LSL6:
// TODO: The following need script patches for simultaneous speech and subtitles
- //|| getGameId() == GID_KQ6
- //|| getGameId() == GID_LAURABOW2
- ) {
+ // GID_KQ6
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 3); // speech + subtitles
- } else {
+ break;
+ case GID_LAURABOW2:
+ // Laura Bow 2 gets patched when speech and subtitles are enabled
+ // It then does both, when the user has "speech" selected. That's why we select speech here
+ default:
// Game does not support speech and subtitles, set it to speech
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
}
@@ -910,6 +925,46 @@ void SciEngine::syncIngameAudioOptions() {
}
}
+void SciEngine::updateScummVMAudioOptions() {
+ // Update ScummVM's speech/subtitles settings for SCI1.1 CD games,
+ // depending on the in-game settings
+ if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
+ uint16 ingameSetting = _gamestate->variables[VAR_GLOBAL][90].getOffset();
+ bool subtitlesOn = ConfMan.getBool("subtitles");
+ bool speechOn = !ConfMan.getBool("speech_mute");
+
+ switch (ingameSetting) {
+ case 1:
+ // subtitles
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ break;
+ case 2:
+ // speech
+ switch (_gameId) {
+ case GID_LAURABOW2:
+ // We don't sync "speech" for Laura Bow 2 in case the user choose "both" in the setting
+ // Because "speech" (2) within SCI means "speech + subtitles" for Laura Bow 2
+ if (subtitlesOn && speechOn)
+ return;
+ break;
+ default:
+ break;
+ }
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ case 3:
+ // speech + subtitles
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void SciEngine::loadMacExecutable() {
if (getPlatform() != Common::kPlatformMacintosh || getSciVersion() < SCI_VERSION_1_EARLY || getSciVersion() > SCI_VERSION_1_1)
return;
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 3b9844b326..c91606fbc9 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -82,28 +82,29 @@ class GfxFrameout;
// our engine debug levels
enum kDebugLevels {
- kDebugLevelError = 1 << 0,
- kDebugLevelNodes = 1 << 1,
- kDebugLevelGraphics = 1 << 2,
- kDebugLevelStrings = 1 << 3,
- kDebugLevelMemory = 1 << 4,
- kDebugLevelFuncCheck = 1 << 5,
- kDebugLevelBresen = 1 << 6,
- kDebugLevelSound = 1 << 7,
- kDebugLevelBaseSetter = 1 << 8,
- kDebugLevelParser = 1 << 9,
- kDebugLevelSaid = 1 << 10,
- kDebugLevelFile = 1 << 11,
- kDebugLevelTime = 1 << 12,
- kDebugLevelRoom = 1 << 13,
- kDebugLevelAvoidPath = 1 << 14,
- kDebugLevelDclInflate = 1 << 15,
- kDebugLevelVM = 1 << 16,
- kDebugLevelScripts = 1 << 17,
- kDebugLevelGC = 1 << 18,
- kDebugLevelResMan = 1 << 19,
- kDebugLevelOnStartup = 1 << 20,
- kDebugLevelDebugMode = 1 << 21
+ kDebugLevelError = 1 << 0,
+ kDebugLevelNodes = 1 << 1,
+ kDebugLevelGraphics = 1 << 2,
+ kDebugLevelStrings = 1 << 3,
+ kDebugLevelMemory = 1 << 4,
+ kDebugLevelFuncCheck = 1 << 5,
+ kDebugLevelBresen = 1 << 6,
+ kDebugLevelSound = 1 << 7,
+ kDebugLevelBaseSetter = 1 << 8,
+ kDebugLevelParser = 1 << 9,
+ kDebugLevelSaid = 1 << 10,
+ kDebugLevelFile = 1 << 11,
+ kDebugLevelTime = 1 << 12,
+ kDebugLevelRoom = 1 << 13,
+ kDebugLevelAvoidPath = 1 << 14,
+ kDebugLevelDclInflate = 1 << 15,
+ kDebugLevelVM = 1 << 16,
+ kDebugLevelScripts = 1 << 17,
+ kDebugLevelGC = 1 << 18,
+ kDebugLevelResMan = 1 << 19,
+ kDebugLevelOnStartup = 1 << 20,
+ kDebugLevelDebugMode = 1 << 21,
+ kDebugLevelScriptPatcher = 1 << 22
};
enum SciGameId {
@@ -138,6 +139,7 @@ enum SciGameId {
GID_KQ5,
GID_KQ6,
GID_KQ7,
+ GID_KQUESTIONS,
GID_LAURABOW,
GID_LAURABOW2,
GID_LIGHTHOUSE,
@@ -243,13 +245,15 @@ public:
* and we add this functionality in ScummVM:
* - Space Quest 4 CD
* - Freddy Pharkas CD
+ * - Laura Bow 2 CD
* SCI1.1 games which don't support simultaneous speech and subtitles,
* and we haven't added any extra functionality in ScummVM because extra
* script patches are needed:
- * - Laura Bow 2 CD
* - King's Quest 6 CD
*/
+ bool speechAndSubtitlesEnabled();
void syncIngameAudioOptions();
+ void updateScummVMAudioOptions();
const SciGameId &getGameId() const { return _gameId; }
const char *getGameIdStr() const;
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 9546b1503f..186fc18a5c 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -20,6 +20,9 @@
*
*/
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+
#include "sci/engine/kernel.h"
#include "sci/engine/state.h"
#include "sci/sound/midiparser_sci.h"
@@ -53,10 +56,6 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) :
_masterVolume = 15;
_volume = 127;
- _signalSet = false;
- _signalToSet = 0;
- _dataincAdd = false;
- _dataincToAdd = 0;
_resetOnPause = false;
_pSnd = 0;
}
@@ -439,20 +438,6 @@ void MidiParser_SCI::sendToDriver(uint32 midi) {
}
void MidiParser_SCI::parseNextEvent(EventInfo &info) {
- // Set signal AFTER waiting for delta, otherwise we would set signal too soon resulting in all sorts of bugs
- if (_dataincAdd) {
- _dataincAdd = false;
- _pSnd->dataInc += _dataincToAdd;
- _pSnd->signal = 0x7f + _pSnd->dataInc;
- debugC(4, kDebugLevelSound, "datainc %04x", _dataincToAdd);
- }
- if (_signalSet) {
- _signalSet = false;
- _pSnd->setSignal(_signalToSet);
-
- debugC(4, kDebugLevelSound, "signal %04x", _signalToSet);
- }
-
info.start = _position._playPos;
info.delta = 0;
while (*_position._playPos == 0xF8) {
@@ -474,6 +459,79 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0xC:
info.basic.param1 = *(_position._playPos++);
info.basic.param2 = 0;
+ break;
+ case 0xD:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = 0;
+ break;
+
+ case 0xB:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ info.length = 0;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xE:
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ if (info.command() == 0x9 && info.basic.param2 == 0)
+ info.event = info.channel() | 0x80;
+ info.length = 0;
+ break;
+
+ case 0xF: // System Common, Meta or SysEx event
+ switch (info.event & 0x0F) {
+ case 0x2: // Song Position Pointer
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = *(_position._playPos++);
+ break;
+
+ case 0x3: // Song Select
+ info.basic.param1 = *(_position._playPos++);
+ info.basic.param2 = 0;
+ break;
+
+ case 0x6:
+ case 0x8:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xE:
+ info.basic.param1 = info.basic.param2 = 0;
+ break;
+
+ case 0x0: // SysEx
+ info.length = readVLQ(_position._playPos);
+ info.ext.data = _position._playPos;
+ _position._playPos += info.length;
+ break;
+
+ case 0xF: // META event
+ info.ext.type = *(_position._playPos++);
+ info.length = readVLQ(_position._playPos);
+ info.ext.data = _position._playPos;
+ _position._playPos += info.length;
+ break;
+ default:
+ warning(
+ "MidiParser_SCI::parseNextEvent: Unsupported event code %x",
+ info.event);
+ } // // System Common, Meta or SysEx event
+ }// switch (info.command())
+}
+
+void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
+ if (!fireEvents) {
+ // We don't do any processing that should be done while skipping events
+ MidiParser::processEvent(info, fireEvents);
+ return;
+ }
+
+ switch (info.command()) {
+ case 0xC:
if (info.channel() == 0xF) {// SCI special case
if (info.basic.param1 != kSetSignalLoop) {
// At least in kq5/french&mac the first scene in the intro has
@@ -486,25 +544,47 @@ 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.
- if (_soundVersion <= SCI_VERSION_0_LATE ||
- _position._playTick || info.delta) {
- _signalSet = true;
- _signalToSet = info.basic.param1;
+ // 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.
+ bool skipSignal = false;
+ if (_soundVersion >= SCI_VERSION_1_EARLY) {
+ if (!_position._playTick) {
+ skipSignal = true;
+ switch (g_sci->getGameId()) {
+ case GID_ECOQUEST2:
+ // In Eco Quest 2 room 530 - gonzales is supposed to dance
+ // WORKAROUND: we need to signal in this case on tick 0
+ // this whole issue is complicated and can only be properly fixed by
+ // changing the whole parser to a per-channel parser. SSCI seems to
+ // start each channel at offset 13 (may be 10 for us) and only
+ // starting at offset 0 when the music loops to the initial position.
+ if (g_sci->getEngineState()->currentRoomNumber() == 530)
+ skipSignal = false;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (!skipSignal) {
+ if (!_jumpingToTick) {
+ _pSnd->setSignal(info.basic.param1);
+ debugC(4, kDebugLevelSound, "signal %04x", info.basic.param1);
+ }
}
} else {
- _loopTick = _position._playTick + info.delta;
+ _loopTick = _position._playTick;
}
+
+ // Done with this event.
+ return;
}
- break;
- case 0xD:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = 0;
- break;
+ // Break to let parent handle the rest.
+ break;
case 0xB:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
-
// Reference for some events:
// http://wiki.scummvm.org/index.php/SCI/Specifications/Sound/SCI0_Resource_Format#Status_Reference
// Handle common special events
@@ -526,43 +606,48 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
switch (info.basic.param1) {
case kSetReverb:
// Already handled above
- break;
+ return;
case kMidiHold:
// 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.
if (info.basic.param2 == _pSnd->hold) {
- uint32 extraDelta = info.delta;
jumpToTick(_loopTick, false, false);
- _nextEvent.delta += extraDelta;
+ // Done with this event.
+ return;
}
- break;
+ return;
case kUpdateCue:
- _dataincAdd = true;
- switch (_soundVersion) {
- case SCI_VERSION_0_EARLY:
- case SCI_VERSION_0_LATE:
- _dataincToAdd = info.basic.param2;
- break;
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
- case SCI_VERSION_2_1:
- _dataincToAdd = 1;
- break;
- default:
- error("unsupported _soundVersion");
+ if (!_jumpingToTick) {
+ int inc;
+ switch (_soundVersion) {
+ case SCI_VERSION_0_EARLY:
+ case SCI_VERSION_0_LATE:
+ inc = info.basic.param2;
+ break;
+ case SCI_VERSION_1_EARLY:
+ case SCI_VERSION_1_LATE:
+ case SCI_VERSION_2_1:
+ inc = 1;
+ break;
+ default:
+ error("unsupported _soundVersion");
+ }
+ _pSnd->dataInc += inc;
+ debugC(4, kDebugLevelSound, "datainc %04x", inc);
+
}
- break;
+ return;
case kResetOnPause:
_resetOnPause = info.basic.param2;
- break;
+ return;
// Unhandled SCI commands
case 0x46: // LSL3 - binoculars
case 0x61: // Iceman (AdLib?)
case 0x73: // Hoyle
case 0xD1: // KQ4, when riding the unicorn
// Obscure SCI commands - ignored
- break;
+ return;
// Standard MIDI commands
case 0x01: // mod wheel
case 0x04: // foot controller
@@ -577,84 +662,49 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0x4B: // voice mapping
// TODO: is any support for this needed at the MIDI parser level?
warning("Unhanded SCI MIDI command 0x%x - voice mapping (parameter %d)", info.basic.param1, info.basic.param2);
- break;
+ return;
default:
warning("Unhandled SCI MIDI command 0x%x (parameter %d)", info.basic.param1, info.basic.param2);
- break;
+ return;
}
+
}
- info.length = 0;
- break;
- case 0x8:
- case 0x9:
- case 0xA:
- case 0xE:
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
- if (info.command() == 0x9 && info.basic.param2 == 0)
- info.event = info.channel() | 0x80;
- info.length = 0;
+ // Break to let parent handle the rest.
break;
+ case 0xF: // META event
+ if (info.ext.type == 0x2F) {// end of track reached
+ if (_pSnd->loop)
+ _pSnd->loop--;
+ // QFG3 abuses the hold flag. Its scripts call kDoSoundSetHold,
+ // but sometimes there's no hold marker in the associated songs
+ // (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) {
+ jumpToTick(_loopTick);
+
+ // Done with this event.
+ return;
- case 0xF: // System Common, Meta or SysEx event
- switch (info.event & 0x0F) {
- case 0x2: // Song Position Pointer
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = *(_position._playPos++);
- break;
+ } else {
+ _pSnd->status = kSoundStopped;
+ _pSnd->setSignal(SIGNAL_OFFSET);
- case 0x3: // Song Select
- info.basic.param1 = *(_position._playPos++);
- info.basic.param2 = 0;
- break;
+ debugC(4, kDebugLevelSound, "signal EOT");
+ }
+ }
- case 0x6:
- case 0x8:
- case 0xA:
- case 0xB:
- case 0xC:
- case 0xE:
- info.basic.param1 = info.basic.param2 = 0;
- break;
+ // Break to let parent handle the rest.
+ break;
- case 0x0: // SysEx
- info.length = readVLQ(_position._playPos);
- info.ext.data = _position._playPos;
- _position._playPos += info.length;
- break;
+ default:
+ // Break to let parent handle the rest.
+ break;
+ }
- case 0xF: // META event
- info.ext.type = *(_position._playPos++);
- info.length = readVLQ(_position._playPos);
- info.ext.data = _position._playPos;
- _position._playPos += info.length;
- if (info.ext.type == 0x2F) {// end of track reached
- if (_pSnd->loop)
- _pSnd->loop--;
- // QFG3 abuses the hold flag. Its scripts call kDoSoundSetHold,
- // but sometimes there's no hold marker in the associated songs
- // (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...
- uint32 extraDelta = info.delta;
- jumpToTick(_loopTick);
- _nextEvent.delta += extraDelta;
- } else {
- _pSnd->status = kSoundStopped;
- _pSnd->setSignal(SIGNAL_OFFSET);
-
- debugC(4, kDebugLevelSound, "signal EOT");
- }
- }
- break;
- default:
- warning(
- "MidiParser_SCI::parseNextEvent: Unsupported event code %x",
- info.event);
- } // // System Common, Meta or SysEx event
- }// switch (info.command())
+
+ // Let parent handle the rest
+ MidiParser::processEvent(info, fireEvents);
}
byte MidiParser_SCI::getSongReverb() {
diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h
index d3fd337644..5784dca1ab 100644
--- a/engines/sci/sound/midiparser_sci.h
+++ b/engines/sci/sound/midiparser_sci.h
@@ -89,6 +89,7 @@ public:
protected:
void parseNextEvent(EventInfo &info);
+ void processEvent(const EventInfo &info, bool fireEvents = true);
byte *midiMixChannels();
byte *midiFilterChannels(int channelMask);
byte midiGetNextChannel(long ticker);
@@ -106,10 +107,6 @@ protected:
byte _masterVolume; // the overall master volume (same for all tracks)
byte _volume; // the global volume of the current track
- bool _signalSet;
- int16 _signalToSet;
- bool _dataincAdd;
- int16 _dataincToAdd;
bool _resetOnPause;
bool _channelUsed[16];
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 913ba32cba..8c6d0d6431 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -519,9 +519,10 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
if (pSnd->status == kSoundStopped)
pSnd->pMidiParser->jumpToTick(0);
- else
+ else {
// Fast forward to the last position and perform associated events when loading
pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
+ }
// Restore looping and hold
pSnd->loop = prevLoop;
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 1f798c90d7..40236c8445 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -69,7 +69,7 @@ public:
uint16 dataInc;
uint16 ticker;
uint16 signal;
- byte priority;
+ int16 priority; // must be int16, at least in Laura Bow 1, main music (object conMusic) uses priority -1
uint16 loop;
int16 volume;
int16 hold;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index daba976f50..aa2a309f4d 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -116,7 +116,10 @@ void SoundCommandParser::processInitSound(reg_t obj) {
newSound->resourceId = resourceId;
newSound->soundObj = obj;
newSound->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
- newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority)) & 0xFF;
+ if (_soundVersion <= SCI_VERSION_0_LATE)
+ newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ else
+ newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority)) & 0xFF;
if (_soundVersion >= SCI_VERSION_1_EARLY)
newSound->volume = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, MUSIC_VOLUME_MAX);
newSound->reverb = -1; // initialize to SCI invalid, it'll be set correctly in soundInitSnd() below
@@ -428,7 +431,7 @@ reg_t SoundCommandParser::kDoSoundUpdate(int argc, reg_t *argv, reg_t acc) {
int16 objVol = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, 255);
if (objVol != musicSlot->volume)
_music->soundSetVolume(musicSlot, objVol);
- uint32 objPrio = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ int16 objPrio = readSelectorValue(_segMan, obj, SELECTOR(priority));
if (objPrio != musicSlot->priority)
_music->soundSetPriority(musicSlot, objPrio);
return acc;
@@ -505,9 +508,19 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
// fireworks).
// It is also needed in other games, e.g. LSL6 when talking to the
// receptionist (bug #3192166).
- // CHECKME: At least kq5cd/win and kq6 set signal to 0xFE here, but
- // kq5cd/dos does not set signal at all. Needs more investigation.
- writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
+ // TODO: More thorougly check the different SCI version:
+ // * SCI1late sets signal to 0xFE here. (With signal 0xFF
+ // duplicate music plays in LauraBow2CD - bug #6462)
+ // SCI1middle LSL1 1.000.510 does not have the 0xFE;
+ // SCI1late CastleDrBrain demo 1.000.005 does have the 0xFE.
+ // * Other SCI1 games seem to rely on processStopSound to set the signal
+ // * Need to check SCI0 behaviour.
+ uint16 sig;
+ if (getSciVersion() >= SCI_VERSION_1_LATE)
+ sig = 0xFFFE;
+ else
+ sig = SIGNAL_OFFSET;
+ writeSelectorValue(_segMan, obj, SELECTOR(signal), sig);
if (_soundVersion <= SCI_VERSION_0_LATE) {
processStopSound(obj, false);
} else {
@@ -530,17 +543,21 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
}
reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) {
+ // The 4 parameter variant of this call is used in at least LSL1VGA, room
+ // 110 (Lefty's bar), to distort the music when Larry is drunk and stands
+ // up - bug #3614447.
reg_t obj = argv[0];
byte channel = argv[1].toUint16() & 0xf;
- byte midiCmd = argv[2].toUint16() & 0xff;
+ byte midiCmd = (argc == 5) ? argv[2].toUint16() & 0xff : 0xB0; // 0xB0: controller
+ uint16 controller = (argc == 5) ? argv[3].toUint16() : argv[2].toUint16();
+ uint16 param = (argc == 5) ? argv[4].toUint16() : argv[3].toUint16();
- // TODO: first there is a 4-parameter variant of this call which needs to get reversed
- // second the current code isn't 100% accurate, sierra sci does checks on the 4th parameter
- if (argc == 4)
- return acc;
-
- uint16 controller = argv[3].toUint16();
- uint16 param = argv[4].toUint16();
+ if (argc == 4 && controller == 0xFF) {
+ midiCmd = 0xE0; // 0xE0: pitch wheel
+ uint16 pitch = CLIP<uint16>(argv[3].toSint16() + 0x2000, 0x0000, 0x3FFF);
+ controller = pitch & 0x7F;
+ param = pitch >> 7;
+ }
debugC(kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param);
if (channel)
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/POTFILES b/engines/scumm/POTFILES
new file mode 100644
index 0000000000..6034320259
--- /dev/null
+++ b/engines/scumm/POTFILES
@@ -0,0 +1,3 @@
+engines/scumm/dialogs.cpp
+engines/scumm/help.cpp
+engines/scumm/scumm.cpp
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/configure.engine b/engines/scumm/configure.engine
new file mode 100644
index 0000000000..e1de788061
--- /dev/null
+++ b/engines/scumm/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
+add_engine scumm_7_8 "v7 & v8 games" yes
+add_engine he "HE71+ games" yes
diff --git a/engines/scumm/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.cpp b/engines/scumm/detection.cpp
index 170ca0993c..aa7e60930a 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -1223,8 +1223,8 @@ const char *ScummMetaEngine::getOriginalCopyright() const {
}
namespace Scumm {
- extern bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion);
-}
+bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion);
+} // End of namespace Scumm
int ScummMetaEngine::getMaximumSaveSlot() const { return 99; }
@@ -1262,25 +1262,21 @@ void ScummMetaEngine::removeSaveState(const char *target, int slot) const {
}
SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
- Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
-
- if (!in)
- return SaveStateDescriptor();
-
Common::String saveDesc;
- Scumm::getSavegameName(in, saveDesc, 0); // FIXME: heversion?!?
- delete in;
+ Graphics::Surface *thumbnail = nullptr;
+ SaveStateMetaInfos infos;
+ memset(&infos, 0, sizeof(infos));
+ SaveStateMetaInfos *infoPtr = &infos;
- // TODO: Cleanup
- Graphics::Surface *thumbnail = ScummEngine::loadThumbnailFromSlot(target, slot);
+ // FIXME: heversion?!?
+ if (!ScummEngine::querySaveMetaInfos(target, slot, 0, saveDesc, thumbnail, infoPtr)) {
+ return SaveStateDescriptor();
+ }
SaveStateDescriptor desc(slot, saveDesc);
desc.setThumbnail(thumbnail);
- SaveStateMetaInfos infos;
- memset(&infos, 0, sizeof(infos));
- if (ScummEngine::loadInfosFromSlot(target, slot, &infos)) {
+ if (infoPtr) {
int day = (infos.date >> 24) & 0xFF;
int month = (infos.date >> 16) & 0xFF;
int year = infos.date & 0xFFFF;
diff --git a/engines/scumm/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/intern_he.h b/engines/scumm/he/intern_he.h
index fc5e4bcdf0..a674288775 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -628,7 +628,6 @@ public:
void parseEvents();
- bool _quit;
OSystem *_syst;
GameSettings _game;
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 a875702383..0e96952a48 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -46,7 +46,6 @@ namespace Scumm {
IMuseInternal::IMuseInternal() :
_native_mt32(false),
_enable_gs(false),
- _sc55(false),
_midi_adlib(NULL),
_midi_native(NULL),
_sysex(NULL),
@@ -495,12 +494,9 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
case IMuse::PROP_GS:
_enable_gs = (value > 0);
- // If True Roland MT-32 is not selected, run in GM or GS mode.
- // If it is selected, change the Roland GS synth to MT-32 mode.
- if (_midi_native && !_native_mt32)
- initGM(_midi_native);
- else if (_midi_native && _native_mt32 && _enable_gs) {
- _sc55 = true;
+ // GS Mode emulates MT-32 on a GS device, so _native_mt32 should always be true
+ if (_midi_native && _enable_gs) {
+ _native_mt32 = true;
initGM(_midi_native);
}
break;
@@ -1487,7 +1483,7 @@ void IMuseInternal::initMT32(MidiDriver *midi) {
}
void IMuseInternal::initGM(MidiDriver *midi) {
- byte buffer[11];
+ byte buffer[12];
int i;
// General MIDI System On message
@@ -1499,7 +1495,7 @@ void IMuseInternal::initGM(MidiDriver *midi) {
if (_enable_gs) {
// All GS devices recognize the GS Reset command,
- // even with Roland's ID. It is impractical to
+ // even using Roland's ID. It is impractical to
// support other manufacturers' devices for
// further GS settings, as there are limitless
// numbers of them out there that would each
@@ -1514,29 +1510,27 @@ void IMuseInternal::initGM(MidiDriver *midi) {
debug(2, "GS SysEx: GS Reset");
_system->delayMillis(200);
- if (_sc55) {
- // This mode is for GS devices that support an MT-32-compatible
- // Map, such as the Roland Sound Canvas line of modules. It
- // will allow them to work with True MT-32 mode, but will
- // obviously still ignore MT-32 SysEx (and thus custom
- // instruments).
-
- // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation
- for (i = 0; i < 16; ++i) {
- midi->send((127 << 16) | (0 << 8) | (0xB0 | i));
- midi->send((1 << 16) | (32 << 8) | (0xB0 | i));
- midi->send((0 << 16) | (0 << 8) | (0xC0 | i));
- }
- debug(2, "GS Program Change: CM-64/32L Map Selected");
+ // 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);
+ debug(2, "GS SysEx: Master Tune set to 442.0kHz");
- // Set Percussion Channel to SC-55 Map (CC#32, 01H), then
- // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums)
- midi->getPercussionChannel()->controlChange(0, 0);
- midi->getPercussionChannel()->controlChange(32, 1);
- midi->send(127 << 8 | 0xC0 | 9);
- debug(2, "GS Program Change: Drum Map is CM-64/32L");
+ // Note: All Roland GS devices support CM-64/32L maps
+ // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation
+ for (i = 0; i < 16; ++i) {
+ midi->send((127 << 16) | (0 << 8) | (0xB0 | i));
+ midi->send((1 << 16) | (32 << 8) | (0xB0 | i));
+ midi->send((0 << 16) | (0 << 8) | (0xC0 | i));
}
+ debug(2, "GS Program Change: CM-64/32L Map Selected");
+
+ // Set Percussion Channel to SC-55 Map (CC#32, 01H), then
+ // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums)
+ midi->getPercussionChannel()->controlChange(0, 0);
+ midi->getPercussionChannel()->controlChange(32, 1);
+ midi->send(127 << 8 | 0xC0 | 9);
+ debug(2, "GS Program Change: Drum Map is CM-64/32L");
// Set Master Chorus to 0. The MT-32 has no chorus capability.
memcpy(&buffer[4], "\x40\x01\x3A\x00\x05", 5);
@@ -1546,7 +1540,7 @@ void IMuseInternal::initGM(MidiDriver *midi) {
// Set Channels 1-16 Reverb to 64, which is the
// equivalent of MT-32 default Reverb Level 5
for (i = 0; i < 16; ++i)
- midi->send((64 << 16) | (91 << 8) | (0xB0 | i));
+ midi->send((64 << 16) | (91 << 8) | (0xB0 | i));
debug(2, "GM Controller 91 Change: Channels 1-16 Reverb Level is 64");
// Set Channels 1-16 Pitch Bend Sensitivity to
diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h
index 6be564a517..d17d4ed28b 100644
--- a/engines/scumm/imuse/imuse_internal.h
+++ b/engines/scumm/imuse/imuse_internal.h
@@ -390,7 +390,6 @@ class IMuseInternal : public IMuse {
protected:
bool _native_mt32;
bool _enable_gs;
- bool _sc55;
MidiDriver *_midi_adlib;
MidiDriver *_midi_native;
TimerCallbackInfo _timer_info_adlib;
diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp
index eb3717494f..a737539c44 100644
--- a/engines/scumm/imuse_digi/dimuse.cpp
+++ b/engines/scumm/imuse_digi/dimuse.cpp
@@ -275,9 +275,12 @@ void IMuseDigital::callback() {
feedSize &= ~1;
if (channels == 2)
feedSize &= ~3;
- } else {
+ } else if (bits == 8) {
if (channels == 2)
feedSize &= ~1;
+ } else {
+ warning("IMuseDigita::callback: Unexpected sample width, %d bits", bits);
+ continue;
}
if (feedSize == 0)
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index abd0d68e56..26e248fbca 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -443,11 +443,13 @@ ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::openSound(int32 soundId, const char
} else if (soundName[0] == 0) {
if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0 || ptr == NULL) {
closeSound(sound);
+ free(ptr);
return NULL;
}
} else {
if (sound->bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside) == 0 || ptr == NULL) {
closeSound(sound);
+ free(ptr);
return NULL;
}
}
@@ -667,15 +669,18 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (scumm_stricmp(fileName, soundDesc->lastFileName) != 0) {
int32 offs = 0, len = 0;
Common::SeekableReadStream *cmpFile;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
uint8 soundMode = 0;
+#endif
sprintf(fileName, "%s_reg%03d.fla", soundDesc->name, region);
cmpFile = soundDesc->bundle->getFile(fileName, offs, len);
if (len) {
#ifndef USE_FLAC
error("FLAC library compiled support needed");
-#endif
+#else
soundMode = 3;
+#endif
}
if (!len) {
sprintf(fileName, "%s_reg%03d.ogg", soundDesc->name, region);
@@ -683,8 +688,9 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (len) {
#ifndef USE_VORBIS
error("Vorbis library compiled support needed");
-#endif
+#else
soundMode = 2;
+#endif
}
}
if (!len) {
@@ -693,8 +699,9 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (len) {
#ifndef USE_MAD
error("Mad library compiled support needed");
-#endif
+#else
soundMode = 1;
+#endif
}
}
assert(len);
diff --git a/engines/scumm/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/module.mk b/engines/scumm/module.mk
index 28884d7f78..d43db1e5f1 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -35,22 +35,23 @@ MODULE_OBJS := \
midiparser_ro.o \
object.o \
palette.o \
- player_apple2.o \
- player_mac.o \
- player_mod.o \
- player_nes.o \
- player_pce.o \
- player_sid.o \
- player_towns.o \
- player_v1.o \
- player_v2.o \
- player_v2a.o \
- player_v2base.o \
- player_v2cms.o \
- player_v3a.o \
- player_v3m.o \
- player_v4a.o \
- player_v5m.o \
+ players/player_ad.o \
+ players/player_apple2.o \
+ players/player_mac.o \
+ players/player_mod.o \
+ players/player_nes.o \
+ players/player_pce.o \
+ players/player_sid.o \
+ players/player_towns.o \
+ players/player_v1.o \
+ players/player_v2.o \
+ players/player_v2a.o \
+ players/player_v2base.o \
+ players/player_v2cms.o \
+ players/player_v3a.o \
+ players/player_v3m.o \
+ players/player_v4a.o \
+ players/player_v5m.o \
resource_v2.o \
resource_v3.o \
resource_v4.o \
diff --git a/engines/scumm/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/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
new file mode 100644
index 0000000000..20630e1cb9
--- /dev/null
+++ b/engines/scumm/players/player_ad.cpp
@@ -0,0 +1,959 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/players/player_ad.h"
+#include "scumm/imuse/imuse.h"
+#include "scumm/scumm.h"
+#include "scumm/resource.h"
+
+#include "audio/fmopl.h"
+
+#include "common/textconsole.h"
+#include "common/config-manager.h"
+
+namespace Scumm {
+
+#define AD_CALLBACK_FREQUENCY 472
+
+Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
+ : _vm(scumm), _mixer(mixer), _rate(mixer->getOutputRate()) {
+ _opl2 = OPL::Config::create();
+ if (!_opl2->init(_rate)) {
+ error("Could not initialize OPL2 emulator");
+ }
+
+ _samplesPerCallback = _rate / AD_CALLBACK_FREQUENCY;
+ _samplesPerCallbackRemainder = _rate % AD_CALLBACK_FREQUENCY;
+ _samplesTillCallback = 0;
+ _samplesTillCallbackRemainder = 0;
+
+ memset(_registerBackUpTable, 0, sizeof(_registerBackUpTable));
+ writeReg(0x01, 0x00);
+ writeReg(0xBD, 0x00);
+ writeReg(0x08, 0x00);
+ writeReg(0x01, 0x20);
+
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ _engineMusicTimer = 0;
+ _soundPlaying = -1;
+
+ _curOffset = 0;
+
+ _sfxTimer = 4;
+ _rndSeed = 1;
+
+ memset(_channels, 0, sizeof(_channels));
+ memset(_sfxResource, 0, sizeof(_sfxResource));
+ memset(_sfxPriority, 0, sizeof(_sfxPriority));
+}
+
+Player_AD::~Player_AD() {
+ _mixer->stopHandle(_soundHandle);
+
+ stopAllSounds();
+ Common::StackLock lock(_mutex);
+ delete _opl2;
+ _opl2 = 0;
+}
+
+void Player_AD::setMusicVolume(int vol) {
+ // HACK: We ignore the parameter and set up the volume specified in the
+ // config manager. This allows us to differentiate between music and sfx
+ // volume changes.
+ setupVolume();
+}
+
+void Player_AD::startSound(int sound) {
+ Common::StackLock lock(_mutex);
+
+ // Query the sound resource
+ const byte *res = _vm->getResourceAddress(rtSound, sound);
+
+ if (res[2] == 0x80) {
+ // Stop the current sounds
+ stopAllSounds();
+
+ // Lock the new music resource
+ _soundPlaying = sound;
+ _vm->_res->lock(rtSound, _soundPlaying);
+
+ // Start the new music resource
+ _resource = res;
+ startMusic();
+ } else {
+ // Only try to start a sfx when no music is playing.
+ if (_soundPlaying == -1) {
+ const byte priority = res[0];
+ const byte channel = res[1];
+
+ // Check for out of bounds access
+ if (channel >= 3) {
+ warning("AdLib sfx resource %d uses channel %d", sound, channel);
+ return;
+ }
+
+ // Check whether the channel is free or the priority of the new
+ // sfx resource is above the old one.
+ if (_channels[channel * 3 + 0].state
+ || _channels[channel * 3 + 1].state
+ || _channels[channel * 3 + 2].state) {
+ if (_sfxPriority[channel] > priority) {
+ return;
+ }
+ }
+
+ // Lock the new resource
+ _sfxResource[channel] = sound;
+ _sfxPriority[channel] = priority;
+ _vm->_res->lock(rtSound, sound);
+
+ // Start the actual sfx resource
+ _resource = res;
+ startSfx();
+ }
+ }
+
+ // Setup the sound volume
+ setupVolume();
+}
+
+void Player_AD::stopSound(int sound) {
+ Common::StackLock lock(_mutex);
+
+ if (sound == _soundPlaying) {
+ stopAllSounds();
+ } else {
+ for (int i = 0; i < 3; ++i) {
+ if (_sfxResource[i] == sound) {
+ if (_channels[i * 3 + 0].state
+ || _channels[i * 3 + 1].state
+ || _channels[i * 3 + 2].state) {
+ // Unlock the sound resource
+ _vm->_res->unlock(rtSound, sound);
+
+ // Stop the actual sfx playback
+ _channels[i * 3 + 0].state = 0;
+ _channels[i * 3 + 1].state = 0;
+ _channels[i * 3 + 2].state = 0;
+ clearChannel(i * 3 + 0);
+ clearChannel(i * 3 + 1);
+ clearChannel(i * 3 + 2);
+ }
+ }
+ }
+ }
+}
+
+void Player_AD::stopAllSounds() {
+ Common::StackLock lock(_mutex);
+
+ // Unlock the music resource if present
+ if (_soundPlaying != -1) {
+ _vm->_res->unlock(rtSound, _soundPlaying);
+ _soundPlaying = -1;
+ }
+
+ // Stop the music playback
+ _curOffset = 0;
+
+ // Unloack all used sfx resources
+ for (int i = 0; i < 3; ++i) {
+ if (_channels[i * 3 + 0].state || _channels[i * 3 + 1].state || _channels[i * 3 + 2].state) {
+ _vm->_res->unlock(rtSound, _sfxResource[i]);
+ }
+ }
+
+ // Reset all the sfx channels
+ for (int i = 0; i < 9; ++i) {
+ _channels[i].state = 0;
+ clearChannel(i);
+ }
+
+ writeReg(0xBD, 0x00);
+}
+
+int Player_AD::getMusicTimer() {
+ return _engineMusicTimer;
+}
+
+int Player_AD::getSoundStatus(int sound) const {
+ return (sound == _soundPlaying);
+}
+
+void Player_AD::saveLoadWithSerializer(Serializer *ser) {
+ Common::StackLock lock(_mutex);
+
+ if (ser->getVersion() < VER(95)) {
+ IMuse *dummyImuse = IMuse::create(_vm->_system, NULL, NULL);
+ dummyImuse->save_or_load(ser, _vm, false);
+ delete dummyImuse;
+ return;
+ }
+
+ // TODO: Be nicer than the original and save the data to continue the
+ // currently played sound resources on load?
+}
+
+int Player_AD::readBuffer(int16 *buffer, const int numSamples) {
+ Common::StackLock lock(_mutex);
+
+ int len = numSamples;
+
+ while (len > 0) {
+ if (!_samplesTillCallback) {
+ // Run the update callback for music or sfx depending on which is
+ // active.
+ if (_curOffset) {
+ updateMusic();
+ } else {
+ updateSfx();
+ }
+
+ _samplesTillCallback = _samplesPerCallback;
+ _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+ if (_samplesTillCallbackRemainder >= AD_CALLBACK_FREQUENCY) {
+ ++_samplesTillCallback;
+ _samplesTillCallbackRemainder -= AD_CALLBACK_FREQUENCY;
+ }
+ }
+
+ const int samplesToRead = MIN(len, _samplesTillCallback);
+ _opl2->readBuffer(buffer, samplesToRead);
+
+ buffer += samplesToRead;
+ len -= samplesToRead;
+ _samplesTillCallback -= samplesToRead;
+ }
+
+ return numSamples;
+}
+
+void Player_AD::setupVolume() {
+ // Setup the correct volume
+ int soundVolumeMusic = CLIP<int>(ConfMan.getInt("music_volume"), 0, Audio::Mixer::kMaxChannelVolume);
+ int soundVolumeSfx = CLIP<int>(ConfMan.getInt("sfx_volume"), 0, Audio::Mixer::kMaxChannelVolume);
+ if (ConfMan.hasKey("mute")) {
+ if (ConfMan.getBool("mute")) {
+ soundVolumeMusic = 0;
+ soundVolumeSfx = 0;
+ }
+ }
+
+ // In case a music is being played set the music volume. Set the sfx
+ // volume otherwise. This is safe because in the latter case either
+ // sfx are playing or there is no sound being played at all.
+ if (_soundPlaying != -1) {
+ _mixer->setChannelVolume(_soundHandle, soundVolumeMusic);
+ } else {
+ _mixer->setChannelVolume(_soundHandle, soundVolumeSfx);
+ }
+}
+
+void Player_AD::writeReg(int r, int v) {
+ if (r >= 0 && r < ARRAYSIZE(_registerBackUpTable)) {
+ _registerBackUpTable[r] = v;
+ }
+ _opl2->writeReg(r, v);
+}
+
+uint8 Player_AD::readReg(int r) const {
+ if (r >= 0 && r < ARRAYSIZE(_registerBackUpTable)) {
+ return _registerBackUpTable[r];
+ } else {
+ return 0;
+ }
+}
+
+void Player_AD::setupChannel(const uint channel, const byte *instrOffset) {
+ instrOffset += 2;
+ writeReg(0xC0 + channel, *instrOffset++);
+ setupOperator(_operatorOffsetTable[channel * 2 + 0], instrOffset);
+ setupOperator(_operatorOffsetTable[channel * 2 + 1], instrOffset);
+}
+
+void Player_AD::setupOperator(const uint opr, const byte *&instrOffset) {
+ writeReg(0x20 + opr, *instrOffset++);
+ writeReg(0x40 + opr, *instrOffset++);
+ writeReg(0x60 + opr, *instrOffset++);
+ writeReg(0x80 + opr, *instrOffset++);
+ writeReg(0xE0 + opr, *instrOffset++);
+}
+
+const int Player_AD::_operatorOffsetTable[18] = {
+ 0, 3, 1, 4,
+ 2, 5, 8, 11,
+ 9, 12, 10, 13,
+ 16, 19, 17, 20,
+ 18, 21
+};
+
+// Music
+
+void Player_AD::startMusic() {
+ memset(_instrumentOffset, 0, sizeof(_instrumentOffset));
+ memset(_channelLastEvent, 0, sizeof(_channelLastEvent));
+ memset(_channelFrequency, 0, sizeof(_channelFrequency));
+ memset(_channelB0Reg, 0, sizeof(_channelB0Reg));
+
+ _voiceChannels = 0;
+ uint instruments = _resource[10];
+ for (uint i = 0; i < instruments; ++i) {
+ const int instrIndex = _resource[11 + i] - 1;
+ if (0 <= instrIndex && instrIndex < 16) {
+ _instrumentOffset[instrIndex] = i * 16 + 16 + 3;
+ _voiceChannels |= _resource[_instrumentOffset[instrIndex] + 13];
+ }
+ }
+
+ if (_voiceChannels) {
+ _mdvdrState = 0x20;
+ _voiceChannels = 6;
+ } else {
+ _mdvdrState = 0;
+ _voiceChannels = 9;
+ }
+
+ _curOffset = 0x93;
+ // TODO: is this the same for Loom?
+ _nextEventTimer = 40;
+ _engineMusicTimer = 0;
+ _internalMusicTimer = 0;
+ _musicTimer = 0;
+
+ writeReg(0xBD, _mdvdrState);
+
+ const bool isLoom = (_vm->_game.id == GID_LOOM);
+ _timerLimit = isLoom ? 473 : 256;
+ _musicTicks = _resource[3] * (isLoom ? 2 : 1);
+ _loopFlag = (_resource[4] == 0);
+ _musicLoopStart = READ_LE_UINT16(_resource + 5);
+}
+
+void Player_AD::updateMusic() {
+ _musicTimer += _musicTicks;
+ if (_musicTimer < _timerLimit) {
+ return;
+ }
+ _musicTimer -= _timerLimit;
+
+ ++_internalMusicTimer;
+ if (_internalMusicTimer > 120) {
+ _internalMusicTimer = 0;
+ ++_engineMusicTimer;
+ }
+
+ --_nextEventTimer;
+ if (_nextEventTimer) {
+ return;
+ }
+
+ while (true) {
+ uint command = _resource[_curOffset++];
+ if (command == 0xFF) {
+ // META EVENT
+ // Get the command number.
+ command = _resource[_curOffset++];
+ if (command == 47) {
+ // End of track
+ if (_loopFlag) {
+ // In case the track is looping jump to the start.
+ _curOffset = _musicLoopStart;
+ _nextEventTimer = 0;
+ } else {
+ // Otherwise completely stop playback.
+ stopAllSounds();
+ }
+ return;
+ } else if (command == 88) {
+ // This is proposedly a debug information insertion. The CMS
+ // player code handles this differently, but is still using
+ // the same resources...
+ _curOffset += 5;
+ } else if (command == 81) {
+ // Change tempo. This is used exclusively in Loom.
+ const uint timing = _resource[_curOffset + 2] | (_resource[_curOffset + 1] << 8);
+ _musicTicks = 0x73000 / timing;
+ command = _resource[_curOffset++];
+ _curOffset += command;
+ } else {
+ // In case an unknown meta event occurs just skip over the
+ // data by using the length supplied.
+ command = _resource[_curOffset++];
+ _curOffset += command;
+ }
+ } else {
+ if (command >= 0x90) {
+ // NOTE ON
+ // Extract the channel number and save it in command.
+ command -= 0x90;
+
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset) {
+ if (_resource[instrOffset + 13] != 0) {
+ setupRhythm(_resource[instrOffset + 13], instrOffset);
+ } else {
+ int channel = findFreeChannel();
+ if (channel != -1) {
+ noteOff(channel);
+ setupChannel(channel, instrOffset);
+ _channelLastEvent[channel] = command + 0x90;
+ _channelFrequency[channel] = _resource[_curOffset];
+ setupFrequency(channel, _resource[_curOffset]);
+ }
+ }
+ }
+ } else {
+ // NOTE OFF
+ const uint note = _resource[_curOffset];
+ command += 0x10;
+
+ // Find the output channel which plays the note.
+ uint channel = 0xFF;
+ for (uint i = 0; i < _voiceChannels; ++i) {
+ if (_channelFrequency[i] == note && _channelLastEvent[i] == command) {
+ channel = i;
+ break;
+ }
+ }
+
+ if (channel != 0xFF) {
+ // In case a output channel playing the note was found,
+ // stop it.
+ noteOff(channel);
+ } else {
+ // In case there is no such note this will disable the
+ // rhythm instrument played on the channel.
+ command -= 0x90;
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset && _resource[instrOffset + 13] != 0) {
+ const uint rhythmInstr = _resource[instrOffset + 13];
+ if (rhythmInstr < 6) {
+ _mdvdrState &= _mdvdrTable[rhythmInstr] ^ 0xFF;
+ writeReg(0xBD, _mdvdrState);
+ }
+ }
+ }
+ }
+
+ _curOffset += 2;
+ }
+
+ // In case there is a delay till the next event stop handling.
+ if (_resource[_curOffset] != 0) {
+ break;
+ }
+ ++_curOffset;
+ }
+
+ _nextEventTimer = _resource[_curOffset++];
+ if (_nextEventTimer & 0x80) {
+ _nextEventTimer -= 0x80;
+ _nextEventTimer <<= 7;
+ _nextEventTimer |= _resource[_curOffset++];
+ }
+
+ _nextEventTimer >>= (_vm->_game.id == GID_LOOM) ? 2 : 1;
+ if (!_nextEventTimer) {
+ _nextEventTimer = 1;
+ }
+}
+
+void Player_AD::noteOff(uint channel) {
+ _channelLastEvent[channel] = 0;
+ writeReg(0xB0 + channel, _channelB0Reg[channel] & 0xDF);
+}
+
+int Player_AD::findFreeChannel() {
+ for (uint i = 0; i < _voiceChannels; ++i) {
+ if (!_channelLastEvent[i]) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void Player_AD::setupFrequency(uint channel, int8 frequency) {
+ frequency -= 31;
+ if (frequency < 0) {
+ frequency = 0;
+ }
+
+ uint octave = 0;
+ while (frequency >= 12) {
+ frequency -= 12;
+ ++octave;
+ }
+
+ const uint noteFrequency = _noteFrequencies[frequency];
+ octave <<= 2;
+ octave |= noteFrequency >> 8;
+ octave |= 0x20;
+ writeReg(0xA0 + channel, noteFrequency & 0xFF);
+ _channelB0Reg[channel] = octave;
+ writeReg(0xB0 + channel, octave);
+}
+
+void Player_AD::setupRhythm(uint rhythmInstr, uint instrOffset) {
+ if (rhythmInstr == 1) {
+ setupChannel(6, instrOffset);
+ writeReg(0xA6, _resource[instrOffset++]);
+ writeReg(0xB6, _resource[instrOffset] & 0xDF);
+ _mdvdrState |= 0x10;
+ writeReg(0xBD, _mdvdrState);
+ } else if (rhythmInstr < 6) {
+ const byte *secondOperatorOffset = _resource + instrOffset + 8;
+ setupOperator(_rhythmOperatorTable[rhythmInstr], secondOperatorOffset);
+ writeReg(0xA0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset++]);
+ writeReg(0xB0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset++] & 0xDF);
+ writeReg(0xC0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset]);
+ _mdvdrState |= _mdvdrTable[rhythmInstr];
+ writeReg(0xBD, _mdvdrState);
+ }
+}
+
+const uint Player_AD::_noteFrequencies[12] = {
+ 0x200, 0x21E, 0x23F, 0x261,
+ 0x285, 0x2AB, 0x2D4, 0x300,
+ 0x32E, 0x35E, 0x390, 0x3C7
+};
+
+const uint Player_AD::_mdvdrTable[6] = {
+ 0x00, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+const uint Player_AD::_rhythmOperatorTable[6] = {
+ 0x00, 0x00, 0x14, 0x12, 0x15, 0x11
+};
+
+const uint Player_AD::_rhythmChannelTable[6] = {
+ 0x00, 0x00, 0x07, 0x08, 0x08, 0x07
+};
+
+// SFX
+
+void Player_AD::startSfx() {
+ writeReg(0xBD, 0x00);
+
+ // The second byte of the resource defines the logical channel where
+ // the sound effect should be played.
+ const int startChannel = _resource[1] * 3;
+
+ // Clear the channel.
+ _channels[startChannel + 0].state = 0;
+ _channels[startChannel + 1].state = 0;
+ _channels[startChannel + 2].state = 0;
+
+ clearChannel(startChannel + 0);
+ clearChannel(startChannel + 1);
+ clearChannel(startChannel + 2);
+
+ // Set up the first channel to pick up playback.
+ _channels[startChannel].currentOffset = _channels[startChannel].startOffset = _resource + 2;
+ _channels[startChannel].state = 1;
+
+ // Scan for the start of the other channels and set them up if required.
+ int curChannel = startChannel + 1;
+ const byte *bufferPosition = _resource + 2;
+ uint8 command = 0;
+ while ((command = *bufferPosition) != 0xFF) {
+ switch (command) {
+ case 1:
+ // INSTRUMENT DEFINITION
+ bufferPosition += 15;
+ break;
+
+ case 2:
+ // NOTE DEFINITION
+ bufferPosition += 11;
+ break;
+
+ case 0x80:
+ // LOOP
+ bufferPosition += 1;
+ break;
+
+ default:
+ // START OF CHANNEL
+ bufferPosition += 1;
+ _channels[curChannel].currentOffset = bufferPosition;
+ _channels[curChannel].startOffset = bufferPosition;
+ _channels[curChannel].state = 1;
+ ++curChannel;
+ break;
+ }
+ }
+}
+
+void Player_AD::updateSfx() {
+ if (--_sfxTimer) {
+ return;
+ }
+ _sfxTimer = 4;
+
+ for (int i = 0; i <= 9; ++i) {
+ if (!_channels[i].state) {
+ continue;
+ }
+
+ updateChannel(i);
+ }
+}
+
+void Player_AD::clearChannel(int channel) {
+ writeReg(0xA0 + channel, 0x00);
+ writeReg(0xB0 + channel, 0x00);
+}
+
+void Player_AD::updateChannel(int channel) {
+ if (_channels[channel].state == 1) {
+ parseSlot(channel);
+ } else {
+ updateSlot(channel);
+ }
+}
+
+void Player_AD::parseSlot(int channel) {
+ while (true) {
+ const byte *curOffset = _channels[channel].currentOffset;
+
+ switch (*curOffset) {
+ case 1:
+ // INSTRUMENT DEFINITION
+ ++curOffset;
+ _channels[channel].instrumentData[0] = *(curOffset + 0);
+ _channels[channel].instrumentData[1] = *(curOffset + 2);
+ _channels[channel].instrumentData[2] = *(curOffset + 9);
+ _channels[channel].instrumentData[3] = *(curOffset + 8);
+ _channels[channel].instrumentData[4] = *(curOffset + 4);
+ _channels[channel].instrumentData[5] = *(curOffset + 3);
+ _channels[channel].instrumentData[6] = 0;
+
+ setupChannel(channel, curOffset);
+
+ writeReg(0xA0 + channel, *(curOffset + 0));
+ writeReg(0xB0 + channel, *(curOffset + 1) & 0xDF);
+
+ _channels[channel].currentOffset += 15;
+ break;
+
+ case 2:
+ // NOTE DEFINITION
+ ++curOffset;
+ _channels[channel].state = 2;
+ noteOffOn(channel);
+ parseNote(channel, 0, curOffset);
+ parseNote(channel, 1, curOffset);
+ return;
+
+ case 0x80:
+ // LOOP
+ _channels[channel].currentOffset = _channels[channel].startOffset;
+ break;
+
+ default:
+ // START OF CHANNEL
+ // When we encounter a start of another channel while playback
+ // it means that the current channel is finished. Thus, we will
+ // stop it.
+ clearChannel(channel);
+ _channels[channel].state = 0;
+
+ // If no channel of the sound effect is playing anymore, unlock
+ // the resource.
+ channel /= 3;
+ if (!_channels[channel + 0].state
+ && !_channels[channel + 1].state
+ && !_channels[channel + 2].state) {
+ _vm->_res->unlock(rtSound, _sfxResource[channel]);
+ }
+ return;
+ }
+ }
+}
+
+void Player_AD::updateSlot(int channel) {
+ const byte *curOffset = _channels[channel].currentOffset + 1;
+
+ for (int num = 0; num <= 1; ++num, curOffset += 5) {
+ if (!(*curOffset & 0x80)) {
+ continue;
+ }
+
+ const int note = channel * 2 + num;
+ bool updateNote = false;
+
+ if (_notes[note].state == 2) {
+ if (!--_notes[note].sustainTimer) {
+ updateNote = true;
+ }
+ } else {
+ updateNote = processNoteEnvelope(note, _notes[note].instrumentValue);
+
+ if (_notes[note].bias) {
+ writeRegisterSpecial(note, _notes[note].bias - _notes[note].instrumentValue, *curOffset & 0x07);
+ } else {
+ writeRegisterSpecial(note, _notes[note].instrumentValue, *curOffset & 0x07);
+ }
+ }
+
+ if (updateNote) {
+ if (processNote(note, curOffset)) {
+ if (!(*curOffset & 0x08)) {
+ _channels[channel].currentOffset += 11;
+ _channels[channel].state = 1;
+ continue;
+ } else if (*curOffset & 0x10) {
+ noteOffOn(channel);
+ }
+
+ _notes[note].state = -1;
+ processNote(note, curOffset);
+ }
+ }
+
+ if ((*curOffset & 0x20) && !--_notes[note].playTime) {
+ _channels[channel].currentOffset += 11;
+ _channels[channel].state = 1;
+ }
+ }
+}
+
+void Player_AD::parseNote(int channel, int num, const byte *offset) {
+ if (num) {
+ offset += 5;
+ }
+
+ if (*offset & 0x80) {
+ const int note = channel * 2 + num;
+ _notes[note].state = -1;
+ processNote(note, offset);
+ _notes[note].playTime = 0;
+
+ if (*offset & 0x20) {
+ _notes[note].playTime = (*(offset + 4) >> 4) * 118;
+ _notes[note].playTime += (*(offset + 4) & 0x0F) * 8;
+ }
+ }
+}
+
+bool Player_AD::processNote(int note, const byte *offset) {
+ if (++_notes[note].state == 4) {
+ return true;
+ }
+
+ const int instrumentDataOffset = *offset & 0x07;
+ _notes[note].bias = _noteBiasTable[instrumentDataOffset];
+
+ uint8 instrumentDataValue = 0;
+ if (_notes[note].state == 0) {
+ instrumentDataValue = _channels[note / 2].instrumentData[instrumentDataOffset];
+ }
+
+ uint8 noteInstrumentValue = readRegisterSpecial(note, instrumentDataValue, instrumentDataOffset);
+ if (_notes[note].bias) {
+ noteInstrumentValue = _notes[note].bias - noteInstrumentValue;
+ }
+ _notes[note].instrumentValue = noteInstrumentValue;
+
+ if (_notes[note].state == 2) {
+ _notes[note].sustainTimer = _numStepsTable[*(offset + 3) >> 4];
+
+ if (*offset & 0x40) {
+ _notes[note].sustainTimer = (((getRnd() << 8) * _notes[note].sustainTimer) >> 16) + 1;
+ }
+ } else {
+ int timer1, timer2;
+ if (_notes[note].state == 3) {
+ timer1 = *(offset + 3) & 0x0F;
+ timer2 = 0;
+ } else {
+ timer1 = *(offset + _notes[note].state + 1) >> 4;
+ timer2 = *(offset + _notes[note].state + 1) & 0x0F;
+ }
+
+ int adjustValue = ((_noteAdjustTable[timer2] * _noteAdjustScaleTable[instrumentDataOffset]) >> 16) - noteInstrumentValue;
+ setupNoteEnvelopeState(note, _numStepsTable[timer1], adjustValue);
+ }
+
+ return false;
+}
+
+void Player_AD::noteOffOn(int channel) {
+ const uint8 regValue = readReg(0xB0 | channel);
+ writeReg(0xB0 | channel, regValue & 0xDF);
+ writeReg(0xB0 | channel, regValue | 0x20);
+}
+
+void Player_AD::writeRegisterSpecial(int note, uint8 value, int offset) {
+ if (offset == 6) {
+ return;
+ }
+
+ // Division by 2 extracts the channel number out of the note.
+ note /= 2;
+
+ uint8 regNum;
+ if (_useOperatorTable[offset]) {
+ regNum = _operatorOffsetTable[_channelOperatorOffsetTable[offset] + note * 2];
+ } else {
+ regNum = _channelOffsetTable[note];
+ }
+
+ regNum += _baseRegisterTable[offset];
+
+ uint8 regValue = readReg(regNum) & (~_registerMaskTable[offset]);
+ regValue |= value << _registerShiftTable[offset];
+
+ writeReg(regNum, regValue);
+}
+
+uint8 Player_AD::readRegisterSpecial(int note, uint8 defaultValue, int offset) {
+ if (offset == 6) {
+ return 0;
+ }
+
+ // Division by 2 extracts the channel number out of the note.
+ note /= 2;
+
+ uint8 regNum;
+ if (_useOperatorTable[offset]) {
+ regNum = _operatorOffsetTable[_channelOperatorOffsetTable[offset] + note * 2];
+ } else {
+ regNum = _channelOffsetTable[note];
+ }
+
+ regNum += _baseRegisterTable[offset];
+
+ uint8 regValue;
+ if (defaultValue) {
+ regValue = defaultValue;
+ } else {
+ regValue = readReg(regNum);
+ }
+
+ regValue &= _registerMaskTable[offset];
+ regValue >>= _registerShiftTable[offset];
+
+ return regValue;
+}
+
+void Player_AD::setupNoteEnvelopeState(int note, int steps, int adjust) {
+ _notes[note].preIncrease = 0;
+ if (ABS(adjust) > steps) {
+ _notes[note].preIncrease = 1;
+ _notes[note].adjust = adjust / steps;
+ _notes[note].envelope.stepIncrease = ABS(adjust % steps);
+ } else {
+ _notes[note].adjust = adjust;
+ _notes[note].envelope.stepIncrease = ABS(adjust);
+ }
+
+ _notes[note].envelope.step = steps;
+ _notes[note].envelope.stepCounter = 0;
+ _notes[note].envelope.timer = steps;
+}
+
+bool Player_AD::processNoteEnvelope(int note, int &instrumentValue) {
+ if (_notes[note].preIncrease) {
+ instrumentValue += _notes[note].adjust;
+ }
+
+ _notes[note].envelope.stepCounter += _notes[note].envelope.stepIncrease;
+ if (_notes[note].envelope.stepCounter >= _notes[note].envelope.step) {
+ _notes[note].envelope.stepCounter -= _notes[note].envelope.step;
+
+ if (_notes[note].adjust < 0) {
+ --instrumentValue;
+ } else {
+ ++instrumentValue;
+ }
+ }
+
+ if (--_notes[note].envelope.timer) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+uint8 Player_AD::getRnd() {
+ if (_rndSeed & 1) {
+ _rndSeed >>= 1;
+ _rndSeed ^= 0xB8;
+ } else {
+ _rndSeed >>= 1;
+ }
+
+ return _rndSeed;
+}
+
+const uint Player_AD::_noteBiasTable[7] = {
+ 0x00, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x00
+};
+
+const uint Player_AD::_numStepsTable[16] = {
+ 1, 4, 6, 8,
+ 10, 14, 18, 24,
+ 36, 64, 100, 160,
+ 240, 340, 600, 1200
+};
+
+const uint Player_AD::_noteAdjustScaleTable[7] = {
+ 255, 7, 63, 15, 63, 15, 63
+};
+
+const uint Player_AD::_noteAdjustTable[16] = {
+ 0, 4369, 8738, 13107,
+ 17476, 21845, 26214, 30583,
+ 34952, 39321, 43690, 48059,
+ 52428, 46797, 61166, 65535
+};
+
+const bool Player_AD::_useOperatorTable[7] = {
+ false, false, true, true, true, true, false
+};
+
+const uint Player_AD::_channelOffsetTable[11] = {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 8, 7
+};
+
+const uint Player_AD::_channelOperatorOffsetTable[7] = {
+ 0, 0, 1, 1, 0, 0, 0
+};
+
+const uint Player_AD::_baseRegisterTable[7] = {
+ 0xA0, 0xC0, 0x40, 0x20, 0x40, 0x20, 0x00
+};
+
+const uint Player_AD::_registerMaskTable[7] = {
+ 0xFF, 0x0E, 0x3F, 0x0F, 0x3F, 0x0F, 0x00
+};
+
+const uint Player_AD::_registerShiftTable[7] = {
+ 0, 1, 0, 0, 0, 0, 0
+};
+
+} // End of namespace Scumm
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
new file mode 100644
index 0000000000..fbb65fbe24
--- /dev/null
+++ b/engines/scumm/players/player_ad.h
@@ -0,0 +1,190 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 SCUMM_PLAYERS_PLAYER_AD_H
+#define SCUMM_PLAYERS_PLAYER_AD_H
+
+#include "scumm/music.h"
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+
+#include "common/mutex.h"
+
+namespace OPL {
+class OPL;
+}
+
+namespace Scumm {
+
+class ScummEngine;
+
+/**
+ * Sound output for v3/v4 AdLib data.
+ */
+class Player_AD : public MusicEngine, public Audio::AudioStream {
+public:
+ Player_AD(ScummEngine *scumm, Audio::Mixer *mixer);
+ virtual ~Player_AD();
+
+ // MusicEngine API
+ virtual void setMusicVolume(int vol);
+ virtual void startSound(int sound);
+ virtual void stopSound(int sound);
+ virtual void stopAllSounds();
+ virtual int getMusicTimer();
+ virtual int getSoundStatus(int sound) const;
+
+ virtual void saveLoadWithSerializer(Serializer *ser);
+
+ // AudioStream API
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+ virtual bool isStereo() const { return false; }
+ virtual bool endOfData() const { return false; }
+ virtual int getRate() const { return _rate; }
+
+private:
+ ScummEngine *const _vm;
+ Common::Mutex _mutex;
+ Audio::Mixer *const _mixer;
+ const int _rate;
+ Audio::SoundHandle _soundHandle;
+ void setupVolume();
+
+ OPL::OPL *_opl2;
+
+ int _samplesPerCallback;
+ int _samplesPerCallbackRemainder;
+ int _samplesTillCallback;
+ int _samplesTillCallbackRemainder;
+
+ int _soundPlaying;
+ int _engineMusicTimer;
+
+ // AdLib register utilities
+ uint8 _registerBackUpTable[256];
+ void writeReg(int r, int v);
+ uint8 readReg(int r) const;
+
+ // Instrument setup
+ void setupChannel(const uint channel, uint instrOffset) {
+ setupChannel(channel, _resource + instrOffset);
+ }
+ void setupChannel(const uint channel, const byte *instrOffset);
+ void setupOperator(const uint opr, const byte *&instrOffset);
+ static const int _operatorOffsetTable[18];
+
+ // Sound data
+ const byte *_resource;
+
+ // Music handling
+ void startMusic();
+ void updateMusic();
+ void noteOff(uint channel);
+ int findFreeChannel();
+ void setupFrequency(uint channel, int8 frequency);
+ void setupRhythm(uint rhythmInstr, uint instrOffset);
+
+ uint _timerLimit;
+ uint _musicTicks;
+ uint _musicTimer;
+ uint _internalMusicTimer;
+ bool _loopFlag;
+ uint _musicLoopStart;
+ uint _instrumentOffset[16];
+ uint _channelLastEvent[9];
+ uint _channelFrequency[9];
+ uint _channelB0Reg[9];
+
+ uint _mdvdrState;
+ uint _voiceChannels;
+
+ uint _curOffset;
+ uint _nextEventTimer;
+
+ static const uint _noteFrequencies[12];
+ static const uint _mdvdrTable[6];
+ static const uint _rhythmOperatorTable[6];
+ static const uint _rhythmChannelTable[6];
+
+ // SFX handling
+ void startSfx();
+ void updateSfx();
+ void clearChannel(int channel);
+ void updateChannel(int channel);
+ void parseSlot(int channel);
+ void updateSlot(int channel);
+ void parseNote(int channel, int num, const byte *offset);
+ bool processNote(int note, const byte *offset);
+ void noteOffOn(int channel);
+ void writeRegisterSpecial(int note, uint8 value, int offset);
+ uint8 readRegisterSpecial(int note, uint8 defaultValue, int offset);
+ void setupNoteEnvelopeState(int note, int steps, int adjust);
+ bool processNoteEnvelope(int note, int &instrumentValue);
+
+ int _sfxTimer;
+
+ int _sfxResource[3];
+ int _sfxPriority[3];
+
+ struct Channel {
+ int state;
+ const byte *currentOffset;
+ const byte *startOffset;
+ uint8 instrumentData[7];
+ } _channels[11];
+
+ uint8 _rndSeed;
+ uint8 getRnd();
+
+ struct Note {
+ int state;
+ int playTime;
+ int sustainTimer;
+ int instrumentValue;
+ int bias;
+ int preIncrease;
+ int adjust;
+
+ struct Envelope {
+ int stepIncrease;
+ int step;
+ int stepCounter;
+ int timer;
+ } envelope;
+ } _notes[22];
+
+ static const uint _noteBiasTable[7];
+ static const uint _numStepsTable[16];
+ static const uint _noteAdjustScaleTable[7];
+ static const uint _noteAdjustTable[16];
+ static const bool _useOperatorTable[7];
+ static const uint _channelOffsetTable[11];
+ static const uint _channelOperatorOffsetTable[7];
+ static const uint _baseRegisterTable[7];
+ static const uint _registerMaskTable[7];
+ static const uint _registerShiftTable[7];
+};
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/player_apple2.cpp b/engines/scumm/players/player_apple2.cpp
index 58e4f78a94..87b8100f22 100644
--- a/engines/scumm/player_apple2.cpp
+++ b/engines/scumm/players/player_apple2.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_apple2.h"
+#include "scumm/players/player_apple2.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_apple2.h b/engines/scumm/players/player_apple2.h
index e1ec9d8946..9930a4f95d 100644
--- a/engines/scumm/player_apple2.h
+++ b/engines/scumm/players/player_apple2.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_APPLEII_H
-#define SCUMM_PLAYER_APPLEII_H
+#ifndef SCUMM_PLAYERS_PLAYER_APPLEII_H
+#define SCUMM_PLAYERS_PLAYER_APPLEII_H
#include "common/mutex.h"
#include "common/scummsys.h"
diff --git a/engines/scumm/player_mac.cpp b/engines/scumm/players/player_mac.cpp
index c16c85bff3..281eec5336 100644
--- a/engines/scumm/player_mac.cpp
+++ b/engines/scumm/players/player_mac.cpp
@@ -24,7 +24,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
#include "scumm/imuse/imuse.h"
@@ -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_mac.h b/engines/scumm/players/player_mac.h
index 09307b4e57..7f9f42c34e 100644
--- a/engines/scumm/player_mac.h
+++ b/engines/scumm/players/player_mac.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_MAC_H
-#define SCUMM_PLAYER_MAC_H
+#ifndef SCUMM_PLAYERS_PLAYER_MAC_H
+#define SCUMM_PLAYERS_PLAYER_MAC_H
#include "common/scummsys.h"
#include "common/util.h"
diff --git a/engines/scumm/player_mod.cpp b/engines/scumm/players/player_mod.cpp
index 6411f0a17a..abaa8c1fc5 100644
--- a/engines/scumm/player_mod.cpp
+++ b/engines/scumm/players/player_mod.cpp
@@ -21,7 +21,7 @@
*/
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
#include "audio/mixer.h"
#include "audio/rate.h"
#include "audio/decoders/raw.h"
diff --git a/engines/scumm/player_mod.h b/engines/scumm/players/player_mod.h
index 619d83541d..d4a5b16fca 100644
--- a/engines/scumm/player_mod.h
+++ b/engines/scumm/players/player_mod.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_MOD_H
-#define SCUMM_PLAYER_MOD_H
+#ifndef SCUMM_PLAYERS_PLAYER_MOD_H
+#define SCUMM_PLAYERS_PLAYER_MOD_H
#include "scumm/scumm.h"
#include "audio/audiostream.h"
diff --git a/engines/scumm/player_nes.cpp b/engines/scumm/players/player_nes.cpp
index a6ffc9ed86..f55f1f9edd 100644
--- a/engines/scumm/player_nes.cpp
+++ b/engines/scumm/players/player_nes.cpp
@@ -23,7 +23,7 @@
#ifndef DISABLE_NES_APU
#include "engines/engine.h"
-#include "scumm/player_nes.h"
+#include "scumm/players/player_nes.h"
#include "scumm/scumm.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_nes.h b/engines/scumm/players/player_nes.h
index be1617e0f6..f0b3e79aad 100644
--- a/engines/scumm/player_nes.h
+++ b/engines/scumm/players/player_nes.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_NES_H
-#define SCUMM_PLAYER_NES_H
+#ifndef SCUMM_PLAYERS_PLAYER_NES_H
+#define SCUMM_PLAYERS_PLAYER_NES_H
#include "common/scummsys.h"
#include "scumm/music.h"
diff --git a/engines/scumm/player_pce.cpp b/engines/scumm/players/player_pce.cpp
index 8d886ee008..6d6e2fcde5 100644
--- a/engines/scumm/player_pce.cpp
+++ b/engines/scumm/players/player_pce.cpp
@@ -29,7 +29,7 @@
*/
#include <math.h>
-#include "player_pce.h"
+#include "scumm/players/player_pce.h"
#include "common/endian.h"
// PCE sound engine is only used by Loom, which requires 16bit color support
diff --git a/engines/scumm/player_pce.h b/engines/scumm/players/player_pce.h
index 427fb1ace6..ca2eddf58c 100644
--- a/engines/scumm/player_pce.h
+++ b/engines/scumm/players/player_pce.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_PCE_H
-#define SCUMM_PLAYER_PCE_H
+#ifndef SCUMM_PLAYERS_PLAYER_PCE_H
+#define SCUMM_PLAYERS_PLAYER_PCE_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/engines/scumm/player_sid.cpp b/engines/scumm/players/player_sid.cpp
index 7a609364e5..1b97ad16d4 100644
--- a/engines/scumm/player_sid.cpp
+++ b/engines/scumm/players/player_sid.cpp
@@ -23,7 +23,7 @@
#ifndef DISABLE_SID
#include "engines/engine.h"
-#include "scumm/player_sid.h"
+#include "scumm/players/player_sid.h"
#include "scumm/scumm.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_sid.h b/engines/scumm/players/player_sid.h
index 12e3573575..a48ec793cd 100644
--- a/engines/scumm/player_sid.h
+++ b/engines/scumm/players/player_sid.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_SID_H
-#define SCUMM_PLAYER_SID_H
+#ifndef SCUMM_PLAYERS_PLAYER_SID_H
+#define SCUMM_PLAYERS_PLAYER_SID_H
#include "common/mutex.h"
#include "common/scummsys.h"
diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/players/player_towns.cpp
index 33e3e40e39..acbdbc7fb6 100644
--- a/engines/scumm/player_towns.cpp
+++ b/engines/scumm/players/player_towns.cpp
@@ -22,7 +22,7 @@
#include "scumm/sound.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
namespace Scumm {
diff --git a/engines/scumm/player_towns.h b/engines/scumm/players/player_towns.h
index 5c76d7c6c7..2369b7da5f 100644
--- a/engines/scumm/player_towns.h
+++ b/engines/scumm/players/player_towns.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_TOWNS_H
-#define SCUMM_PLAYER_TOWNS_H
+#ifndef SCUMM_PLAYERS_PLAYER_TOWNS_H
+#define SCUMM_PLAYERS_PLAYER_TOWNS_H
#include "scumm/scumm.h"
#include "scumm/imuse/imuse.h"
diff --git a/engines/scumm/player_v1.cpp b/engines/scumm/players/player_v1.cpp
index 8e784e9866..0fa1ee9361 100644
--- a/engines/scumm/player_v1.cpp
+++ b/engines/scumm/players/player_v1.cpp
@@ -22,7 +22,7 @@
#include "engines/engine.h"
-#include "scumm/player_v1.h"
+#include "scumm/players/player_v1.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v1.h b/engines/scumm/players/player_v1.h
index 9e6063adc9..ccd24c39df 100644
--- a/engines/scumm/player_v1.h
+++ b/engines/scumm/players/player_v1.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V1_H
-#define SCUMM_PLAYER_V1_H
+#ifndef SCUMM_PLAYERS_PLAYER_V1_H
+#define SCUMM_PLAYERS_PLAYER_V1_H
-#include "scumm/player_v2.h"
+#include "scumm/players/player_v2.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2.cpp b/engines/scumm/players/player_v2.cpp
index 6910f5e0db..2429af2d8c 100644
--- a/engines/scumm/player_v2.cpp
+++ b/engines/scumm/players/player_v2.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2.h"
+#include "scumm/players/player_v2.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2.h b/engines/scumm/players/player_v2.h
index d932585b8e..33878ff08b 100644
--- a/engines/scumm/player_v2.h
+++ b/engines/scumm/players/player_v2.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V2_H
-#define SCUMM_PLAYER_V2_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2_H
+#define SCUMM_PLAYERS_PLAYER_V2_H
-#include "scumm/player_v2base.h"
+#include "scumm/players/player_v2base.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2a.cpp b/engines/scumm/players/player_v2a.cpp
index 07fc77b301..aeccb8b7cb 100644
--- a/engines/scumm/player_v2a.cpp
+++ b/engines/scumm/players/player_v2a.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_v2a.h"
+#include "scumm/players/player_v2a.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2a.h b/engines/scumm/players/player_v2a.h
index fe20b43846..12193635f2 100644
--- a/engines/scumm/player_v2a.h
+++ b/engines/scumm/players/player_v2a.h
@@ -20,12 +20,12 @@
*
*/
-#ifndef SCUMM_PLAYER_V2A_H
-#define SCUMM_PLAYER_V2A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2A_H
+#define SCUMM_PLAYERS_PLAYER_V2A_H
#include "common/scummsys.h"
#include "scumm/music.h"
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
class Mixer;
diff --git a/engines/scumm/player_v2base.cpp b/engines/scumm/players/player_v2base.cpp
index 0d3ad4b1b3..75f1518989 100644
--- a/engines/scumm/player_v2base.cpp
+++ b/engines/scumm/players/player_v2base.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2base.h"
+#include "scumm/players/player_v2base.h"
#include "scumm/scumm.h"
#define FREQ_HZ 236 // Don't change!
diff --git a/engines/scumm/player_v2base.h b/engines/scumm/players/player_v2base.h
index eb9ed941ca..32bde95ddc 100644
--- a/engines/scumm/player_v2base.h
+++ b/engines/scumm/players/player_v2base.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_V2BASE_H
-#define SCUMM_PLAYER_V2BASE_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2BASE_H
+#define SCUMM_PLAYERS_PLAYER_V2BASE_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/engines/scumm/player_v2cms.cpp b/engines/scumm/players/player_v2cms.cpp
index c1242e0645..8e903bf9d2 100644
--- a/engines/scumm/player_v2cms.cpp
+++ b/engines/scumm/players/player_v2cms.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2cms.h"
+#include "scumm/players/player_v2cms.h"
#include "scumm/scumm.h"
#include "audio/mididrv.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_v2cms.h b/engines/scumm/players/player_v2cms.h
index 905c7c141e..fe42720215 100644
--- a/engines/scumm/player_v2cms.h
+++ b/engines/scumm/players/player_v2cms.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V2CMS_H
-#define SCUMM_PLAYER_V2CMS_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2CMS_H
+#define SCUMM_PLAYERS_PLAYER_V2CMS_H
-#include "scumm/player_v2base.h" // for channel_data
+#include "scumm/players/player_v2base.h" // for channel_data
class CMSEmulator;
diff --git a/engines/scumm/player_v3a.cpp b/engines/scumm/players/player_v3a.cpp
index 472cd1252b..ca0eedc90a 100644
--- a/engines/scumm/player_v3a.cpp
+++ b/engines/scumm/players/player_v3a.cpp
@@ -22,7 +22,7 @@
#include "engines/engine.h"
-#include "scumm/player_v3a.h"
+#include "scumm/players/player_v3a.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v3a.h b/engines/scumm/players/player_v3a.h
index 9449664e9b..3f84a74e51 100644
--- a/engines/scumm/player_v3a.h
+++ b/engines/scumm/players/player_v3a.h
@@ -20,12 +20,12 @@
*
*/
-#ifndef SCUMM_PLAYER_V3A_H
-#define SCUMM_PLAYER_V3A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V3A_H
+#define SCUMM_PLAYERS_PLAYER_V3A_H
#include "common/scummsys.h"
#include "scumm/music.h"
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
class Mixer;
diff --git a/engines/scumm/player_v3m.cpp b/engines/scumm/players/player_v3m.cpp
index 0f222d84fe..e30e31aff9 100644
--- a/engines/scumm/player_v3m.cpp
+++ b/engines/scumm/players/player_v3m.cpp
@@ -91,7 +91,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_v3m.h"
+#include "scumm/players/player_v3m.h"
#include "scumm/scumm.h"
namespace Scumm {
@@ -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/player_v3m.h b/engines/scumm/players/player_v3m.h
index 359bab32a9..615d736035 100644
--- a/engines/scumm/player_v3m.h
+++ b/engines/scumm/players/player_v3m.h
@@ -20,14 +20,14 @@
*
*/
-#ifndef SCUMM_PLAYER_V3M_H
-#define SCUMM_PLAYER_V3M_H
+#ifndef SCUMM_PLAYERS_PLAYER_V3M_H
+#define SCUMM_PLAYERS_PLAYER_V3M_H
#include "common/scummsys.h"
#include "common/util.h"
#include "common/mutex.h"
#include "scumm/music.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/players/player_v4a.cpp
index e791736f0e..59f49625c3 100644
--- a/engines/scumm/player_v4a.cpp
+++ b/engines/scumm/players/player_v4a.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_v4a.h"
+#include "scumm/players/player_v4a.h"
#include "scumm/scumm.h"
#include "common/file.h"
diff --git a/engines/scumm/player_v4a.h b/engines/scumm/players/player_v4a.h
index d01c70f295..c8c7b63ed2 100644
--- a/engines/scumm/player_v4a.h
+++ b/engines/scumm/players/player_v4a.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_V4A_H
-#define SCUMM_PLAYER_V4A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V4A_H
+#define SCUMM_PLAYERS_PLAYER_V4A_H
#include "common/scummsys.h"
#include "common/util.h"
diff --git a/engines/scumm/player_v5m.cpp b/engines/scumm/players/player_v5m.cpp
index 500f3bbc40..77b6d52a3c 100644
--- a/engines/scumm/player_v5m.cpp
+++ b/engines/scumm/players/player_v5m.cpp
@@ -76,7 +76,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_v5m.h"
+#include "scumm/players/player_v5m.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v5m.h b/engines/scumm/players/player_v5m.h
index b2079ee331..e3a457f8af 100644
--- a/engines/scumm/player_v5m.h
+++ b/engines/scumm/players/player_v5m.h
@@ -20,14 +20,14 @@
*
*/
-#ifndef SCUMM_PLAYER_V5M_H
-#define SCUMM_PLAYER_V5M_H
+#ifndef SCUMM_PLAYERS_PLAYER_V5M_H
+#define SCUMM_PLAYERS_PLAYER_V5M_H
#include "common/scummsys.h"
#include "common/util.h"
#include "common/mutex.h"
#include "scumm/music.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 3453e53a18..5197e07819 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -30,7 +30,7 @@
#include "scumm/charset.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse/imuse.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/he/intern_he.h"
#include "scumm/object.h"
#include "scumm/resource.h"
@@ -634,100 +634,83 @@ bool ScummEngine::getSavegameName(int slot, Common::String &desc) {
return result;
}
-bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion) {
- SaveGameHeader hdr;
-
+namespace {
+bool loadAndCheckSaveGameHeader(Common::InSaveFile *in, int heversion, SaveGameHeader &hdr, Common::String *error = nullptr) {
if (!loadSaveGameHeader(in, hdr)) {
- desc = "Invalid savegame";
+ if (error) {
+ *error = "Invalid savegame";
+ }
return false;
}
- if (hdr.ver > CURRENT_VER)
+ if (hdr.ver > CURRENT_VER) {
hdr.ver = TO_LE_32(hdr.ver);
+ }
+
if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) {
- desc = "Invalid version";
+ if (error) {
+ *error = "Invalid version";
+ }
return false;
}
// We (deliberately) broke HE savegame compatibility at some point.
if (hdr.ver < VER(57) && heversion >= 60) {
- desc = "Unsupported version";
+ if (error) {
+ *error = "Unsupported version";
+ }
return false;
}
hdr.name[sizeof(hdr.name) - 1] = 0;
- desc = hdr.name;
return true;
}
+} // End of anonymous namespace
-Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int slot) {
- Common::SeekableReadStream *in;
+bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion) {
SaveGameHeader hdr;
- if (slot < 0)
- return 0;
-
- Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
- if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
- return 0;
- }
-
- if (!loadSaveGameHeader(in, hdr)) {
- delete in;
- return 0;
+ if (!loadAndCheckSaveGameHeader(in, heversion, hdr, &desc)) {
+ return false;
}
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(52)) {
- delete in;
- return 0;
- }
+ desc = hdr.name;
+ return true;
+}
- Graphics::Surface *thumb = 0;
- if (Graphics::checkThumbnailHeader(*in)) {
- thumb = Graphics::loadThumbnail(*in);
+bool ScummEngine::querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos) {
+ if (slot < 0) {
+ return false;
}
- delete in;
- return thumb;
-}
-
-bool ScummEngine::loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff) {
- Common::SeekableReadStream *in;
SaveGameHeader hdr;
+ const Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ Common::ScopedPtr<Common::SeekableReadStream> in(g_system->getSavefileManager()->openForLoading(filename));
- if (slot < 0)
- return 0;
-
- Common::String filename = makeSavegameName(target, slot, false);
- if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ if (!in) {
return false;
}
- if (!loadSaveGameHeader(in, hdr)) {
- delete in;
+ if (!loadAndCheckSaveGameHeader(in.get(), heversion, hdr)) {
return false;
}
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(56)) {
- delete in;
- return false;
- }
+ desc = hdr.name;
- if (!Graphics::skipThumbnail(*in)) {
- delete in;
- return false;
- }
+ if (hdr.ver > VER(52)) {
+ if (Graphics::checkThumbnailHeader(*in)) {
+ thumbnail = Graphics::loadThumbnail(*in);
+ }
- if (!loadInfos(in, stuff)) {
- delete in;
- return false;
+ if (hdr.ver > VER(57)) {
+ if (!loadInfos(in.get(), timeInfos)) {
+ return false;
+ }
+ } else {
+ timeInfos = nullptr;
+ }
}
- delete in;
return true;
}
@@ -781,7 +764,7 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos
return true;
}
-void ScummEngine::saveInfos(Common::WriteStream* file) {
+void ScummEngine::saveInfos(Common::WriteStream *file) {
SaveInfoSection section;
section.type = MKTAG('I','N','F','O');
section.version = INFOSECTION_VERSION;
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 7b2ff91ad3..c34be5816d 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 94
+#define CURRENT_VER 95
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 2d4c326b68..3da7000ae9 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -27,7 +27,7 @@
#include "scumm/scumm_v3.h"
#include "scumm/scumm_v5.h"
#include "scumm/sound.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/util.h"
#include "scumm/verbs.h"
diff --git a/engines/scumm/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 6aad52578d..ae80f306af 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Thu May 2 21:27:50 2013
+ This file was generated by the md5table tool on Fri Sep 27 05:44:12 2013
DO NOT EDIT MANUALLY!
*/
@@ -121,9 +121,11 @@ static const MD5Table md5table[] = {
{ "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformDOS },
{ "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "27b3a4224ad63d5b04627595c1c1a025", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformAmiga },
+ { "288fb75b24389733c29fa107fe8d44e8", "catalog", "HE CUP", "Preview", 10795148, Common::EN_USA, Common::kPlatformUnknown },
{ "28d24a33448fab6795850bc9f159a4a2", "atlantis", "FM-TOWNS", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
{ "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS },
{ "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
+ { "291fb06071e65897f755846611f5ad40", "ft", "", "7-Wolf", 19697, Common::RU_RUS, Common::kPlatformUnknown },
{ "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows },
@@ -238,7 +240,7 @@ static const MD5Table md5table[] = {
{ "53e94115b55dd51d4b8ff0871aa1df1e", "spyfox", "", "Demo", 20103, Common::EN_ANY, Common::kPlatformUnknown },
{ "54a936ad06161ff7bfefcb96200f7bff", "monkey", "VGA", "VGA Demo", 7617, Common::EN_ANY, Common::kPlatformAmiga },
{ "55518cd73cf9c6d23ea29c51ee06bdfe", "ft", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown },
- { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
+ { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "Akella", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "55f4e9402bec2bded383843123f37c5c", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
{ "56b5922751be7ffd771b38dda56b028b", "freddi", "HE 100", "", 34837, Common::NL_NLD, Common::kPlatformWii },
@@ -327,6 +329,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 },
@@ -342,6 +345,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 },
@@ -534,7 +538,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 },
@@ -582,6 +586,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.cpp b/engines/scumm/scumm.cpp
index 2a14673855..cc8665e450 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -45,25 +45,26 @@
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/smush/smush_mixer.h"
#include "scumm/smush/smush_player.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/insane/insane.h"
#include "scumm/he/animation_he.h"
#include "scumm/he/intern_he.h"
#include "scumm/he/logic_he.h"
#include "scumm/he/sound_he.h"
#include "scumm/object.h"
-#include "scumm/player_nes.h"
-#include "scumm/player_sid.h"
-#include "scumm/player_pce.h"
-#include "scumm/player_apple2.h"
-#include "scumm/player_v1.h"
-#include "scumm/player_v2.h"
-#include "scumm/player_v2cms.h"
-#include "scumm/player_v2a.h"
-#include "scumm/player_v3a.h"
-#include "scumm/player_v3m.h"
-#include "scumm/player_v4a.h"
-#include "scumm/player_v5m.h"
+#include "scumm/players/player_ad.h"
+#include "scumm/players/player_nes.h"
+#include "scumm/players/player_sid.h"
+#include "scumm/players/player_pce.h"
+#include "scumm/players/player_apple2.h"
+#include "scumm/players/player_v1.h"
+#include "scumm/players/player_v2.h"
+#include "scumm/players/player_v2cms.h"
+#include "scumm/players/player_v2a.h"
+#include "scumm/players/player_v3a.h"
+#include "scumm/players/player_v3m.h"
+#include "scumm/players/player_v4a.h"
+#include "scumm/players/player_v5m.h"
#include "scumm/resource.h"
#include "scumm/he/resource_he.h"
#include "scumm/scumm_v0.h"
@@ -1841,6 +1842,15 @@ void ScummEngine::setupMusic(int midi) {
_musicEngine = _townsPlayer = new Player_Towns_v1(this, _mixer);
if (!_townsPlayer->init())
error("Failed to initialize FM-Towns audio driver");
+ } else if (_game.platform == Common::kPlatformDOS && (_sound->_musicType == MDT_ADLIB) && (_game.id == GID_LOOM || _game.id == GID_INDY3)) {
+ // For Indy3 DOS and Loom DOS we use an implementation of the original
+ // AD player when AdLib is selected. This fixes sound effects in those
+ // games (see for example bug #2027877 "INDY3: Non-Looping Sound
+ // Effects"). The player itself is also used in Monkey Island DOS
+ // EGA/VGA. However, we support multi MIDI for that game and we cannot
+ // support this with the Player_AD code at the moment. The reason here
+ // is that multi MIDI is supported internally by our iMuse output.
+ _musicEngine = new Player_AD(this, _mixer);
} else if (_game.version >= 3 && _game.heversion <= 62) {
MidiDriver *nativeMidiDriver = 0;
MidiDriver *adlibMidiDriver = 0;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index a77c1c0141..f192a1e256 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,
@@ -619,15 +620,10 @@ public:
// thumbnail + info stuff
public:
- Graphics::Surface *loadThumbnailFromSlot(int slot) {
- return loadThumbnailFromSlot(_targetName.c_str(), slot);
- }
- static Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot);
-
- static bool loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff);
+ static bool querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos);
protected:
- void saveInfos(Common::WriteStream* file);
+ void saveInfos(Common::WriteStream *file);
static bool loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff);
protected:
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 3f6290f8fc..071805752b 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -30,7 +30,7 @@
#include "scumm/file.h"
#include "scumm/imuse/imuse.h"
#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
#include "scumm/sound.h"
@@ -470,8 +470,10 @@ static int compareMP3OffsetTable(const void *a, const void *b) {
void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle *handle) {
int num = 0, i;
- int size = 0;
int id = -1;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
+ int size = 0;
+#endif
Common::ScopedPtr<ScummFile> file;
if (_vm->_game.id == GID_CMI) {
@@ -562,10 +564,14 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
num = result->num_tags;
}
offset = result->new_offset;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
size = result->compressed_size;
+#endif
} else {
offset += 8;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
size = -1;
+#endif
}
file.reset(new ScummFile());
@@ -1930,7 +1936,6 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
// 8 bytes MTrk header
// 7 bytes MIDI tempo sysex
// + some default instruments
- byte *ptr;
if (_game.features & GF_OLD_BUNDLE) {
ad_size -= 4;
_fileHandle->seek(ad_offs + 4, SEEK_SET);
@@ -1938,10 +1943,17 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
ad_size -= 6;
_fileHandle->seek(ad_offs, SEEK_SET);
}
- ptr = (byte *) calloc(ad_size, 1);
- _fileHandle->read(ptr, ad_size);
- convertADResource(_res, _game, idx, ptr, ad_size);
- free(ptr);
+ // For games using AD except Indy3 and Loom we are using our iMuse
+ // implementation. See output initialization in
+ // ScummEngine::setupMusic for more information.
+ if (_game.id != GID_INDY3 && _game.id != GID_LOOM) {
+ byte *ptr = (byte *)calloc(ad_size, 1);
+ _fileHandle->read(ptr, ad_size);
+ convertADResource(_res, _game, idx, ptr, ad_size);
+ free(ptr);
+ } else {
+ _fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size);
+ }
return 1;
} else if (ro_offs != 0) {
_fileHandle->seek(ro_offs - 2, SEEK_SET);
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/sky/POTFILES b/engines/sky/POTFILES
new file mode 100644
index 0000000000..6c39f82e75
--- /dev/null
+++ b/engines/sky/POTFILES
@@ -0,0 +1,2 @@
+engines/sky/compact.cpp
+engines/sky/detection.cpp
diff --git a/engines/sky/configure.engine b/engines/sky/configure.engine
new file mode 100644
index 0000000000..32b84849cb
--- /dev/null
+++ b/engines/sky/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sky "Beneath a Steel Sky" yes
diff --git a/engines/sky/music/musicbase.cpp b/engines/sky/music/musicbase.cpp
index b388afdb13..944edb1fdc 100644
--- a/engines/sky/music/musicbase.cpp
+++ b/engines/sky/music/musicbase.cpp
@@ -44,9 +44,9 @@ MusicBase::~MusicBase() {
}
void MusicBase::loadSection(uint8 pSection) {
- Common::StackLock lock(_mutex);
if (_currentMusic)
stopMusicInternal();
+ Common::StackLock lock(_mutex);
free(_musicData);
_currentSection = pSection;
_musicData = _skyDisk->loadFile(_driverFileBase + FILES_PER_SECTION * pSection);
@@ -70,13 +70,14 @@ bool MusicBase::musicIsPlaying() {
}
void MusicBase::stopMusic() {
- Common::StackLock lock(_mutex);
stopMusicInternal();
}
void MusicBase::stopMusicInternal() {
_mixer->stopHandle(_musicHandle);
+ Common::StackLock lock(_mutex);
+
for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++)
delete _channels[cnt];
_numberOfChannels = 0;
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index fd90015aa3..4c47dfafc7 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -187,9 +187,14 @@ Common::Error SkyEngine::go() {
}
if (!shouldQuit()) {
- _skyLogic->initScreen0();
+ // restartGame() takes us to the first scene, without showing the
+ // initial animation where Foster is being chased. initScreen0()
+ // shows the first scene together with that animation. We can't
+ // call both, as they both load the same scene.
if (introSkipped)
_skyControl->restartGame();
+ else
+ _skyLogic->initScreen0();
}
}
diff --git a/engines/sword1/POTFILES b/engines/sword1/POTFILES
new file mode 100644
index 0000000000..849bef9060
--- /dev/null
+++ b/engines/sword1/POTFILES
@@ -0,0 +1,4 @@
+engines/sword1/animation.cpp
+engines/sword1/control.cpp
+engines/sword1/logic.cpp
+engines/sword1/sword1.cpp
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 206bd68b07..742aac1a53 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -37,7 +37,14 @@
#include "gui/message.h"
+#ifdef USE_MPEG2
+#include "video/avi_decoder.h"
+#endif
+
+#ifdef USE_ZLIB
#include "video/dxa_decoder.h"
+#endif
+
#include "video/psx_decoder.h"
#include "video/smk_decoder.h"
@@ -176,27 +183,26 @@ bool MoviePlayer::load(uint32 id) {
break;
case kVideoDecoderPSX:
filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]);
+ break;
+ case kVideoDecoderMP2:
+ filename = Common::String::format("%s.mp2", sequenceList[id]);
+ break;
+ }
- // Need to switch to true color
+ // Need to switch to true color for PSX/MP2 videos
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0);
- // Need to load here in case it fails in which case we'd need
- // to go back to paletted mode
- if (_decoder->loadFile(filename)) {
- _decoder->start();
- return true;
- } else {
+ if (!_decoder->loadFile(filename)) {
+ // Go back to 8bpp color
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
initGraphics(g_system->getWidth(), g_system->getHeight(), true);
- return false;
- }
- break;
- }
- if (!_decoder->loadFile(filename))
return false;
+ }
- // For DXA, also add the external sound file
- if (_decoderType == kVideoDecoderDXA)
+ // For DXA/MP2, also add the external sound file
+ if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2)
_decoder->addStreamFileTrack(sequenceList[id]);
_decoder->start();
@@ -224,9 +230,9 @@ void MoviePlayer::play() {
}
void MoviePlayer::performPostProcessing(byte *screen) {
- // TODO: We don't support the PSX stream videos yet
+ // TODO: We don't support displaying these in true color yet,
// nor using the PSX fonts to display subtitles.
- if (_vm->isPsx())
+ if (_vm->isPsx() || _decoderType == kVideoDecoderMP2)
return;
if (!_movieTexts.empty()) {
@@ -308,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()) {
@@ -401,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();
}
@@ -414,20 +420,19 @@ bool MoviePlayer::playVideo() {
_vm->_system->delayMillis(10);
}
- if (_decoderType == kVideoDecoderPSX) {
- // Need to jump back to paletted color
+ // Need to jump back to paletted color
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
initGraphics(g_system->getWidth(), g_system->getHeight(), true);
- }
return !_vm->shouldQuit() && !skipped;
}
uint32 MoviePlayer::getBlackColor() {
- return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
+ return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
}
uint32 MoviePlayer::findTextColor() {
- if (_decoderType == kVideoDecoderPSX) {
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) {
// We're in true color mode, so return the actual colors
switch (_textColor) {
case 1:
@@ -493,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();
}
@@ -547,9 +552,16 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *
filename = Common::String::format("%s.mp2", sequenceList[id]);
if (Common::File::exists(filename)) {
- GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK"));
+#ifdef USE_MPEG2
+ // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video
+ // to be played back at 12fps.
+ Video::VideoDecoder *aviDecoder = new Video::AVIDecoder(12);
+ return new MoviePlayer(vm, textMan, resMan, system, aviDecoder, kVideoDecoderMP2);
+#else
+ GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"), _("OK"));
dialog.runModal();
return 0;
+#endif
}
if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) {
diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h
index d0c61f5eb3..2c51a74f71 100644
--- a/engines/sword1/animation.h
+++ b/engines/sword1/animation.h
@@ -41,7 +41,8 @@ namespace Sword1 {
enum DecoderType {
kVideoDecoderDXA = 0,
kVideoDecoderSMK = 1,
- kVideoDecoderPSX = 2
+ kVideoDecoderPSX = 2,
+ kVideoDecoderMP2 = 3
};
class MovieText {
diff --git a/engines/sword1/configure.engine b/engines/sword1/configure.engine
new file mode 100644
index 0000000000..0578d176a9
--- /dev/null
+++ b/engines/sword1/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword1 "Broken Sword" yes
diff --git a/engines/sword1/music.cpp b/engines/sword1/music.cpp
index c34630aceb..f31faffd5e 100644
--- a/engines/sword1/music.cpp
+++ b/engines/sword1/music.cpp
@@ -110,7 +110,7 @@ bool MusicHandle::play(const Common::String &filename, bool loop) {
return true;
}
-bool MusicHandle::playPSX(uint16 id) {
+bool MusicHandle::playPSX(uint16 id, bool loop) {
stop();
if (!_file.isOpen())
@@ -131,7 +131,7 @@ bool MusicHandle::playPSX(uint16 id) {
// not over file size
if ((size != 0) && (size != 0xffffffff) && ((int32)(offset + size) <= _file.size())) {
_file.seek(offset, SEEK_SET);
- _audioSource = Audio::makeXAStream(_file.readStream(size), 11025);
+ _audioSource = Audio::makeLoopingAudioStream(Audio::makeXAStream(_file.readStream(size), 11025), loop ? 0 : 1);
fadeUp();
} else {
_audioSource = NULL;
@@ -297,7 +297,7 @@ void Music::startMusic(int32 tuneId, int32 loopFlag) {
the mutex before, to have the soundthread playing normally.
As the corresponding _converter is NULL, the handle will be ignored by the playing thread */
if (SwordEngine::isPsx()) {
- if (_handles[newStream].playPSX(tuneId)) {
+ if (_handles[newStream].playPSX(tuneId, loopFlag != 0)) {
_mutex.lock();
_converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), false);
_mutex.unlock();
diff --git a/engines/sword1/music.h b/engines/sword1/music.h
index f1366202d7..4207019c13 100644
--- a/engines/sword1/music.h
+++ b/engines/sword1/music.h
@@ -44,7 +44,7 @@ public:
MusicHandle() : _fading(0), _audioSource(NULL) {}
virtual int readBuffer(int16 *buffer, const int numSamples);
bool play(const Common::String &filename, bool loop);
- bool playPSX(uint16 id);
+ bool playPSX(uint16 id, bool loop);
void stop();
void fadeUp();
void fadeDown();
diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp
index ae128b8c05..76957e0a70 100644
--- a/engines/sword1/screen.cpp
+++ b/engines/sword1/screen.cpp
@@ -57,6 +57,30 @@ Screen::Screen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) {
_psxCache.extPlxCache = NULL;
_oldScrollX = 0;
_oldScrollY = 0;
+
+ _textMan = 0;
+
+ for (int i = 0; i < 4; i++)
+ _layerGrid[i] = 0;
+
+ for (int i = 0; i < 4; i++)
+ _layerBlocks[i] = 0;
+
+ _parallax[0] = 0;
+ _parallax[1] = 0;
+
+ _fullRefresh = 0;
+
+ for (int i = 0; i < MAX_SORT; i++) {
+ _sortList[i].id = 0;
+ _sortList[i].y = 0;
+ }
+ _scrnSizeX = 0;
+ _scrnSizeY = 0;
+ _gridSizeX = 0;
+ _gridSizeY = 0;
+ _fadingDirection = 0;
+ _isBlack = 0;
}
Screen::~Screen() {
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index 268da74508..643657c71f 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -269,9 +269,8 @@ void Sound::playSample(QueueElement *elem) {
uint8 volume = (volR + volL) / 2;
if (SwordEngine::isPsx()) {
- // We ignore FX_LOOP as XA has its own looping mechanism
uint32 size = READ_LE_UINT32(sampleData);
- Audio::AudioStream *audStream = Audio::makeXAStream(new Common::MemoryReadStream(sampleData + 4, size - 4), 11025);
+ Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(Audio::makeXAStream(new Common::MemoryReadStream(sampleData + 4, size - 4), 11025), (_fxList[elem->id].type == FX_LOOP) ? 0 : 1);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &elem->handle, audStream, elem->id, volume, pan);
} else {
uint32 size = READ_LE_UINT32(sampleData + 0x28);
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 2d5452778d..5738431dce 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -67,6 +67,17 @@ SwordEngine::SwordEngine(OSystem *syst)
SearchMan.addSubDirectoryMatching(gameDataDir, "italian"); // PSX Demo
_console = new SwordConsole(this);
+
+ _mouseState = 0;
+ _resMan = 0;
+ _objectMan = 0;
+ _screen = 0;
+ _mouse = 0;
+ _logic = 0;
+ _sound = 0;
+ _menu = 0;
+ _music = 0;
+ _control = 0;
}
SwordEngine::~SwordEngine() {
diff --git a/engines/sword2/POTFILES b/engines/sword2/POTFILES
new file mode 100644
index 0000000000..94ad720989
--- /dev/null
+++ b/engines/sword2/POTFILES
@@ -0,0 +1,2 @@
+engines/sword2/animation.cpp
+engines/sword2/sword2.cpp
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 00260f789a..92fa9d0e44 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -42,7 +42,14 @@
#include "gui/message.h"
+#ifdef USE_MPEG2
+#include "video/avi_decoder.h"
+#endif
+
+#ifdef USE_ZLIB
#include "video/dxa_decoder.h"
+#endif
+
#include "video/smk_decoder.h"
#include "video/psx_decoder.h"
@@ -88,26 +95,26 @@ bool MoviePlayer::load(const char *name) {
break;
case kVideoDecoderPSX:
filename = Common::String::format("%s.str", name);
+ break;
+ case kVideoDecoderMP2:
+ filename = Common::String::format("%s.mp2", name);
+ break;
+ }
- // Need to switch to true color
- initGraphics(640, 480, true, 0);
+ // Need to switch to true color for PSX/MP2 videos
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0);
- // Need to load here in case it fails in which case we'd need
- // to go back to paletted mode
- if (_decoder->loadFile(filename)) {
- _decoder->start();
- return true;
- } else {
- initGraphics(640, 480, true);
- return false;
- }
- }
+ if (!_decoder->loadFile(filename)) {
+ // Go back to 8bpp color
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true);
- if (!_decoder->loadFile(filename))
return false;
+ }
- // For DXA, also add the external sound file
- if (_decoderType == kVideoDecoderDXA)
+ // For DXA/MP2, also add the external sound file
+ if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2)
_decoder->addStreamFileTrack(name);
_decoder->start();
@@ -136,10 +143,9 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
_vm->_sound->stopSpeech();
}
- if (_decoderType == kVideoDecoderPSX) {
- // Need to jump back to paletted color
+ // Need to jump back to paletted color
+ if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2)
initGraphics(640, 480, true);
- }
}
void MoviePlayer::openTextObject(uint32 index) {
@@ -328,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()) {
@@ -378,11 +384,11 @@ bool MoviePlayer::playVideo() {
}
uint32 MoviePlayer::getBlackColor() {
- return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
+ return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
}
uint32 MoviePlayer::getWhiteColor() {
- return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white;
+ return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white;
}
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
@@ -397,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();
}
@@ -446,9 +452,16 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, OSystem *system
filename = Common::String::format("%s.mp2", name);
if (Common::File::exists(filename)) {
- GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK"));
+#ifdef USE_MPEG2
+ // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video
+ // to be played back at 12fps.
+ Video::AVIDecoder *aviDecoder = new Video::AVIDecoder(12);
+ return new MoviePlayer(vm, system, aviDecoder, kVideoDecoderMP2);
+#else
+ GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2 support"), _("OK"));
dialog.runModal();
return NULL;
+#endif
}
// The demo tries to play some cutscenes that aren't there, so make those warnings more discreet.
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index b2a243b2ca..8669bdc8d8 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -40,7 +40,8 @@ namespace Sword2 {
enum DecoderType {
kVideoDecoderDXA = 0,
kVideoDecoderSMK = 1,
- kVideoDecoderPSX = 2
+ kVideoDecoderPSX = 2,
+ kVideoDecoderMP2 = 3
};
struct MovieText {
diff --git a/engines/sword2/configure.engine b/engines/sword2/configure.engine
new file mode 100644
index 0000000000..7153605433
--- /dev/null
+++ b/engines/sword2/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword2 "Broken Sword II" yes
diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine
new file mode 100644
index 0000000000..1729bbeb33
--- /dev/null
+++ b/engines/sword25/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
diff --git a/engines/sword25/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/animation.cpp b/engines/sword25/gfx/animation.cpp
index 1660c393c0..37207c967b 100644
--- a/engines/sword25/gfx/animation.cpp
+++ b/engines/sword25/gfx/animation.cpp
@@ -553,15 +553,15 @@ bool Animation::persist(OutputPersistenceBlock &writer) {
writer.write(_currentFrameTime);
writer.write(_running);
writer.write(_finished);
- writer.write(static_cast<uint>(_direction));
+ writer.write(static_cast<uint32>(_direction));
// Je nach Animationstyp entweder das Template oder die Ressource speichern.
if (_animationResourcePtr) {
- uint marker = 0;
+ uint32 marker = 0;
writer.write(marker);
writer.writeString(_animationResourcePtr->getFileName());
} else if (_animationTemplateHandle) {
- uint marker = 1;
+ uint32 marker = 1;
writer.write(marker);
writer.write(_animationTemplateHandle);
} else {
@@ -574,13 +574,13 @@ bool Animation::persist(OutputPersistenceBlock &writer) {
// The following is only there to for compatibility with older saves
// resp. the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaLoopPointCB");
writer.write(getHandle());
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaActionCB");
writer.write(getHandle());
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaDeleteCB");
writer.write(getHandle());
@@ -605,12 +605,12 @@ bool Animation::unpersist(InputPersistenceBlock &reader) {
reader.read(_currentFrameTime);
reader.read(_running);
reader.read(_finished);
- uint direction;
+ uint32 direction;
reader.read(direction);
_direction = static_cast<Direction>(direction);
// Animationstyp einlesen.
- uint marker;
+ uint32 marker;
reader.read(marker);
if (marker == 0) {
Common::String resourceFilename;
@@ -629,9 +629,9 @@ bool Animation::unpersist(InputPersistenceBlock &reader) {
// The following is only there to for compatibility with older saves
// resp. the original engine.
- uint callbackCount;
+ uint32 callbackCount;
Common::String callbackFunctionName;
- uint callbackData;
+ uint32 callbackData;
// loop point callback
reader.read(callbackCount);
diff --git a/engines/sword25/gfx/animation.h b/engines/sword25/gfx/animation.h
index 44255e3b64..ced1995ae9 100644
--- a/engines/sword25/gfx/animation.h
+++ b/engines/sword25/gfx/animation.h
@@ -159,18 +159,18 @@ private:
BACKWARD
};
- int _relX;
- int _relY;
+ int32 _relX;
+ int32 _relY;
float _scaleFactorX;
float _scaleFactorY;
- uint _modulationColor;
- uint _currentFrame;
- int _currentFrameTime;
+ uint32 _modulationColor;
+ uint32 _currentFrame;
+ int32 _currentFrameTime;
bool _running;
bool _finished;
Direction _direction;
AnimationResource *_animationResourcePtr;
- uint _animationTemplateHandle;
+ uint32 _animationTemplateHandle;
bool _framesLocked;
ANIMATION_CALLBACK _loopPointCallback;
diff --git a/engines/sword25/gfx/animationdescription.cpp b/engines/sword25/gfx/animationdescription.cpp
index da0a660df9..164206bbc2 100644
--- a/engines/sword25/gfx/animationdescription.cpp
+++ b/engines/sword25/gfx/animationdescription.cpp
@@ -36,7 +36,7 @@
namespace Sword25 {
bool AnimationDescription::persist(OutputPersistenceBlock &writer) {
- writer.write(static_cast<uint>(_animationType));
+ writer.write(static_cast<uint32>(_animationType));
writer.write(_FPS);
writer.write(_millisPerFrame);
writer.write(_scalingAllowed);
@@ -47,7 +47,7 @@ bool AnimationDescription::persist(OutputPersistenceBlock &writer) {
}
bool AnimationDescription::unpersist(InputPersistenceBlock &reader) {
- uint animationType;
+ uint32 animationType;
reader.read(animationType);
_animationType = static_cast<Animation::ANIMATION_TYPES>(animationType);
reader.read(_FPS);
diff --git a/engines/sword25/gfx/animationdescription.h b/engines/sword25/gfx/animationdescription.h
index 3b11686bb9..009d83dcc7 100644
--- a/engines/sword25/gfx/animationdescription.h
+++ b/engines/sword25/gfx/animationdescription.h
@@ -52,8 +52,8 @@ protected:
public:
struct Frame {
// Die Hotspot-Angabe bezieht sich auf das ungeflippte Bild!!
- int hotspotX;
- int hotspotY;
+ int32 hotspotX;
+ int32 hotspotY;
bool flipV;
bool flipH;
Common::String fileName;
@@ -88,8 +88,8 @@ public:
protected:
Animation::ANIMATION_TYPES _animationType;
- int _FPS;
- int _millisPerFrame;
+ int32 _FPS;
+ int32 _millisPerFrame;
bool _scalingAllowed;
bool _alphaAllowed;
bool _colorModulationAllowed;
diff --git a/engines/sword25/gfx/animationresource.cpp b/engines/sword25/gfx/animationresource.cpp
index 621e20ad8c..8c09a545a0 100644
--- a/engines/sword25/gfx/animationresource.cpp
+++ b/engines/sword25/gfx/animationresource.cpp
@@ -188,7 +188,7 @@ bool AnimationResource::parserCallback_frame(ParserNode *node) {
Common::String flipHString = node->values["fliph"];
if (!flipHString.empty()) {
- if (!parseBooleanKey(flipVString, frame.flipV)) {
+ if (!parseBooleanKey(flipHString, frame.flipH)) {
warning("Illegal fliph value (\"%s\") in <frame> tag in \"%s\". Assuming default (\"false\").",
flipHString.c_str(), getFileName().c_str());
frame.flipH = false;
diff --git a/engines/sword25/gfx/animationtemplate.cpp b/engines/sword25/gfx/animationtemplate.cpp
index 19924302b9..a1d2bf5d1a 100644
--- a/engines/sword25/gfx/animationtemplate.cpp
+++ b/engines/sword25/gfx/animationtemplate.cpp
@@ -181,7 +181,7 @@ bool AnimationTemplate::persist(OutputPersistenceBlock &writer) {
Result &= AnimationDescription::persist(writer);
// Frameanzahl schreiben.
- writer.write(_frames.size());
+ writer.write((uint32)_frames.size());
// Frames einzeln persistieren.
Common::Array<const Frame>::const_iterator Iter = _frames.begin();
@@ -209,7 +209,7 @@ bool AnimationTemplate::unpersist(InputPersistenceBlock &reader) {
result &= AnimationDescription::unpersist(reader);
// Frameanzahl lesen.
- uint frameCount;
+ uint32 frameCount;
reader.read(frameCount);
// Frames einzeln wieder herstellen.
diff --git a/engines/sword25/gfx/animationtemplateregistry.cpp b/engines/sword25/gfx/animationtemplateregistry.cpp
index 8184b49eba..4cefe24b18 100644
--- a/engines/sword25/gfx/animationtemplateregistry.cpp
+++ b/engines/sword25/gfx/animationtemplateregistry.cpp
@@ -47,7 +47,7 @@ bool AnimationTemplateRegistry::persist(OutputPersistenceBlock &writer) {
writer.write(_nextHandle);
// Anzahl an BS_AnimationTemplates schreiben.
- writer.write(_handle2PtrMap.size());
+ writer.write((uint32)_handle2PtrMap.size());
// Alle BS_AnimationTemplates persistieren.
HANDLE2PTR_MAP::const_iterator iter = _handle2PtrMap.begin();
@@ -77,13 +77,13 @@ bool AnimationTemplateRegistry::unpersist(InputPersistenceBlock &reader) {
delete _handle2PtrMap.begin()->_value;
// Anzahl an BS_AnimationTemplates einlesen.
- uint animationTemplateCount;
+ uint32 animationTemplateCount;
reader.read(animationTemplateCount);
// Alle gespeicherten BS_AnimationTemplates wieder herstellen.
for (uint i = 0; i < animationTemplateCount; ++i) {
// Handle lesen.
- uint handle;
+ uint32 handle;
reader.read(handle);
// BS_AnimationTemplate wieder herstellen.
diff --git a/engines/sword25/gfx/bitmap.h b/engines/sword25/gfx/bitmap.h
index caa1238558..f22c5d7fc9 100644
--- a/engines/sword25/gfx/bitmap.h
+++ b/engines/sword25/gfx/bitmap.h
@@ -176,9 +176,9 @@ protected:
bool _flipV;
float _scaleFactorX;
float _scaleFactorY;
- uint _modulationColor;
- int _originalWidth;
- int _originalHeight;
+ uint32 _modulationColor;
+ int32 _originalWidth;
+ int32 _originalHeight;
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/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/art.cpp b/engines/sword25/gfx/image/art.cpp
index 9c4b9fe8bd..e2eeaca33f 100644
--- a/engines/sword25/gfx/image/art.cpp
+++ b/engines/sword25/gfx/image/art.cpp
@@ -424,8 +424,7 @@ static void art_vpath_render_bez(ArtVpath **p_vpath, int *pn, int *pn_max,
x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness);
} else {
// don't subdivide
- art_vpath_add_point(p_vpath, pn, pn_max,
- ART_LINETO, x3, y3);
+ art_vpath_add_point(p_vpath, pn, pn_max, ART_LINETO, x3, y3);
}
}
diff --git a/engines/sword25/gfx/image/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 c8a6666046..b359fc6a3e 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -41,6 +41,7 @@
#include "sword25/gfx/renderobjectmanager.h"
#include "common/system.h"
+#include "graphics/thumbnail.h"
namespace Sword25 {
@@ -239,25 +240,13 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
int cg = (color >> 8) & 0xff;
int cb = (color >> 0) & 0xff;
- // Compensate for transparency. Since we're coming
- // down to 255 alpha, we just compensate for the colors here
- if (ca != 255) {
- cr = cr * ca >> 8;
- cg = cg * ca >> 8;
- cb = cb * ca >> 8;
- }
-
// Create an encapsulating surface for the data
Graphics::Surface srcImage;
// TODO: Is the data really in the screen format?
- 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;
@@ -286,14 +275,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;
@@ -305,7 +294,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;
@@ -314,13 +303,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) {
@@ -329,14 +318,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);
@@ -350,7 +339,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++) {
@@ -360,7 +349,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;
}
@@ -370,11 +359,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)
@@ -403,52 +392,52 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
} else {
#if defined(SCUMM_LITTLE_ENDIAN)
pix = *(uint32 *)out;
- int outb = (pix >> 0) & 0xff;
- int outg = (pix >> 8) & 0xff;
- int outr = (pix >> 16) & 0xff;
+ int outb = ((pix >> 0) & 0xff) * (255 - a);
+ int outg = ((pix >> 8) & 0xff) * (255 - a);
+ int outr = ((pix >> 16) & 0xff) * (255 - a);
if (cb == 0)
- outb = 0;
+ outb = outb >> 8;
else if (cb != 255)
- outb += ((b - outb) * a * cb) >> 16;
+ outb = ((outb << 8) + b * a * cb) >> 16;
else
- outb += ((b - outb) * a) >> 8;
+ outb = (outb + b * a) >> 8;
if (cg == 0)
- outg = 0;
+ outg = outg >> 8;
else if (cg != 255)
- outg += ((g - outg) * a * cg) >> 16;
+ outg = ((outg << 8) + g * a * cg) >> 16;
else
- outg += ((g - outg) * a) >> 8;
+ outg = (outg + g * a) >> 8;
if (cr == 0)
- outr = 0;
+ outr = outr >> 8;
else if (cr != 255)
- outr += ((r - outr) * a * cr) >> 16;
+ outr = ((outr << 8) + r * a * cr) >> 16;
else
- outr += ((r - outr) * a) >> 8;
+ outr = (outr + r * a) >> 8;
*(uint32 *)out = (255 << 24) | (outr << 16) | (outg << 8) | outb;
out += 4;
#else
*out = 255;
out++;
if (cr == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cr != 255)
- *out += ((r - *out) * a * cr) >> 16;
+ *out = (((*out * (255-a)) << 8) + r * a * cr) >> 16;
else
- *out += ((r - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + r * a) >> 8;
out++;
if (cg == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cg != 255)
- *out += ((g - *out) * a * cg) >> 16;
+ *out = (((*out * (255-a)) << 8) + g * a * cg) >> 16;
else
- *out += ((g - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + g * a) >> 8;
out++;
if (cb == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cb != 255)
- *out += ((b - *out) * a * cb) >> 16;
+ *out = (((*out * (255-a)) << 8) + b * a * cb) >> 16;
else
- *out += ((b - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + b * a) >> 8;
out++;
#endif
}
@@ -459,11 +448,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;
}
@@ -509,60 +498,4 @@ void RenderedImage::checkForTransparency() {
}
}
-/**
- * Scales a passed surface, creating a new surface with the result
- * @param srcImage Source image to scale
- * @param scaleFactor Scale amount. Must be between 0 and 1.0 (but not zero)
- * @remarks Caller is responsible for freeing the returned surface
- */
-Graphics::Surface *RenderedImage::scale(const Graphics::Surface &srcImage, int xSize, int ySize) {
- Graphics::Surface *s = new Graphics::Surface();
- s->create(xSize, ySize, srcImage.format);
-
- int *horizUsage = scaleLine(xSize, srcImage.w);
- int *vertUsage = scaleLine(ySize, srcImage.h);
-
- // Loop to create scaled version
- for (int yp = 0; yp < ySize; ++yp) {
- const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);
- byte *destP = (byte *)s->getBasePtr(0, yp);
-
- for (int xp = 0; xp < xSize; ++xp) {
- const byte *tempSrcP = srcP + (horizUsage[xp] * srcImage.format.bytesPerPixel);
- for (int byteCtr = 0; byteCtr < srcImage.format.bytesPerPixel; ++byteCtr) {
- *destP++ = *tempSrcP++;
- }
- }
- }
-
- // Delete arrays and return surface
- delete[] horizUsage;
- delete[] vertUsage;
- return s;
-}
-
-/**
- * Returns an array indicating which pixels of a source image horizontally or vertically get
- * included in a scaled image
- */
-int *RenderedImage::scaleLine(int size, int srcSize) {
- int scale = 100 * size / srcSize;
- assert(scale > 0);
- int *v = new int[size];
- Common::fill(v, &v[size], 0);
-
- int distCtr = 0;
- int *destP = v;
- for (int distIndex = 0; distIndex < srcSize; ++distIndex) {
- distCtr += scale;
- while (distCtr >= 100) {
- assert(destP < &v[size]);
- *destP++ = distIndex;
- distCtr -= 100;
- }
- }
-
- return v;
-}
-
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/renderedimage.h b/engines/sword25/gfx/image/renderedimage.h
index a25b258592..116f97de26 100644
--- a/engines/sword25/gfx/image/renderedimage.h
+++ b/engines/sword25/gfx/image/renderedimage.h
@@ -104,8 +104,6 @@ public:
return true;
}
- static Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize);
-
void setIsTransparent(bool isTransparent) { _isTransparent = isTransparent; }
virtual bool isSolid() const { return !_isTransparent; }
@@ -119,7 +117,6 @@ private:
Graphics::Surface *_backSurface;
void checkForTransparency();
- static int *scaleLine(int size, int srcSize);
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/microtiles.cpp b/engines/sword25/gfx/microtiles.cpp
index 8dceed5348..18e4a9a1fb 100644
--- a/engines/sword25/gfx/microtiles.cpp
+++ b/engines/sword25/gfx/microtiles.cpp
@@ -119,7 +119,6 @@ RectangleList *MicroTileArray::getRectangles() {
for (y = 0; y < _tilesH; ++y) {
for (x = 0; x < _tilesW; ++x) {
- int start;
int finish = 0;
BoundingBox boundingBox = _tiles[i];
@@ -132,8 +131,6 @@ RectangleList *MicroTileArray::getRectangles() {
y0 = (y * TileSize) + TileY0(boundingBox);
y1 = (y * TileSize) + TileY1(boundingBox);
- start = i;
-
if (TileX1(boundingBox) == TileSize - 1 && x != _tilesW - 1) { // check if the tile continues
while (!finish) {
++x;
diff --git a/engines/sword25/gfx/panel.cpp b/engines/sword25/gfx/panel.cpp
index 931b9cdbe7..9b7fe82914 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;
}
@@ -104,7 +104,7 @@ bool Panel::unpersist(InputPersistenceBlock &reader) {
result &= RenderObject::unpersist(reader);
- uint color;
+ uint32 color;
reader.read(color);
setColor(color);
diff --git a/engines/sword25/gfx/panel.h b/engines/sword25/gfx/panel.h
index 74a93247b6..d372b4e0fc 100644
--- a/engines/sword25/gfx/panel.h
+++ b/engines/sword25/gfx/panel.h
@@ -64,7 +64,7 @@ protected:
virtual bool doRender(RectangleList *updateRects);
private:
- uint _color;
+ uint32 _color;
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp
index 807c1eb64b..e9e11aae4e 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
@@ -219,27 +219,27 @@ Common::Rect RenderObject::calcBoundingBox() const {
return bbox;
}
-void RenderObject::calcAbsolutePos(int &x, int &y, int &z) const {
+void RenderObject::calcAbsolutePos(int32 &x, int32 &y, int32 &z) const {
x = calcAbsoluteX();
y = calcAbsoluteY();
z = calcAbsoluteZ();
}
-int RenderObject::calcAbsoluteX() const {
+int32 RenderObject::calcAbsoluteX() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteX() + _x;
else
return _x;
}
-int RenderObject::calcAbsoluteY() const {
+int32 RenderObject::calcAbsoluteY() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteY() + _y;
else
return _y;
}
-int RenderObject::calcAbsoluteZ() const {
+int32 RenderObject::calcAbsoluteZ() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteZ() + _z;
else
@@ -399,7 +399,7 @@ RenderObjectPtr<Text> RenderObject::addText(const Common::String &font, const Co
bool RenderObject::persist(OutputPersistenceBlock &writer) {
// Typ und Handle werden als erstes gespeichert, damit beim Laden ein Objekt vom richtigen Typ mit dem richtigen Handle erzeugt werden kann.
- writer.write(static_cast<uint>(_type));
+ writer.write(static_cast<uint32>(_type));
writer.write(_handle);
// Restliche Objekteigenschaften speichern.
@@ -413,14 +413,14 @@ bool RenderObject::persist(OutputPersistenceBlock &writer) {
writer.write(_visible);
writer.write(_childChanged);
writer.write(_initSuccess);
- writer.write(_bbox.left);
- writer.write(_bbox.top);
- writer.write(_bbox.right);
- writer.write(_bbox.bottom);
- writer.write(_oldBbox.left);
- writer.write(_oldBbox.top);
- writer.write(_oldBbox.right);
- writer.write(_oldBbox.bottom);
+ writer.write((int32)_bbox.left);
+ writer.write((int32)_bbox.top);
+ writer.write((int32)_bbox.right);
+ writer.write((int32)_bbox.bottom);
+ writer.write((int32)_oldBbox.left);
+ writer.write((int32)_oldBbox.top);
+ writer.write((int32)_oldBbox.right);
+ writer.write((int32)_oldBbox.bottom);
writer.write(_oldX);
writer.write(_oldY);
writer.write(_oldZ);
@@ -455,7 +455,7 @@ bool RenderObject::unpersist(InputPersistenceBlock &reader) {
reader.read(_oldY);
reader.read(_oldZ);
reader.read(_oldVisible);
- uint parentHandle;
+ uint32 parentHandle;
reader.read(parentHandle);
_parentPtr = RenderObjectPtr<RenderObject>(parentHandle);
reader.read(_refreshForced);
@@ -470,7 +470,7 @@ bool RenderObject::persistChildren(OutputPersistenceBlock &writer) {
bool result = true;
// Kinderanzahl speichern.
- writer.write(_children.size());
+ writer.write((uint32)_children.size());
// Rekursiv alle Kinder speichern.
RENDEROBJECT_LIST::iterator it = _children.begin();
@@ -486,13 +486,13 @@ bool RenderObject::unpersistChildren(InputPersistenceBlock &reader) {
bool result = true;
// Kinderanzahl einlesen.
- uint childrenCount;
+ uint32 childrenCount;
reader.read(childrenCount);
if (!reader.isGood())
return false;
// Alle Kinder rekursiv wieder herstellen.
- for (uint i = 0; i < childrenCount; ++i) {
+ for (uint32 i = 0; i < childrenCount; ++i) {
if (!recreatePersistedRenderObject(reader).isValid())
return false;
}
@@ -504,8 +504,8 @@ RenderObjectPtr<RenderObject> RenderObject::recreatePersistedRenderObject(InputP
RenderObjectPtr<RenderObject> result;
// Typ und Handle auslesen.
- uint type;
- uint handle;
+ uint32 type;
+ uint32 handle;
reader.read(type);
reader.read(handle);
if (!reader.isGood())
diff --git a/engines/sword25/gfx/renderobject.h b/engines/sword25/gfx/renderobject.h
index 7e0334ee88..7fcd3a87a3 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.
*/
@@ -359,15 +359,15 @@ public:
/**
@brief Gibt das Handle des Objekte zurück.
*/
- uint getHandle() const {
+ uint32 getHandle() const {
return _handle;
}
- // Get the RenderObjects current version
+ // Get the RenderObjects current version
int getVersion() const {
return _version;
}
-
+
bool isSolid() const {
return _isSolid;
}
@@ -388,14 +388,14 @@ protected:
typedef Common::List<RenderObjectPtr<RenderObject> > RENDEROBJECT_LIST;
typedef Common::List<RenderObjectPtr<RenderObject> >::iterator RENDEROBJECT_ITER;
- int _x; ///< Die X-Position des Objektes relativ zum Eltern-Objekt
- int _y; ///< Die Y-Position des Objektes relativ zum Eltern-Objekt
- int _z; ///< Der Z-Wert des Objektes relativ zum Eltern-Objekt
- int _absoluteX; ///< Die absolute X-Position des Objektes
- int _absoluteY; ///< Die absolute Y-Position des Objektes
- int _absoluteZ;
- int _width; ///< Die Breite des Objektes
- int _height; ///< Die Höhe des Objektes
+ int32 _x; ///< Die X-Position des Objektes relativ zum Eltern-Objekt
+ int32 _y; ///< Die Y-Position des Objektes relativ zum Eltern-Objekt
+ int32 _z; ///< Der Z-Wert des Objektes relativ zum Eltern-Objekt
+ int32 _absoluteX; ///< Die absolute X-Position des Objektes
+ int32 _absoluteY; ///< Die absolute Y-Position des Objektes
+ int32 _absoluteZ;
+ int32 _width; ///< Die Breite des Objektes
+ int32 _height; ///< Die Höhe des Objektes
bool _visible; ///< Ist true, wenn das Objekt sichtbar ist
bool _childChanged; ///< Ist true, wenn sich ein Kinderobjekt verändert hat
TYPES _type; ///< Der Objekttyp
@@ -404,14 +404,14 @@ protected:
// Kopien der Variablen, die für die Errechnung des Dirty-Rects und zur Bestimmung der Objektveränderung notwendig sind
Common::Rect _oldBbox;
- int _oldX;
- int _oldY;
- int _oldZ;
+ int32 _oldX;
+ int32 _oldY;
+ int32 _oldZ;
bool _oldVisible;
static int _nextGlobalVersion;
-
- int _version;
+
+ int32 _version;
// This should be set to true if the RenderObject is NOT alpha-blended to optimize drawing
bool _isSolid;
@@ -475,7 +475,7 @@ private:
/// Ist true, wenn das Objekt in nächsten Frame neu gezeichnet werden soll
bool _refreshForced;
- uint _handle;
+ uint32 _handle;
/**
@brief Entfernt ein Objekt aus der Kinderliste.
@@ -500,18 +500,18 @@ private:
/**
@brief Berechnet die absolute Position des Objektes.
*/
- void calcAbsolutePos(int &x, int &y, int &z) const;
+ void calcAbsolutePos(int32 &x, int32 &y, int32 &z) const;
/**
@brief Berechnet die absolute Position des Objektes auf der X-Achse.
*/
- int calcAbsoluteX() const;
+ int32 calcAbsoluteX() const;
/**
@brief Berechnet die absolute Position des Objektes.
*/
- int calcAbsoluteY() const;
-
- int calcAbsoluteZ() const;
-
+ int32 calcAbsoluteY() const;
+
+ int32 calcAbsoluteZ() const;
+
/**
@brief Sortiert alle Kinderobjekte nach ihrem Renderang.
*/
diff --git a/engines/sword25/gfx/renderobjectmanager.cpp b/engines/sword25/gfx/renderobjectmanager.cpp
index 994d9367ab..bc7dd02636 100644
--- a/engines/sword25/gfx/renderobjectmanager.cpp
+++ b/engines/sword25/gfx/renderobjectmanager.cpp
@@ -103,17 +103,20 @@ bool RenderObjectManager::render() {
_uta->clear();
// Add rectangles of objects which don't exist in this frame any more
- for (RenderObjectQueue::iterator it = _prevQueue->begin(); it != _prevQueue->end(); ++it)
- if (!_currQueue->exists(*it))
- _uta->addRect((*it)._bbox);
- // Add rectangles of objects which are different from the previous frame
- for (RenderObjectQueue::iterator it = _currQueue->begin(); it != _currQueue->end(); ++it)
- if (!_prevQueue->exists(*it))
- _uta->addRect((*it)._bbox);
+ for (RenderObjectQueue::iterator it = _prevQueue->begin(); it != _prevQueue->end(); ++it) {
+ if (!_currQueue->exists(*it))
+ _uta->addRect((*it)._bbox);
+ }
+
+ // Add rectangles of objects which are different from the previous frame
+ for (RenderObjectQueue::iterator it = _currQueue->begin(); it != _currQueue->end(); ++it) {
+ if (!_prevQueue->exists(*it))
+ _uta->addRect((*it)._bbox);
+ }
RectangleList *updateRects = _uta->getRectangles();
Common::Array<int> updateRectsMinZ;
-
+
updateRectsMinZ.reserve(updateRects->size());
// Calculate the minimum drawing Z value of each update rectangle
@@ -144,9 +147,9 @@ bool RenderObjectManager::render() {
}
delete updateRects;
-
+
SWAP(_currQueue, _prevQueue);
-
+
return true;
}
@@ -171,7 +174,7 @@ bool RenderObjectManager::persist(OutputPersistenceBlock &writer) {
writer.write(_frameStarted);
// Referenzen auf die TimedRenderObjects persistieren.
- writer.write(_timedRenderObjects.size());
+ writer.write((uint32)_timedRenderObjects.size());
RenderObjectList::const_iterator iter = _timedRenderObjects.begin();
while (iter != _timedRenderObjects.end()) {
writer.write((*iter)->getHandle());
@@ -200,10 +203,10 @@ bool RenderObjectManager::unpersist(InputPersistenceBlock &reader) {
_timedRenderObjects.resize(0);
// Referenzen auf die TimedRenderObjects wieder herstellen.
- uint timedObjectCount;
+ uint32 timedObjectCount;
reader.read(timedObjectCount);
- for (uint i = 0; i < timedObjectCount; ++i) {
- uint handle;
+ for (uint32 i = 0; i < timedObjectCount; ++i) {
+ uint32 handle;
reader.read(handle);
_timedRenderObjects.push_back(handle);
}
diff --git a/engines/sword25/gfx/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/gfx/text.cpp b/engines/sword25/gfx/text.cpp
index d4aaa90682..8c33fa8d61 100644
--- a/engines/sword25/gfx/text.cpp
+++ b/engines/sword25/gfx/text.cpp
@@ -45,7 +45,7 @@
namespace Sword25 {
namespace {
-const uint AUTO_WRAP_THRESHOLD_DEFAULT = 300;
+const uint32 AUTO_WRAP_THRESHOLD_DEFAULT = 300;
}
Text::Text(RenderObjectPtr<RenderObject> parentPtr) :
@@ -98,8 +98,8 @@ void Text::setText(const Common::String &text) {
}
}
-void Text::setColor(uint modulationColor) {
- uint newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
+void Text::setColor(uint32 modulationColor) {
+ uint32 newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
if (newModulationColor != _modulationColor) {
_modulationColor = newModulationColor;
forceRefresh();
@@ -108,7 +108,7 @@ void Text::setColor(uint modulationColor) {
void Text::setAlpha(int alpha) {
assert(alpha >= 0 && alpha < 256);
- uint newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
+ uint32 newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
if (newModulationColor != _modulationColor) {
_modulationColor = newModulationColor;
forceRefresh();
@@ -123,7 +123,7 @@ void Text::setAutoWrap(bool autoWrap) {
}
}
-void Text::setAutoWrapThreshold(uint autoWrapThreshold) {
+void Text::setAutoWrapThreshold(uint32 autoWrapThreshold) {
if (autoWrapThreshold != _autoWrapThreshold) {
_autoWrapThreshold = autoWrapThreshold;
updateFormat();
@@ -351,7 +351,7 @@ bool Text::unpersist(InputPersistenceBlock &reader) {
reader.read(autoWrap);
setAutoWrap(autoWrap);
- uint autoWrapThreshold;
+ uint32 autoWrapThreshold;
reader.read(autoWrapThreshold);
setAutoWrapThreshold(autoWrapThreshold);
diff --git a/engines/sword25/gfx/text.h b/engines/sword25/gfx/text.h
index 94e7a30865..873eb33380 100644
--- a/engines/sword25/gfx/text.h
+++ b/engines/sword25/gfx/text.h
@@ -80,7 +80,7 @@ public:
@remark Dieses Attribut wird mit dem Wert 300 initialisiert.
@remark Eine automatische Formatierung wird nur vorgenommen, wenn diese durch einen Aufruf von SetAutoWrap() aktiviert wurde.
*/
- void setAutoWrapThreshold(uint autoWrapThreshold);
+ void setAutoWrapThreshold(uint32 autoWrapThreshold);
/**
@brief Gibt den dargestellten Text zurück.
@@ -100,7 +100,7 @@ public:
@brief Setzt die Farbe des Textes.
@param Color eine 24-Bit RGB Farbe, die die Farbe des Textes festlegt.
*/
- void setColor(uint modulationColor);
+ void setColor(uint32 modulationColor);
/**
@brief Gibt den Alphawert des Textes zurück.
@@ -128,7 +128,7 @@ public:
/**
@brief Gibt die Längengrenze des Textes in Pixeln zurück, ab der eine automatische Formatierung vorgenommen wird.
*/
- uint getAutoWrapThreshold() const {
+ uint32 getAutoWrapThreshold() const {
return _autoWrapThreshold;
}
@@ -142,11 +142,11 @@ private:
Text(RenderObjectPtr<RenderObject> parentPtr);
Text(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPtr, uint handle);
- uint _modulationColor;
+ uint32 _modulationColor;
Common::String _font;
Common::String _text;
bool _autoWrap;
- uint _autoWrapThreshold;
+ uint32 _autoWrapThreshold;
struct Line {
Common::Rect bbox;
diff --git a/engines/sword25/input/inputengine.cpp b/engines/sword25/input/inputengine.cpp
index bb9c2c8b40..0d1c449805 100644
--- a/engines/sword25/input/inputengine.cpp
+++ b/engines/sword25/input/inputengine.cpp
@@ -235,13 +235,13 @@ bool InputEngine::persist(OutputPersistenceBlock &writer) {
// Write out the number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaCommandCB");
// Write out the number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaCharacterCB");
return true;
@@ -253,7 +253,7 @@ bool InputEngine::unpersist(InputPersistenceBlock &reader) {
// Read number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- uint commandCallbackCount;
+ uint32 commandCallbackCount;
reader.read(commandCallbackCount);
assert(commandCallbackCount == 1);
@@ -263,7 +263,7 @@ bool InputEngine::unpersist(InputPersistenceBlock &reader) {
// Read number of character callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- uint characterCallbackCount;
+ uint32 characterCallbackCount;
reader.read(characterCallbackCount);
assert(characterCallbackCount == 1);
diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp
index 0fe5d88b80..aa3a759756 100644
--- a/engines/sword25/kernel/inputpersistenceblock.cpp
+++ b/engines/sword25/kernel/inputpersistenceblock.cpp
@@ -48,12 +48,12 @@ InputPersistenceBlock::~InputPersistenceBlock() {
}
void InputPersistenceBlock::read(int16 &value) {
- signed int v;
+ int32 v;
read(v);
value = static_cast<int16>(v);
}
-void InputPersistenceBlock::read(signed int &value) {
+void InputPersistenceBlock::read(int32 &value) {
if (checkMarker(SINT_MARKER)) {
value = (int32)READ_LE_UINT32(_iter);
_iter += 4;
@@ -62,7 +62,7 @@ void InputPersistenceBlock::read(signed int &value) {
}
}
-void InputPersistenceBlock::read(uint &value) {
+void InputPersistenceBlock::read(uint32 &value) {
if (checkMarker(UINT_MARKER)) {
value = READ_LE_UINT32(_iter);
_iter += 4;
@@ -96,7 +96,7 @@ void InputPersistenceBlock::readString(Common::String &value) {
value = "";
if (checkMarker(STRING_MARKER)) {
- uint size;
+ uint32 size;
read(size);
if (checkBlockSize(size)) {
@@ -108,7 +108,7 @@ void InputPersistenceBlock::readString(Common::String &value) {
void InputPersistenceBlock::readByteArray(Common::Array<byte> &value) {
if (checkMarker(BLOCK_MARKER)) {
- uint size;
+ uint32 size;
read(size);
if (checkBlockSize(size)) {
diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h
index 2518d7e32c..02a944ff1b 100644
--- a/engines/sword25/kernel/inputpersistenceblock.h
+++ b/engines/sword25/kernel/inputpersistenceblock.h
@@ -50,8 +50,8 @@ public:
virtual ~InputPersistenceBlock();
void read(int16 &value);
- void read(signed int &value);
- void read(uint &value);
+ void read(int32 &value);
+ void read(uint32 &value);
void read(float &value);
void read(bool &value);
void readString(Common::String &value);
diff --git a/engines/sword25/kernel/objectregistry.h b/engines/sword25/kernel/objectregistry.h
index d9a7c353f7..449b1b60a3 100644
--- a/engines/sword25/kernel/objectregistry.h
+++ b/engines/sword25/kernel/objectregistry.h
@@ -139,12 +139,12 @@ protected:
}
};
- typedef Common::HashMap<uint, T *> HANDLE2PTR_MAP;
- typedef Common::HashMap<T *, uint, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP;
+ typedef Common::HashMap<uint32, T *> HANDLE2PTR_MAP;
+ typedef Common::HashMap<T *, uint32, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP;
HANDLE2PTR_MAP _handle2PtrMap;
PTR2HANDLE_MAP _ptr2HandleMap;
- uint _nextHandle;
+ uint32 _nextHandle;
T *findPtrByHandle(uint handle) {
// Zum Handle gehörigen Pointer finden.
diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp
index e29d956e5f..53fb624767 100644
--- a/engines/sword25/kernel/outputpersistenceblock.cpp
+++ b/engines/sword25/kernel/outputpersistenceblock.cpp
@@ -41,13 +41,13 @@ OutputPersistenceBlock::OutputPersistenceBlock() {
_data.reserve(INITIAL_BUFFER_SIZE);
}
-void OutputPersistenceBlock::write(signed int value) {
+void OutputPersistenceBlock::write(int32 value) {
writeMarker(SINT_MARKER);
value = TO_LE_32(value);
rawWrite(&value, sizeof(value));
}
-void OutputPersistenceBlock::write(uint value) {
+void OutputPersistenceBlock::write(uint32 value) {
writeMarker(UINT_MARKER);
value = TO_LE_32(value);
rawWrite(&value, sizeof(value));
@@ -74,14 +74,14 @@ void OutputPersistenceBlock::write(bool value) {
void OutputPersistenceBlock::writeString(const Common::String &string) {
writeMarker(STRING_MARKER);
- write(string.size());
+ write((uint32)string.size());
rawWrite(string.c_str(), string.size());
}
void OutputPersistenceBlock::writeByteArray(Common::Array<byte> &value) {
writeMarker(BLOCK_MARKER);
- write((uint)value.size());
+ write((uint32)value.size());
rawWrite(&value[0], value.size());
}
diff --git a/engines/sword25/kernel/outputpersistenceblock.h b/engines/sword25/kernel/outputpersistenceblock.h
index 12351d22e2..17f018a106 100644
--- a/engines/sword25/kernel/outputpersistenceblock.h
+++ b/engines/sword25/kernel/outputpersistenceblock.h
@@ -41,8 +41,8 @@ class OutputPersistenceBlock : public PersistenceBlock {
public:
OutputPersistenceBlock();
- void write(signed int value);
- void write(uint value);
+ void write(int32 value);
+ void write(uint32 value);
void write(float value);
void write(bool value);
void writeString(const Common::String &string);
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
index 27d669caa1..df26da7800 100644
--- a/engines/sword25/kernel/persistenceservice.cpp
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -59,7 +59,7 @@ static const int VERSIONNUM = 2;
char gameTarget[MAX_SAVEGAME_SIZE];
void setGameTarget(const char *target) {
- strncpy(gameTarget, target, MAX_SAVEGAME_SIZE);
+ strncpy(gameTarget, target, MAX_SAVEGAME_SIZE - 1);
}
static Common::String generateSavegameFilename(uint slotID) {
diff --git a/engines/sword25/math/polygon.cpp b/engines/sword25/math/polygon.cpp
index 2e7836ff77..99d947df87 100644
--- a/engines/sword25/math/polygon.cpp
+++ b/engines/sword25/math/polygon.cpp
@@ -364,20 +364,20 @@ bool Polygon::isPointInPolygon(const Vertex &point, bool edgesBelongToPolygon) c
bool Polygon::persist(OutputPersistenceBlock &writer) {
writer.write(vertexCount);
for (int i = 0; i < vertexCount; ++i) {
- writer.write(vertices[i].x);
- writer.write(vertices[i].y);
+ writer.write((int32)vertices[i].x);
+ writer.write((int32)vertices[i].y);
}
return true;
}
bool Polygon::unpersist(InputPersistenceBlock &reader) {
- int storedvertexCount;
+ int32 storedvertexCount;
reader.read(storedvertexCount);
Common::Array<Vertex> storedvertices;
for (int i = 0; i < storedvertexCount; ++i) {
- int x, y;
+ int32 x, y;
reader.read(x);
reader.read(y);
storedvertices.push_back(Vertex(x, y));
diff --git a/engines/sword25/math/polygon.h b/engines/sword25/math/polygon.h
index ffdbf14f6b..f81e165621 100644
--- a/engines/sword25/math/polygon.h
+++ b/engines/sword25/math/polygon.h
@@ -169,7 +169,7 @@ public:
//
/// Specifies the number of Vertecies in the Vertecies array.
- int vertexCount;
+ int32 vertexCount;
/// COntains the Vertecies of the polygon
Vertex *vertices;
diff --git a/engines/sword25/math/region.cpp b/engines/sword25/math/region.cpp
index 7681ef6d9f..db888e432a 100644
--- a/engines/sword25/math/region.cpp
+++ b/engines/sword25/math/region.cpp
@@ -67,7 +67,7 @@ uint Region::create(REGION_TYPE type) {
uint Region::create(InputPersistenceBlock &reader, uint handle) {
// Read type
- uint type;
+ uint32 type;
reader.read(type);
// Depending on the type, create a new BS_Region or BS_WalkRegion object
@@ -299,22 +299,22 @@ bool Region::isLineOfSight(const Vertex &a, const Vertex &b) const {
bool Region::persist(OutputPersistenceBlock &writer) {
bool Result = true;
- writer.write(static_cast<uint>(_type));
+ writer.write(static_cast<uint32>(_type));
writer.write(_valid);
- writer.write(_position.x);
- writer.write(_position.y);
+ writer.write((int32)_position.x);
+ writer.write((int32)_position.y);
- writer.write(_polygons.size());
+ writer.write((uint32)_polygons.size());
Common::Array<Polygon>::iterator It = _polygons.begin();
while (It != _polygons.end()) {
Result &= It->persist(writer);
++It;
}
- writer.write(_boundingBox.left);
- writer.write(_boundingBox.top);
- writer.write(_boundingBox.right);
- writer.write(_boundingBox.bottom);
+ writer.write((int32)_boundingBox.left);
+ writer.write((int32)_boundingBox.top);
+ writer.write((int32)_boundingBox.right);
+ writer.write((int32)_boundingBox.bottom);
return Result;
}
@@ -325,7 +325,7 @@ bool Region::unpersist(InputPersistenceBlock &reader) {
reader.read(_position.y);
_polygons.clear();
- uint PolygonCount;
+ uint32 PolygonCount;
reader.read(PolygonCount);
for (uint i = 0; i < PolygonCount; ++i) {
_polygons.push_back(Polygon(reader));
diff --git a/engines/sword25/math/regionregistry.cpp b/engines/sword25/math/regionregistry.cpp
index 68c360a5ee..e4925f7baf 100644
--- a/engines/sword25/math/regionregistry.cpp
+++ b/engines/sword25/math/regionregistry.cpp
@@ -47,7 +47,7 @@ bool RegionRegistry::persist(OutputPersistenceBlock &writer) {
writer.write(_nextHandle);
// Number of regions to write
- writer.write(_handle2PtrMap.size());
+ writer.write((uint32)_handle2PtrMap.size());
// Persist all the BS_Regions
HANDLE2PTR_MAP::const_iterator iter = _handle2PtrMap.begin();
@@ -76,13 +76,13 @@ bool RegionRegistry::unpersist(InputPersistenceBlock &reader) {
delete _handle2PtrMap.begin()->_value;
// read in the number of BS_Regions
- uint regionCount;
+ uint32 regionCount;
reader.read(regionCount);
// Restore all the BS_Regions objects
for (uint i = 0; i < regionCount; ++i) {
// Handle read
- uint handle;
+ uint32 handle;
reader.read(handle);
// BS_Region restore
diff --git a/engines/sword25/math/walkregion.cpp b/engines/sword25/math/walkregion.cpp
index bace4d54bc..0ba7e8ec3d 100644
--- a/engines/sword25/math/walkregion.cpp
+++ b/engines/sword25/math/walkregion.cpp
@@ -328,22 +328,22 @@ bool WalkRegion::persist(OutputPersistenceBlock &writer) {
result &= Region::persist(writer);
// Persist the nodes
- writer.write(_nodes.size());
+ writer.write((uint32)_nodes.size());
Common::Array<Vertex>::const_iterator it = _nodes.begin();
while (it != _nodes.end()) {
- writer.write(it->x);
- writer.write(it->y);
+ writer.write((int32)it->x);
+ writer.write((int32)it->y);
++it;
}
// Persist the visibility matrix
- writer.write(_visibilityMatrix.size());
+ writer.write((uint32)_visibilityMatrix.size());
Common::Array< Common::Array<int> >::const_iterator rowIter = _visibilityMatrix.begin();
while (rowIter != _visibilityMatrix.end()) {
- writer.write(rowIter->size());
+ writer.write((uint32)rowIter->size());
Common::Array<int>::const_iterator colIter = rowIter->begin();
while (colIter != rowIter->end()) {
- writer.write(*colIter);
+ writer.write((int32)*colIter);
++colIter;
}
@@ -360,7 +360,7 @@ bool WalkRegion::unpersist(InputPersistenceBlock &reader) {
// this point only the additional data from BS_WalkRegion needs to be loaded
// Node load
- uint nodeCount;
+ uint32 nodeCount;
reader.read(nodeCount);
_nodes.clear();
_nodes.resize(nodeCount);
@@ -372,18 +372,20 @@ bool WalkRegion::unpersist(InputPersistenceBlock &reader) {
}
// Visibility matrix load
- uint rowCount;
+ uint32 rowCount;
reader.read(rowCount);
_visibilityMatrix.clear();
_visibilityMatrix.resize(rowCount);
Common::Array< Common::Array<int> >::iterator rowIter = _visibilityMatrix.begin();
while (rowIter != _visibilityMatrix.end()) {
- uint colCount;
+ uint32 colCount;
reader.read(colCount);
rowIter->resize(colCount);
Common::Array<int>::iterator colIter = rowIter->begin();
while (colIter != rowIter->end()) {
- reader.read(*colIter);
+ int32 t;
+ reader.read(t);
+ *colIter = t;
++colIter;
}
diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp
index 61d53c89a7..8ff1b0cf2a 100644
--- a/engines/sword25/sfx/soundengine.cpp
+++ b/engines/sword25/sfx/soundengine.cpp
@@ -339,7 +339,10 @@ bool SoundEngine::persist(OutputPersistenceBlock &writer) {
_handles[i].type = kFreeHandle;
writer.writeString(_handles[i].fileName);
- writer.write((int)_handles[i].sndType);
+ if (_handles[i].type == kFreeHandle)
+ writer.write((int32)-1);
+ else
+ writer.write(_handles[i].sndType);
writer.write(_handles[i].volume);
writer.write(_handles[i].pan);
writer.write(_handles[i].loop);
@@ -363,13 +366,13 @@ bool SoundEngine::unpersist(InputPersistenceBlock &reader) {
reader.read(_handles[i].id);
Common::String fileName;
- int sndType;
+ int32 sndType;
float volume;
float pan;
bool loop;
- int loopStart;
- int loopEnd;
- uint layer;
+ int32 loopStart;
+ int32 loopEnd;
+ uint32 layer;
reader.readString(fileName);
reader.read(sndType);
@@ -381,7 +384,7 @@ bool SoundEngine::unpersist(InputPersistenceBlock &reader) {
reader.read(layer);
if (reader.isGood()) {
- if (sndType != kFreeHandle)
+ if (sndType != -1)
playSoundEx(fileName, (SOUND_TYPES)sndType, volume, pan, loop, loopStart, loopEnd, layer, i);
} else
return false;
diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h
index 8132ec556e..8974ee69e5 100644
--- a/engines/sword25/sfx/soundengine.h
+++ b/engines/sword25/sfx/soundengine.h
@@ -67,13 +67,13 @@ struct SndHandle {
uint32 id;
Common::String fileName;
- int sndType;
+ int32 sndType;
float volume;
float pan;
bool loop;
- int loopStart;
- int loopEnd;
- uint layer;
+ int32 loopStart;
+ int32 loopEnd;
+ uint32 layer;
};
diff --git a/engines/sword25/util/lua/lcode.cpp b/engines/sword25/util/lua/lcode.cpp
index ead780d359..93188b37e2 100644
--- a/engines/sword25/util/lua/lcode.cpp
+++ b/engines/sword25/util/lua/lcode.cpp
@@ -5,8 +5,6 @@
*/
-#include <stdlib.h>
-
#define lcode_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/ldebug.cpp b/engines/sword25/util/lua/ldebug.cpp
index e89ae9cad5..396c5df18b 100644
--- a/engines/sword25/util/lua/ldebug.cpp
+++ b/engines/sword25/util/lua/ldebug.cpp
@@ -5,11 +5,6 @@
*/
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-
-
#define ldebug_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lfunc.cpp b/engines/sword25/util/lua/lfunc.cpp
index f8fa19e25a..95e616cc7e 100644
--- a/engines/sword25/util/lua/lfunc.cpp
+++ b/engines/sword25/util/lua/lfunc.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lfunc_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lgc.cpp b/engines/sword25/util/lua/lgc.cpp
index 54f7b548dd..53f512280a 100644
--- a/engines/sword25/util/lua/lgc.cpp
+++ b/engines/sword25/util/lua/lgc.cpp
@@ -4,8 +4,6 @@
** See Copyright Notice in lua.h
*/
-#include <string.h>
-
#define lgc_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/llimits.h b/engines/sword25/util/lua/llimits.h
index 0925231350..ce6dbc980c 100644
--- a/engines/sword25/util/lua/llimits.h
+++ b/engines/sword25/util/lua/llimits.h
@@ -8,9 +8,6 @@
#define llimits_h
-#include <limits.h>
-#include <stddef.h>
-
#include "lua.h"
diff --git a/engines/sword25/util/lua/lmem.cpp b/engines/sword25/util/lua/lmem.cpp
index 004a467dc8..8cd220308c 100644
--- a/engines/sword25/util/lua/lmem.cpp
+++ b/engines/sword25/util/lua/lmem.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lmem_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lopcodes.cpp b/engines/sword25/util/lua/lopcodes.cpp
index 255b2029e9..8b0a3ab330 100644
--- a/engines/sword25/util/lua/lopcodes.cpp
+++ b/engines/sword25/util/lua/lopcodes.cpp
@@ -8,6 +8,7 @@
#define LUA_CORE
+#include "lua.h"
#include "lopcodes.h"
@@ -60,7 +61,7 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
- opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
diff --git a/engines/sword25/util/lua/lparser.cpp b/engines/sword25/util/lua/lparser.cpp
index 03ea333315..0c88992e79 100644
--- a/engines/sword25/util/lua/lparser.cpp
+++ b/engines/sword25/util/lua/lparser.cpp
@@ -5,8 +5,6 @@
*/
-#include <string.h>
-
#define lparser_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstate.cpp b/engines/sword25/util/lua/lstate.cpp
index 26bed7bec2..c0ea29de01 100644
--- a/engines/sword25/util/lua/lstate.cpp
+++ b/engines/sword25/util/lua/lstate.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lstate_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstring.cpp b/engines/sword25/util/lua/lstring.cpp
index 046b87ee1c..5cfc72539a 100644
--- a/engines/sword25/util/lua/lstring.cpp
+++ b/engines/sword25/util/lua/lstring.cpp
@@ -5,8 +5,6 @@
*/
-#include <string.h>
-
#define lstring_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstrlib.cpp b/engines/sword25/util/lua/lstrlib.cpp
index ed68a2fa00..5da45e1fea 100644
--- a/engines/sword25/util/lua/lstrlib.cpp
+++ b/engines/sword25/util/lua/lstrlib.cpp
@@ -7,12 +7,6 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
-#include <ctype.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#define lstrlib_c
#define LUA_LIB
diff --git a/engines/sword25/util/lua/ltablib.cpp b/engines/sword25/util/lua/ltablib.cpp
index 93be9e6077..064c33c005 100644
--- a/engines/sword25/util/lua/ltablib.cpp
+++ b/engines/sword25/util/lua/ltablib.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define ltablib_c
#define LUA_LIB
diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h
index a3b7573ca5..4f557e462b 100644
--- a/engines/sword25/util/lua/lua.h
+++ b/engines/sword25/util/lua/lua.h
@@ -22,7 +22,7 @@
#define LUA_RELEASE "Lua 5.1.3"
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
-#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
/* mark for precompiled code (`<esc>Lua') */
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
index b7f5e30340..fb477c1687 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,16 @@
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Instrumented by Stefan Reich (info@luaos.net)
+ * for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
*/
#include "sword25/util/lua/lua.h"
#include "pluto.h"
+#undef TOTEXT
+
#define USE_PDEP
#ifdef USE_PDEP
@@ -42,10 +47,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 +71,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 +108,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 +210,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 +237,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 +260,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 +300,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 +318,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 +374,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 +415,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 +455,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 +554,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 +575,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 +596,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 +637,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 +677,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 +787,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 +796,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 +805,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 +825,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 +857,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 +872,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 +950,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 +981,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 +1000,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 +1016,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 +1040,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 +1064,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 +1167,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 +1188,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 +1264,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 +1684,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 +1703,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 +1735,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 +1764,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 +1816,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 +1984,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 +2026,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/POTFILES b/engines/teenagent/POTFILES
new file mode 100644
index 0000000000..b8b832872e
--- /dev/null
+++ b/engines/teenagent/POTFILES
@@ -0,0 +1 @@
+engines/teenagent/resources.cpp
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/configure.engine b/engines/teenagent/configure.engine
new file mode 100644
index 0000000000..223a0e884c
--- /dev/null
+++ b/engines/teenagent/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine teenagent "Teen Agent" yes
diff --git a/engines/teenagent/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-params.cpp b/engines/testbed/config-params.cpp
index e89da0b07f..47e5dfa933 100644
--- a/engines/testbed/config-params.cpp
+++ b/engines/testbed/config-params.cpp
@@ -38,6 +38,8 @@ ConfigParams::ConfigParams() {
_isInteractive = true;
_isGameDataFound = true;
_rerunTests = false;
+
+ _testbedConfMan = 0;
}
void ConfigParams::initLogging(const char *dirname, const char *filename, bool enable) {
diff --git a/engines/testbed/config.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..7d479a74fd 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();
};
@@ -113,7 +113,7 @@ private:
class TestbedInteractionDialog : public GUI::Dialog {
public:
- TestbedInteractionDialog(uint x, uint y, uint w, uint h) : GUI::Dialog(x, y, w, h) {}
+ TestbedInteractionDialog(uint x, uint y, uint w, uint h) : GUI::Dialog(x, y, w, h), _xOffset(0), _yOffset(0) {}
~TestbedInteractionDialog() {}
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
void addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset = 0, uint yPadding = 8);
diff --git a/engines/testbed/configure.engine b/engines/testbed/configure.engine
new file mode 100644
index 0000000000..c0a68c8eb8
--- /dev/null
+++ b/engines/testbed/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine testbed "TestBed: the Testing framework" no
diff --git a/engines/testbed/events.cpp b/engines/testbed/events.cpp
index 78de87e133..4b9ced2a53 100644
--- a/engines/testbed/events.cpp
+++ b/engines/testbed/events.cpp
@@ -83,11 +83,10 @@ struct keycodeToChar {
char EventTests::keystrokeToChar() {
Common::EventManager *eventMan = g_system->getEventManager();
- bool quitLoop = false;
Common::Event event;
// handle all keybd events
- while (!quitLoop) {
+ while (true) {
while (eventMan->pollEvent(event)) {
// Quit if explicitly requested!
if (Engine::shouldQuit()) {
@@ -110,8 +109,6 @@ char EventTests::keystrokeToChar() {
}
}
}
-
- return 0;
}
Common::Rect EventTests::drawFinishZone() {
diff --git a/engines/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/testbed/midi.cpp b/engines/testbed/midi.cpp
index 70ede406d5..33fab03a5e 100644
--- a/engines/testbed/midi.cpp
+++ b/engines/testbed/midi.cpp
@@ -103,7 +103,7 @@ TestExitStatus MidiTests::playMidiMusic() {
return kTestFailed;
}
- Testsuite::logDetailedPrintf("Info! Midi: Succesfully opened the driver\n");
+ Testsuite::logDetailedPrintf("Info! Midi: Successfully opened the driver\n");
Common::MemoryWriteStreamDynamic ws(DisposeAfterUse::YES);
loadMusicInMemory(&ws);
diff --git a/engines/tinsel/POTFILES b/engines/tinsel/POTFILES
new file mode 100644
index 0000000000..714da378c8
--- /dev/null
+++ b/engines/tinsel/POTFILES
@@ -0,0 +1 @@
+engines/tinsel/saveload.cpp
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/configure.engine b/engines/tinsel/configure.engine
new file mode 100644
index 0000000000..c0f3e0a18d
--- /dev/null
+++ b/engines/tinsel/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tinsel "Tinsel" yes
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index 2e4be33e53..a7ba8b28cb 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -67,7 +67,7 @@ bool TinselEngine::getIsADGFDemo() const {
return (bool)(_gameDescription->desc.flags & ADGF_DEMO);
}
-bool TinselEngine::isCD() const {
+bool TinselEngine::isV1CD() const {
return (bool)(_gameDescription->desc.flags & ADGF_CD);
}
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index f05f39b319..cc8166f295 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -34,6 +34,8 @@ static const TinselGameDescription gameDescriptions[] = {
// TINSEL_V2: The Discworld 2 game used this updated version of the Tinsel 1 engine,
// and as far as we know there aren't any variations of this engine.
+ // ==== Discworld 1 early (TinselV0) entries ==============================
+
{ // Floppy Demo V0 from http://www.adventure-treff.de/specials/dl_demos.php
{
"dw",
@@ -51,6 +53,8 @@ static const TinselGameDescription gameDescriptions[] = {
TINSEL_V0,
},
+ // ==== Discworld 1 entries ===============================================
+
{ // CD Demo V1 version, with *.gra files
{
"dw",
@@ -474,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",
@@ -553,6 +577,9 @@ static const TinselGameDescription gameDescriptions[] = {
TINSEL_V1,
},
+ // ==== Discworld 2 entries ===============================================
+ // Note: All Discworld 2 versions are CD only, therefore we don't add the ADGF_CD flag
+
{ // English Discworld 2 demo
{
"dw2",
@@ -564,7 +591,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_DEMO | ADGF_CD,
+ ADGF_DEMO,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -584,7 +611,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_GRB,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -604,7 +631,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_USA,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -624,7 +651,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -644,7 +671,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -665,7 +692,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -685,7 +712,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
@@ -706,7 +733,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::RU_RUS,
Common::kPlatformDOS,
- ADGF_CD,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOASPECT)
},
GID_DW2,
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/music.cpp b/engines/tinsel/music.cpp
index 3144ea7f94..bf7257f876 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -91,28 +91,29 @@ static const int enhancedAudioGRAVersion[] = {
};
static const int enhancedAudioSCNVersion[] = {
- 301, 302, 2, 1, 1, 301, 302, 3, 3, 4, // 1-10
- 4, 5, 6, 1, 7, 8, 9, 10, 8, 11, // 11-20
- 11, 12, 13, 13, 13, 13, 13, 14, 13, 13, // 21-30
- 15, 16, 17, 15, 18, 19, 20, 338, 21, 21, // 31-40
- 341, 342, 22, 22, 23, 24, 25, 26, 27, 28, // 41-50
- 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, // 51-60
- 38, 39, 39, 39, 39, 40, 39, 41, 41, 42, // 61-70
- 43, 42, 44, 45, 41, 46, 48, 47, 48, 49, // 71-80
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // 81-90
- 60, 61, 62, 63, 61, 64, 65, 66, 67, 68, // 91-100
- 69, 70, 68, 71, 72, 73, 74, 75, 12, 76, // 101-110
- 77, 78, 79, 80, 4, 4, 82, 83, 77, 4, // 111-120
- 84, 85, 86, 3124, 88, 89, 90, 88, 2, 2, // 121-130
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 131-140
- 3142, 91, 92, 93, 94, 94, 95, 96, 52, 4, // 141-150
- 97, 98, 99, 99 // 151-154
+ 301, 302, 2, 1, 1, 301, 302, 3, 3, 4, // 1-10
+ 4, 5, 6, 1, 7, 8, 9, 10, 8, 11, // 11-20
+ 11, 12, 13, 13, 13, 13, 13, 14, 13, 13, // 21-30
+ 15, 16, 17, 15, 18, 19, 20, 338, 21, 21, // 31-40
+ 341, 342, 22, 22, 23, 24, 25, 26, 27, 28, // 41-50
+ 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, // 51-60
+ 38, 39, 39, 39, 39, 40, 39, 41, 41, 42, // 61-70
+ 43, 42, 44, 45, 41, 46, 48, 47, 48, 49, // 71-80
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // 81-90
+ 60, 61, 62, 63, 61, 64, 65, 66, 67, 68, // 91-100
+ 69, 70, 68, 71, 72, 73, 74, 75, 12, 76, // 101-110
+ 77, 78, 79, 80, 4, 4, 82, 83, 77, 4, // 111-120
+ 84, 85, 86, 3124, 88, 89, 90, 88, 2, 2, // 121-130
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 131-140
+ 3142, 91, 92, 93, 94, 94, 95, 96, 52, 4, // 141-150
+ 97, 98, 99, 99 // 151-154
};
int GetTrackNumber(SCNHANDLE hMidi) {
- for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
+ for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++) {
if (g_midiOffsets[i] == hMidi)
return i;
+ }
return -1;
}
diff --git a/engines/tinsel/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 b652e394a0..043b18b8c5 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -130,15 +130,15 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
const byte *p = pStruc;
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
- g_tempStruc.numEntrance = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.numPoly = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.numTaggedActor = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.defRefer = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.hSceneScript = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.hEntrance = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.hPoly = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
- g_tempStruc.hTaggedActor = FROM_LE_32(READ_32(p)); p += sizeof(uint32);
-
+ g_tempStruc.numEntrance = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.numPoly = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.numTaggedActor = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.defRefer = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.hSceneScript = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.hEntrance = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.hPoly = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.hTaggedActor = READ_32(p); p += sizeof(uint32);
+
return &g_tempStruc;
}
@@ -186,7 +186,7 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
void SendSceneTinselProcess(TINSEL_EVENT event) {
SCENE_STRUC *ss;
- if (g_SceneHandle != (SCNHANDLE)NULL) {
+ if (g_SceneHandle != 0) {
ss = (SCENE_STRUC *) FindChunk(g_SceneHandle, CHUNK_SCENE);
if (ss->hSceneScript) {
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index cadc754de6..416ee74127 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -75,7 +75,7 @@ SoundManager::~SoundManager() {
// playSample for DiscWorld 1
bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) {
// Floppy version has no sample file.
- if (!_vm->isCD())
+ if (!_vm->isV1CD())
return false;
// no sample driver?
@@ -207,10 +207,6 @@ void SoundManager::playDW1MacMusic(Common::File &s, uint32 length) {
bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int priority,
Audio::Mixer::SoundType type, Audio::SoundHandle *handle) {
- // Floppy version has no sample file
- if (!_vm->isCD())
- return false;
-
// no sample driver?
if (!_vm->_mixer->isReady())
return false;
@@ -501,8 +497,8 @@ void SoundManager::showSoundError(const char *errorMsg, const char *soundFile) {
* Opens and inits all sound sample files.
*/
void SoundManager::openSampleFiles() {
- // Floppy and demo versions have no sample files, except for the Discworld 2 demo
- if (!_vm->isCD())
+ // V1 Floppy and V0 demo versions have no sample files
+ if (TinselV0 || (TinselV1 && !_vm->isV1CD()))
return;
TinselFile f;
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/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index ec504b69cd..5eb3b7d7b8 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -184,7 +184,7 @@ public:
uint32 getFlags() const;
Common::Platform getPlatform() const;
bool getIsADGFDemo() const;
- bool isCD() const;
+ bool isV1CD() const;
const char *getSampleIndex(LANGUAGE lang);
const char *getSampleFile(LANGUAGE lang);
@@ -226,7 +226,11 @@ public:
Graphics::Surface &screen() { return _screenSurface; }
Common::Point getMousePosition() const { return _mousePos; }
- void setMousePosition(const Common::Point &pt) {
+ void setMousePosition(Common::Point pt) {
+ // Clip mouse position to be within the screen coordinates
+ pt.x = CLIP<int16>(pt.x, 0, SCREEN_WIDTH - 1);
+ pt.y = CLIP<int16>(pt.y, 0, SCREEN_HEIGHT - 1);
+
int yOffset = TinselV2 ? (g_system->getHeight() - _screenSurface.h) / 2 : 0;
g_system->warpMouse(pt.x, pt.y + yOffset);
_mousePos = pt;
diff --git a/engines/toltecs/POTFILES b/engines/toltecs/POTFILES
new file mode 100644
index 0000000000..81adbb86a1
--- /dev/null
+++ b/engines/toltecs/POTFILES
@@ -0,0 +1,2 @@
+engines/toltecs/detection.cpp
+engines/toltecs/menu.cpp
diff --git a/engines/toltecs/configure.engine b/engines/toltecs/configure.engine
new file mode 100644
index 0000000000..be5533efa2
--- /dev/null
+++ b/engines/toltecs/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine toltecs "3 Skulls of the Toltecs" yes
diff --git a/engines/toltecs/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/render.cpp b/engines/toltecs/render.cpp
index 4c41e6ce00..ae458d40a3 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -156,7 +156,7 @@ void RenderQueue::update() {
byte *srcp = _vm->_screen->_backScreen + _vm->_cameraX + _vm->_cameraY * _vm->_sceneWidth;
int16 w = MIN<int16>(640, _vm->_sceneWidth);
int16 h = MIN<int16>(400, _vm->_cameraHeight);
- while (h--) {
+ while (h--) {
memcpy(destp, srcp, w);
destp += 640;
srcp += _vm->_sceneWidth;
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 6c195a34c2..4edcc601b8 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -183,7 +183,7 @@ void ToltecsEngine::loadgame(const char *filename) {
_mouseDisabled = in->readUint16LE();
_system->warpMouse(_mouseX, _mouseY);
- _system->showMouse(_mouseDisabled == 0);
+ _system->showMouse(_mouseDisabled == 0);
_palette->loadState(in);
_script->loadState(in);
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 5e12773e1b..dd418be71f 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -599,7 +599,7 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const
if (ywobble)
yadd = *ywobble;
- while (len--) {
+ while (len--) {
byte ch = *text++;
if (ch <= 0x20) {
x += font.getWidth();
@@ -634,7 +634,7 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
byte flags = charData[0] & 0xF0;
charData++;
if ((flags & 0x80) == 0) {
- if (flags & 0x10) {
+ if (flags & 0x10) {
memset(dest, color, count);
} else if (outline) {
memset(dest, 0, count);
@@ -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/script.cpp b/engines/toltecs/script.cpp
index 476c3a4fcf..83c4ef15fe 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -65,7 +65,7 @@ ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
_savedSp = 0;
_slots[kMaxScriptSlots - 1].size = 1024;
- _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
+ _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
setupScriptFunctions();
@@ -184,11 +184,11 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
delete[] _slots[slotIndex].data;
- _slots[slotIndex].resIndex = resIndex;
+ _slots[slotIndex].resIndex = resIndex;
Resource *scriptResource = _vm->_res->load(resIndex);
_slots[slotIndex].size = scriptResource->size;
- _slots[slotIndex].data = new byte[_slots[slotIndex].size];
- memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
+ _slots[slotIndex].data = new byte[_slots[slotIndex].size];
+ memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
}
void ScriptInterpreter::setMainScript(uint slotIndex) {
@@ -852,7 +852,7 @@ void ScriptInterpreter::sfFindMouseInRectIndex2() {
}
void ScriptInterpreter::sfDrawGuiImage() {
- _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
+ _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
}
void ScriptInterpreter::sfAddAnimatedSpriteNoLoop() {
diff --git a/engines/toltecs/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/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 188facd63c..8bd824cfee 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -235,7 +235,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
byte *source = scene + 392;
byte *destp = _screen->_backScreen;
byte *destEnd = destp + _sceneWidth * _sceneHeight;
- while (destp < destEnd) {
+ while (destp < destEnd) {
int count = 1;
byte pixel = *source++;
if (pixel & 0x80) {
@@ -250,7 +250,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
debug(0, "_sceneWidth = %d; _sceneHeight = %d", _sceneWidth, _sceneHeight);
// Load scene segmap
- _segmap->load(scene + imageSize + 4);
+ _segmap->load(scene + imageSize + 4);
_screen->_fullRefresh = true;
_screen->_renderQueue->clear();
@@ -574,9 +574,9 @@ void ToltecsEngine::walk(byte *walkData) {
if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
v10 = 100 - walkInfo.scaling;
v11 = v8;
- } else {
+ } else {
v10 = v8;
- v11 = 100 - walkInfo.scaling;
+ v11 = 100 - walkInfo.scaling;
}
walkInfo.yerror += walkInfo.mulValue * v10;
diff --git a/engines/tony/configure.engine b/engines/tony/configure.engine
new file mode 100644
index 0000000000..f85f45d158
--- /dev/null
+++ b/engines/tony/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
diff --git a/engines/tony/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/detection_tables.h b/engines/tony/detection_tables.h
index ee137927dc..ca16495903 100644
--- a/engines/tony/detection_tables.h
+++ b/engines/tony/detection_tables.h
@@ -196,6 +196,40 @@ static const TonyGameDescription gameDescriptions[] = {
},
},
+ {
+ // Tony Tough English Unpacked
+ {
+ "tony",
+ 0,
+ {
+ {"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071},
+ {"roasted.mpc", 0, "57c4a3860cf899443c357e0078ea6f49", 366773},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
+ // Tony Tough German "Shoe Box", reported in bug #3582420
+ {
+ "tony",
+ 0,
+ {
+ {"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071},
+ {"roasted.mpc", 0, "bc3471f098e591dc509dcad401a8d8a5", 389554},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
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..3433ad3024 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -117,6 +117,7 @@ RMGfxBuffer::operator void *() {
}
RMGfxBuffer::RMGfxBuffer(int dimx, int dimy, int nBpp) {
+ _origBuf = _buf = NULL;
create(dimx, dimy, nBpp);
}
@@ -1865,7 +1866,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/gfxengine.cpp b/engines/tony/gfxengine.cpp
index cb27e20ab1..7bb25f59b9 100644
--- a/engines/tony/gfxengine.cpp
+++ b/engines/tony/gfxengine.cpp
@@ -530,7 +530,10 @@ void RMGfxEngine::disableMouse() {
#define TONY_SAVEGAME_VERSION 8
void RMGfxEngine::saveState(const Common::String &fn, byte *curThumb, const Common::String &name) {
- Common::OutSaveFile *f;
+ Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(fn);
+ if (f == NULL)
+ return;
+
byte *state;
char buf[4];
RMPoint tp = _tony.position();
@@ -549,10 +552,6 @@ void RMGfxEngine::saveState(const Common::String &fn, byte *curThumb, const Comm
buf[2] = 'S';
buf[3] = TONY_SAVEGAME_VERSION;
- f = g_system->getSavefileManager()->openForSaving(fn);
- if (f == NULL)
- return;
-
f->write(buf, 4);
f->writeUint32LE(thumbsize);
f->write(curThumb, thumbsize);
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 1a24c5a576..5f2452dcfe 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -409,7 +409,7 @@ static uint32 *getSelectList(uint32 i) {
sl[k++] = dialog->_choice[i]._select[j]._dwData;
}
- sl[k] = (uint32)NULL;
+ sl[k] = 0;
return sl;
}
@@ -436,7 +436,7 @@ static uint32 *GetItemList(uint32 nLoc) {
}
}
- il[j] = (uint32)NULL;
+ il[j] = 0;
return il;
}
@@ -521,14 +521,15 @@ static LpItem getItemData(uint32 nOrdItem) {
dat += dim;
}
- // Check if we've got to the end of the file
int i = READ_LE_UINT16(dat);
- if (i != 0xABCD)
- return NULL;
globalUnlock(hDat);
globalFree(hDat);
+ // Check if we've got to the end of the file
+ if (i != 0xABCD)
+ return NULL;
+
return ret;
}
@@ -831,7 +832,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
if (_ctx->k == 0)
// We can remove this item from the list
- _ctx->il[_ctx->i] = (uint32)NULL;
+ _ctx->il[_ctx->i] = 0;
else
_ctx->nRealItems++;
}
@@ -1875,14 +1876,11 @@ MpalHandle mpalQueryHANDLE(uint16 wQueryType, ...) {
* @remarks This is the specialised version of the original single mpalQuery
* method that needs to run within a co-routine context.
*/
-void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...) {
+void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet) {
CORO_BEGIN_CONTEXT;
uint32 dwRet;
CORO_END_CONTEXT(_ctx);
- va_list v;
- va_start(v, dwRet);
-
CORO_BEGIN_CODE(_ctx);
if (wQueryType == MPQ_DIALOG_WAITFORCHOICE) {
@@ -1908,8 +1906,6 @@ void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...) {
}
CORO_END_CODE;
-
- va_end(v);
}
/**
@@ -1939,7 +1935,7 @@ bool mpalExecuteScript(int nScript) {
// !!! New process management
if (CoroScheduler.createProcess(ScriptThread, &s, sizeof(LpMpalScript)) == CORO_INVALID_PID_VALUE)
- return false;
+ return false;
return true;
}
@@ -2039,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();
}
@@ -2054,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/mpal/mpal.h b/engines/tony/mpal/mpal.h
index 779bdd6188..2d22ee8faf 100644
--- a/engines/tony/mpal/mpal.h
+++ b/engines/tony/mpal/mpal.h
@@ -417,7 +417,7 @@ MpalHandle mpalQueryHANDLE(uint16 wQueryType, ...);
* @remarks This is the specialised version of the original single mpalQuery
* method that needs to run within a co-routine context.
*/
-void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...);
+void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet);
/**
* Execute a script. The script runs on multitasking by a thread.
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..19e997af34 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -41,7 +41,7 @@ bool Animation::loadAnimation(const Common::String &file) {
if (strncmp((char *)fileData, "KevinAguilar", 12))
return false;
- strcpy(_name, file.c_str());
+ Common::strlcpy(_name, file.c_str(), 32);
uint32 headerSize = READ_LE_UINT32(fileData + 16);
uint32 uncompressedBytes = READ_LE_UINT32(fileData + 20);
@@ -52,6 +52,7 @@ bool Animation::loadAnimation(const Common::String &file) {
_x2 = READ_LE_UINT32(fileData + 40);
_y2 = READ_LE_UINT32(fileData + 44);
_paletteEntries = READ_LE_UINT32(fileData + 56);
+ // CHECKME: Useless variable _fps
_fps = READ_LE_UINT32(fileData + 60);
uint32 paletteSize = READ_LE_UINT32(fileData + 64);
@@ -119,6 +120,10 @@ Animation::Animation(ToonEngine *vm) : _vm(vm) {
_palette = NULL;
_numFrames = 0;
_frames = NULL;
+
+ _x1 = _y1 = _x2 = _y2 = 0;
+ _fps = 0;
+ _paletteEntries = 0;
}
Animation::~Animation() {
@@ -190,7 +195,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 +236,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 +346,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++) {
@@ -448,6 +453,7 @@ AnimationInstance::AnimationInstance(ToonEngine *vm, AnimationInstanceType type)
_y = 0;
_z = 0;
_layerZ = 0;
+ _visible = false;
}
void AnimationInstance::render() {
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index bc0e051057..303f6774fa 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -228,6 +228,7 @@ void AudioManager::stopMusic() {
AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream , bool looping, bool deleteFileStreamAtEnd) {
_compBufferSize = 0;
_buffer = NULL;
+ _bufferSize = 0;
_bufferMaxSize = 0;
_mixer = mixer;
_compBuffer = NULL;
@@ -255,6 +256,8 @@ AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer,
} else {
stopNow();
}
+
+ _soundType = Audio::Mixer::kPlainSoundType;
}
AudioStreamInstance::~AudioStreamInstance() {
diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp
index 479f4965f3..baab8888cf 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -58,12 +58,14 @@ Character::Character(ToonEngine *vm) : _vm(vm) {
_animSpecialDefaultId = 0;
_currentPathNode = 0;
_currentWalkStamp = 0;
+ _currentFacingStamp = 0;
_visible = true;
_speed = 150; // 150 = nominal drew speed
_lastWalkTime = 0;
_numPixelToWalk = 0;
_nextIdleTime = _vm->_system->getMillis() + (_vm->randRange(0, 600) + 300) * _vm->getTickLength();
_lineToSayId = 0;
+ _time = 0;
}
Character::~Character(void) {
@@ -99,6 +101,9 @@ void Character::setFacing(int32 facing) {
if (_blockingWalk) {
_flags |= 2;
+ _currentFacingStamp++;
+ int32 localFacingStamp = _currentFacingStamp;
+
int32 dir = 0;
_lastWalkTime = _vm->_system->getMillis();
@@ -127,6 +132,11 @@ void Character::setFacing(int32 facing) {
else
playWalkAnim(0, 0);
_vm->doFrame();
+
+ if (_currentFacingStamp != localFacingStamp) {
+ // another setFacing was started in doFrame, we need to cancel this one.
+ return;
+ }
};
_flags &= ~2;
diff --git a/engines/toon/character.h b/engines/toon/character.h
index d33c314bf7..b248e7ccf2 100644
--- a/engines/toon/character.h
+++ b/engines/toon/character.h
@@ -143,6 +143,7 @@ protected:
Common::Array<Common::Point> _currentPath;
uint32 _currentPathNode;
int32 _currentWalkStamp;
+ int32 _currentFacingStamp;
};
} // End of namespace Toon
diff --git a/engines/toon/configure.engine b/engines/toon/configure.engine
new file mode 100644
index 0000000000..00c98f7d8a
--- /dev/null
+++ b/engines/toon/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine toon "Toonstruck" yes
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index e26ed92f83..2ba4eff652 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -32,6 +32,8 @@ FontRenderer::FontRenderer(ToonEngine *vm) : _vm(vm) {
_currentFontColor[1] = 0xc8;
_currentFontColor[2] = 0xcb;
_currentFontColor[3] = 0xce;
+
+ _currentFont = nullptr;
}
FontRenderer::~FontRenderer() {
@@ -195,8 +197,7 @@ void FontRenderer::renderMultiLineText(int16 x, int16 y, const Common::String &o
// divide the text in several lines
// based on number of characters or size of lines.
byte text[1024];
- strncpy((char *)text, origText.c_str(), 1023);
- text[1023] = 0;
+ Common::strlcpy((char *)text, origText.c_str(), 1024);
byte *lines[16];
int32 lineSize[16];
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index 8c85e20f7c..9e8514d0a8 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -85,7 +85,8 @@ void Movie::play(const Common::String &video, int32 flags) {
_playing = true;
if (flags & 1)
_vm->getAudioManager()->setMusicVolume(0);
- _decoder->loadFile(video.c_str());
+ if (!_decoder->loadFile(video.c_str()))
+ error("Unable to play video %s", video.c_str());
playVideo(isFirstIntroVideo);
_vm->flushPalette(true);
if (flags & 1)
@@ -94,7 +95,7 @@ void Movie::play(const Common::String &video, int32 flags) {
_playing = false;
}
-bool Movie::playVideo(bool isFirstIntroVideo) {
+void Movie::playVideo(bool isFirstIntroVideo) {
debugC(1, kDebugMovie, "playVideo(isFirstIntroVideo: %d)", isFirstIntroVideo);
_decoder->start();
@@ -112,7 +113,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) {
@@ -135,13 +136,13 @@ bool Movie::playVideo(bool isFirstIntroVideo) {
while (_vm->_system->getEventManager()->pollEvent(event))
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
_vm->dirtyAllScreen();
- return false;
+ return;
}
_vm->_system->delayMillis(10);
}
_vm->dirtyAllScreen();
- return !_vm->shouldQuit();
+ return;
}
} // End of namespace Toon
diff --git a/engines/toon/movie.h b/engines/toon/movie.h
index 4dd6583bf6..14287d87fd 100644
--- a/engines/toon/movie.h
+++ b/engines/toon/movie.h
@@ -53,9 +53,8 @@ public:
bool isPlaying() { return _playing; }
protected:
- bool playVideo(bool isFirstIntroVideo);
+ void playVideo(bool isFirstIntroVideo);
ToonEngine *_vm;
- Audio::Mixer *_mixer;
ToonstruckSmackerDecoder *_decoder;
bool _playing;
};
diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp
index 7914aed595..336847e73c 100644
--- a/engines/toon/path.cpp
+++ b/engines/toon/path.cpp
@@ -152,6 +152,8 @@ PathFinding::PathFinding() {
_heap = new PathFindingHeap();
_sq = NULL;
_numBlockingRects = 0;
+
+ _currentMask = nullptr;
}
PathFinding::~PathFinding(void) {
diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp
index f59cdca064..4927f50e08 100644
--- a/engines/toon/picture.cpp
+++ b/engines/toon/picture.cpp
@@ -134,6 +134,11 @@ bool Picture::loadPicture(const Common::String &file) {
Picture::Picture(ToonEngine *vm) : _vm(vm) {
_data = NULL;
_palette = NULL;
+
+ _width = 0;
+ _height = 0;
+ _paletteEntries = 0;
+ _useFullPalette = false;
}
Picture::~Picture() {
@@ -170,7 +175,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 +210,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 +238,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/resource.cpp b/engines/toon/resource.cpp
index 2d419ec027..ffcabbd348 100644
--- a/engines/toon/resource.cpp
+++ b/engines/toon/resource.cpp
@@ -285,6 +285,7 @@ void PakFile::close() {
}
PakFile::PakFile() {
+ _numFiles = 0;
}
PakFile::~PakFile() {
diff --git a/engines/toon/resource.h b/engines/toon/resource.h
index c80ac2216e..b432a1d335 100644
--- a/engines/toon/resource.h
+++ b/engines/toon/resource.h
@@ -53,7 +53,6 @@ protected:
uint32 _numFiles;
Common::Array<File> _files;
- Common::File *_fileHandle;
};
class ToonEngine;
diff --git a/engines/toon/script.cpp b/engines/toon/script.cpp
index 69ae727bb5..d752c277db 100644
--- a/engines/toon/script.cpp
+++ b/engines/toon/script.cpp
@@ -59,6 +59,8 @@ EMCInterpreter::EMCInterpreter(ToonEngine *vm) : _vm(vm), _scriptData(0), _filen
};
_opcodes = opcodes;
#undef OPCODE
+
+ _parameter = 0;
}
EMCInterpreter::~EMCInterpreter() {
@@ -132,8 +134,7 @@ bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Commo
_scriptData->sysFuncs = opcodes;
- strncpy(_scriptData->filename, filename, 13);
- _scriptData->filename[12] = 0;
+ Common::strlcpy(_scriptData->filename, filename, 13);
_scriptData = 0;
_filename = 0;
diff --git a/engines/toon/script_func.cpp b/engines/toon/script_func.cpp
index 1fa4058114..70baaaef22 100644
--- a/engines/toon/script_func.cpp
+++ b/engines/toon/script_func.cpp
@@ -1060,9 +1060,9 @@ int32 ScriptFunc::sys_Cmd_Set_Location_Data(EMCState *state) {
// initial setup of locations
int32 locationId = stackPos(0);
debugC(0, 0, "setlocationdata(%d) %s %x %s %s %d %d", locationId, GetText(1, state), stackPos(2), GetText(3, state), GetText(4, state), stackPos(5), stackPos(6));
- strcpy(_vm->state()->_locations[locationId]._name, GetText(1, state));
- strcpy(_vm->state()->_locations[locationId]._music, GetText(3, state));
- strcpy(_vm->state()->_locations[locationId]._cutaway, GetText(4, state));
+ Common::strlcpy(_vm->state()->_locations[locationId]._name, GetText(1, state), 64);
+ Common::strlcpy(_vm->state()->_locations[locationId]._music, GetText(3, state), 64);
+ Common::strlcpy(_vm->state()->_locations[locationId]._cutaway, GetText(4, state), 64);
_vm->state()->_locations[locationId]._flags = stackPos(2);
_vm->state()->_locations[locationId]._visited = false;
_vm->state()->_locations[locationId]._numSceneAnimations = stackPos(5);
diff --git a/engines/toon/state.cpp b/engines/toon/state.cpp
index 8e4abbd709..fffa8cf529 100644
--- a/engines/toon/state.cpp
+++ b/engines/toon/state.cpp
@@ -115,6 +115,10 @@ State::State(void) {
#endif
memset(_conversationState, 0, sizeof(Conversation) * 60);
+
+ _conversationData = nullptr;
+ _currentConversationId = -1;
+ _exitConversation = true;
}
State::~State(void) {
diff --git a/engines/toon/tools.cpp b/engines/toon/tools.cpp
index added39940..f5c77aca69 100644
--- a/engines/toon/tools.cpp
+++ b/engines/toon/tools.cpp
@@ -136,6 +136,13 @@ uint32 decompressSPCN(byte *src, byte *dst, uint32 dstsize) {
RncDecoder::RncDecoder() {
initCrc();
+
+ _bitBuffl = 0;
+ _bitBuffh = 0;
+ _bitCount = 0;
+ _srcPtr = nullptr;
+ _dstPtr = nullptr;
+ _inputByteLeft = 0;
}
RncDecoder::~RncDecoder() { }
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 7ad29ab8d8..7b1456b05c 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);
}
}
}
@@ -924,6 +922,48 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription)
_gameVariant = 0;
break;
}
+
+ for (int i = 0; i < 64; i++) {
+ _sceneAnimationScripts[i]._lastTimer = 0;
+ _sceneAnimationScripts[i]._frozen = false;
+ _sceneAnimationScripts[i]._frozenForConversation = false;
+ _sceneAnimationScripts[i]._active = false;
+ }
+
+ _lastProcessedSceneScript = 0;
+ _animationSceneScriptRunFlag = false;
+ _updatingSceneScriptRunFlag = false;
+ _dirtyAll = false;
+ _cursorOffsetX = 0;
+ _cursorOffsetY = 0;
+ _currentTextLine = 0;
+ _currentTextLineId = 0;
+ _currentTextLineX = 0;
+ _currentTextLineY = 0;
+ _currentTextLineCharacterId = -1;
+ _oldScrollValue = 0;
+ _drew = nullptr;
+ _flux = nullptr;
+ _currentHotspotItem = 0;
+ _shouldQuit = false;
+ _scriptStep = 0;
+ _oldTimer = 0;
+ _oldTimer2 = 0;
+ _lastRenderTime = 0;
+ _firstFrame = false;
+ _needPaletteFlush = true;
+
+ _numVariant = 0;
+ _currentCutaway = nullptr;
+ for (int i = 0; i < 4; i++) {
+ _scriptState[i].ip = nullptr;
+ _scriptState[i].dataPtr = nullptr;
+ _scriptState[i].retValue = 0;
+ _scriptState[i].bp = 0;
+ _scriptState[i].sp = 0;
+ _scriptState[i].running = false;
+ }
+ _currentScriptRegion = 0;
}
ToonEngine::~ToonEngine() {
diff --git a/engines/touche/configure.engine b/engines/touche/configure.engine
new file mode 100644
index 0000000000..777578e623
--- /dev/null
+++ b/engines/touche/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 5c133ccbc6..b3e3ca5b50 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -51,6 +51,28 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
_saveLoadCurrentSlot = 0;
_hideInventoryTexts = false;
+ _numOpcodes = 0;
+ _compressedSpeechData = 0;
+ _textData = 0;
+ _backdropBuffer = 0;
+ _menuKitData = 0;
+ _convKitData = 0;
+
+ for (int i = 0; i < NUM_SEQUENCES; i++)
+ _sequenceDataTable[i] = 0;
+
+ _programData = 0;
+ _programDataSize = 0;
+ _mouseData = 0;
+ _iconData = 0;
+ _currentBitmapWidth = 0;
+ _currentBitmapHeight = 0;
+ _currentImageWidth = 0;
+ _currentImageHeight = 0;
+ _roomWidth = 0;
+ _programTextDataPtr = 0;
+ _offscreenBuffer = 0;
+
_screenRect = Common::Rect(kScreenWidth, kScreenHeight);
_roomAreaRect = Common::Rect(kScreenWidth, kRoomHeight);
@@ -88,6 +110,63 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
DebugMan.addDebugChannel(kDebugCharset, "Charset", "Charset debug level");
_console = new ToucheConsole(this);
+
+ _newEpisodeNum = 0;
+ _currentEpisodeNum = 0;
+ _currentAmountOfMoney = 0;
+ _giveItemToKeyCharNum = 0;
+ _giveItemToObjectNum = 0;
+ _giveItemToCounter = 0;
+ _currentRoomNum = 0;
+ _waitingSetKeyCharNum1 = 0;
+ _waitingSetKeyCharNum2 = 0;
+ _waitingSetKeyCharNum3 = 0;
+ _script.opcodeNum = 0;
+ _script.dataOffset = 0;
+ _script.keyCharNum = 0;
+ _script.dataPtr = 0;
+ _script.stackDataPtr = 0;
+ _script.stackDataBasePtr = 0;
+ _script.quitFlag = 0;
+ _opcodesTable = 0;
+
+ for (uint i = 0; i < NUM_SPRITES; i++)
+ memset(&_spritesTable[i], 0, sizeof(SpriteData));
+
+ for (uint i = 0; i < NUM_SEQUENCES; i++)
+ memset(&_sequenceEntryTable[i], 0, sizeof(SequenceEntry));
+
+ _talkListEnd = 0;
+ _talkListCurrent = 0;
+ _talkTextRectDefined = 0;
+ _talkTextDisplayed = 0;
+ _talkTextInitialized = 0;
+ _skipTalkText = 0;
+ _talkTextSpeed = 0;
+ _keyCharTalkCounter = 0;
+ _talkTableLastTalkingKeyChar = 0;
+ _talkTableLastOtherKeyChar = 0;
+ _talkTableLastStringNum = 0;
+
+ for (uint i = 0; i < NUM_TALK_ENTRIES; i++)
+ memset(&_talkTable[i], 0, sizeof(TalkEntry));
+
+ _conversationChoicesUpdated = 0;
+ _conversationReplyNum = 0;
+ _conversationEnded = 0;
+ _conversationNum = 0;
+ _scrollConversationChoiceOffset = 0;
+ _currentConversation = 0;
+ _disableConversationScript = 0;
+ _conversationAreaCleared = 0;
+
+ for (uint i = 0; i < NUM_CONVERSATION_CHOICES; i++)
+ memset(&_conversationChoicesTable[i], 0, sizeof(ConversationChoice));
+
+ for (uint i = 0; i < NUM_KEYCHARS; i++)
+ _sortedKeyCharsTable[i] = 0;
+
+ _currentKeyCharNum = 0;
}
ToucheEngine::~ToucheEngine() {
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index 6ac43e7dfe..9cc42b0c68 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -102,7 +102,7 @@ struct KeyChar {
int16 zPosPrev;
int16 prevWalkDataNum;
uint16 textColor;
- int16 inventoryItems[4];
+ int16 inventoryItems[5];
int16 money;
int16 pointsDataNum;
int16 currentWalkBox;
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 3aef18f4f0..be5fb4c7b7 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -454,9 +454,10 @@ void Timer::dispatch() {
if (_endFrame) {
uint32 frameNumber = BF_GLOBALS._events.getFrameNumber();
- if (frameNumber > _endFrame)
+ if (frameNumber > _endFrame) {
// Timer has expired
signal();
+ }
}
}
@@ -472,7 +473,8 @@ void Timer::set(uint32 delay, EventHandler *endHandler) {
/*--------------------------------------------------------------------------*/
TimerExt::TimerExt(): Timer() {
- _action = NULL;
+ _action = nullptr;
+ _newAction = nullptr;
}
void TimerExt::set(uint32 delay, EventHandler *endHandler, Action *newAction) {
@@ -646,8 +648,6 @@ void FocusObject::postInit(SceneObjectList *OwnerList) {
_lookLineNum = 43;
_talkLineNum = 44;
_useLineNum = -1;
- _v90 = 0;
- _v92 = 1;
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
scene->_focusObject = this;
@@ -656,8 +656,11 @@ void FocusObject::postInit(SceneObjectList *OwnerList) {
void FocusObject::synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v90);
- s.syncAsSint16LE(_v92);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
}
void FocusObject::remove() {
@@ -678,7 +681,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;
}
@@ -703,7 +706,6 @@ SceneExt::SceneExt(): Scene() {
_stripManager._onBegin = SceneExt::startStrip;
_stripManager._onEnd = SceneExt::endStrip;
- _field372 = _field37A = 0;
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
@@ -746,6 +748,7 @@ void SceneExt::process(Event &event) {
void SceneExt::dispatch() {
_timerList.dispatch();
+ /*
if (_field37A) {
if ((--_field37A == 0) && BF_GLOBALS._dayNumber) {
if (T2_GLOBALS._uiElements._active && BF_GLOBALS._player._enabled) {
@@ -755,6 +758,7 @@ void SceneExt::dispatch() {
_field37A = 0;
}
}
+ */
Scene::dispatch();
}
@@ -762,8 +766,6 @@ void SceneExt::dispatch() {
void SceneExt::loadScene(int sceneNum) {
Scene::loadScene(sceneNum);
- _v51C34.top = 0;
- _v51C34.bottom = 300;
BF_GLOBALS._sceneHandler->_delayTicks = 1;
}
@@ -831,7 +833,6 @@ void SceneExt::gunDisplay() {
void SceneExt::startStrip() {
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
- scene->_field372 = 1;
scene->_savedPlayerEnabled = BF_GLOBALS._player._enabled;
if (scene->_savedPlayerEnabled) {
@@ -839,21 +840,20 @@ void SceneExt::startStrip() {
scene->_savedCanWalk = BF_GLOBALS._player._canWalk;
BF_GLOBALS._player.disableControl();
- if (!BF_GLOBALS._v50696 && T2_GLOBALS._uiElements._active)
+ if (T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
}
}
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._player._uiEnabled = scene->_savedUiEnabled;
BF_GLOBALS._player._canWalk = scene->_savedCanWalk;
- if (!BF_GLOBALS._v50696 && T2_GLOBALS._uiElements._active)
+ if (T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.show();
}
}
@@ -865,30 +865,29 @@ void SceneExt::clearScreen() {
/*--------------------------------------------------------------------------*/
PalettedScene::PalettedScene(): SceneExt() {
- _field794 = 0;
+ _hasFader = false;
}
void PalettedScene::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field794);
+ s.syncAsSint16LE(_hasFader);
}
void PalettedScene::postInit(SceneObjectList *OwnerList) {
- _field794 = 0;
+ _hasFader = false;
_palette._field412 = 1;
SceneExt::postInit(OwnerList);
}
void PalettedScene::remove() {
SceneExt::remove();
- if (_field794 == 1) {
+ if (_hasFader) {
for (SynchronizedList<SceneObject *>::iterator i = BF_GLOBALS._sceneObjects->begin();
i != BF_GLOBALS._sceneObjects->end(); ++i)
(*i)->remove();
BF_GLOBALS._sceneObjects->draw();
BF_GLOBALS._scenePalette.loadPalette(2);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager._hasPalette = true;
}
@@ -896,7 +895,7 @@ void PalettedScene::remove() {
}
PaletteFader *PalettedScene::addFader(const byte *arrBufferRGB, int step, Action *action) {
- _field794 = 1;
+ _hasFader = true;
return BF_GLOBALS._scenePalette.addFader(arrBufferRGB, 1, step, action);
}
@@ -909,6 +908,7 @@ void PalettedScene::add2Faders(const byte *arrBufferRGB, int step, int paletteNu
void PalettedScene::transition(const byte *arrBufferRGB, int percent, int paletteNum, Action *action, int fromColor1, int fromColor2, int toColor1, int toColor2, bool flag) {
byte tmpPalette[768];
+ memset(tmpPalette, 0, 768);
_palette.loadPalette(paletteNum);
_palette.loadPalette(2);
@@ -1260,8 +1260,6 @@ void BlueForceInvObjectList::alterInventory(int mode) {
setObjectScene(INV_TICKET_BOOK, 60);
setObjectScene(INV_MIRANDA_CARD, 60);
- BF_GLOBALS._v4CEC4 = 0;
-
switch (mode) {
case 2:
if (hasPrintout)
diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 59bc2b7a51..0045980820 100644
--- a/engines/tsage/blue_force/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -139,14 +139,17 @@ public:
class NamedObject2: public NamedObject {
public:
- int _v1, _v2;
+ int _talkCount;
- NamedObject2() { _v1 = _v2 = 0; }
+ NamedObject2() { _talkCount = 0; }
virtual Common::String getClassName() { return "NamedObject2"; }
virtual void synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v1);
- s.syncAsSint16LE(_v2);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
+ s.syncAsSint16LE(_talkCount);
}
};
@@ -177,7 +180,6 @@ public:
class FocusObject: public NamedObject {
public:
- int _v90, _v92;
GfxSurface _img;
FocusObject();
@@ -196,16 +198,12 @@ private:
static void endStrip();
public:
AObjectArray _timerList, _objArray2;
- int _field372;
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
- int _field37A;
EventHandler *_focusObject;
Visage _cursorVisage;
-
- Rect _v51C34;
public:
SceneExt();
@@ -228,7 +226,7 @@ public:
class PalettedScene: public SceneExt {
public:
ScenePalette _palette;
- int _field794;
+ bool _hasFader;
public:
PalettedScene();
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index 95598babc6..06be605c1a 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -343,7 +343,7 @@ void Scene50::synchronize(Serializer &s) {
void Scene50::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
T2_GLOBALS._uiElements._active = false;
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setVisage(830);
@@ -419,6 +419,8 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
tooltip = &_location8;
xp = 75;
break;
+ default:
+ error("Unexpected tooltip value %d", selectedTooltip);
}
_timer.set(240, this);
@@ -888,6 +890,7 @@ void Scene60::Action1::signal() {
break;
case 4:
remove();
+ break;
case 5:
setDelay(120);
break;
@@ -939,7 +942,6 @@ void Scene60::Action3::signal() {
scene->_stripManager.start(71, this);
break;
case 2:
- scene->_field1222 = true;
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -953,7 +955,6 @@ Scene60::Scene60(): SceneExt() {
_sceneNumber = 0;
_visage = 0;
_cursorId = CURSOR_NONE;
- _field1222 = false;
}
void Scene60::synchronize(Serializer &s) {
@@ -963,7 +964,10 @@ void Scene60::synchronize(Serializer &s) {
s.syncAsSint16LE(_sceneNumber);
s.syncAsSint16LE(_visage);
s.syncAsSint16LE(_cursorId);
- s.syncAsSint16LE(_field1222);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene60::postInit(SceneObjectList *OwnerList) {
diff --git a/engines/tsage/blue_force/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h
index dd502c5f30..e7ee06e779 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.h
+++ b/engines/tsage/blue_force/blueforce_scenes0.h
@@ -174,8 +174,6 @@ public:
int _sceneNumber;
int _visage;
CursorType _cursorId;
- // TODO: Check if really useless in original
- bool _field1222;
Scene60();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index 9f1e9ce36e..fa877ea6c9 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -176,7 +176,6 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
loadScene(101);
}
BF_GLOBALS._scenePalette.loadPalette(2);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
g_globals->_player.postInit();
@@ -232,7 +231,6 @@ void Scene109::Action1::signal() {
scene->_text.setup(BF_19840515, this);
break;
case 3:
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(115);
scene->_protaginist2.show();
@@ -246,7 +244,6 @@ void Scene109::Action1::signal() {
scene->_beerSign.show();
scene->_beerSign.setAction(&scene->_action2);
- BF_GLOBALS._v501FC = 170;
setDelay(60);
break;
case 4:
@@ -401,12 +398,10 @@ void Scene110::Action1::signal() {
scene->_object6.show();
scene->_object9.show();
scene->_object10.show();
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(110);
setDelay(10);
break;
case 2:
- BF_GLOBALS._v51C44 = 1;
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 3: {
@@ -1833,8 +1828,6 @@ void Scene125::Action2::signal() {
setDelay(20);
break;
case 2: {
- BF_GLOBALS._v501FA = 10;
- BF_GLOBALS._v51C44 = 1;
Common::Point destPos(202, 94);
NpcMover *mover = new NpcMover();
BF_GLOBALS._player.addMover(mover, &destPos, this);
@@ -2311,7 +2304,6 @@ void Scene140::Action1::signal() {
setDelay(60);
// No break on purpose
case 13:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(150);
default:
break;
@@ -2337,9 +2329,6 @@ void Scene140::postInit(SceneObjectList *OwnerList) {
_object1.changeZoom(100);
_object1.hide();
- BF_GLOBALS._v5020C = 0;
- BF_GLOBALS._v501F8 = 300;
- BF_GLOBALS._v501FC = 90;
BF_GLOBALS._sound1.play(7);
_object2.setAction(&_action1);
@@ -2640,7 +2629,6 @@ void Scene160::Action2::signal() {
BF_GLOBALS._sound1.stop();
// End of hack
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(200);
break;
default:
@@ -2649,7 +2637,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) {
@@ -2788,9 +2776,6 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
setZoomPercents(121, 60, 125, 70);
if ((BF_GLOBALS._bookmark == bLyleStoppedBy) && (BF_GLOBALS._dayNumber == 1)) {
- BF_GLOBALS._v501FC = 87;
- BF_GLOBALS._v501FA = _sceneBounds.left + 10;
- // CHECKME: BF_GLOBALS._v50206 = 18; ??
_sceneMessage.setup(THE_NEXT_DAY);
_sceneMode = 6;
setAction(&_sceneMessage, this);
@@ -2799,9 +2784,6 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._mapLocationId = 4;
} else if (((BF_GLOBALS._bookmark == bDroppedOffLyle) && (BF_GLOBALS._dayNumber == 3)) ||
((BF_GLOBALS._bookmark == bDoneAtLyles) && (BF_GLOBALS._dayNumber == 4))) {
- BF_GLOBALS._v501FC = 87;
- BF_GLOBALS._v501FA = _sceneBounds.left + 10;
- // CHECKME: BF_GLOBALS._v50206 = 18; ??
_sceneMessage.setup(THE_NEXT_DAY);
_sceneMode = 6;
setAction(&_sceneMessage, this);
@@ -3237,7 +3219,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_scenes2.cpp b/engines/tsage/blue_force/blueforce_scenes2.cpp
index c992afe620..1b0ed2a145 100644
--- a/engines/tsage/blue_force/blueforce_scenes2.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes2.cpp
@@ -1603,7 +1603,6 @@ void Scene271::signal() {
}
break;
case 12:
- BF_GLOBALS._v51C44 = 0;
BF_GLOBALS._sound1.changeSound(67);
BF_GLOBALS._sceneManager.changeScene(280);
break;
@@ -1617,7 +1616,6 @@ void Scene271::signal() {
_field2E16 = 1;
break;
case 2704:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sound1.fadeOut2(NULL);
BF_GLOBALS._sceneManager.changeScene(690);
break;
@@ -1649,7 +1647,6 @@ void Scene271::signal() {
addFader((const byte *)&black, 2, this);
break;
case 2712:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sound1.fadeOut2(NULL);
BF_GLOBALS._sceneManager.changeScene(180);
break;
@@ -1657,7 +1654,6 @@ void Scene271::signal() {
BF_GLOBALS._player.enableControl();
break;
case 2714:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(560);
break;
case 2715:
diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp
index 81e4af6e97..feaf789392 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes3.cpp
@@ -564,7 +564,6 @@ void Scene300::dispatch() {
if ((BF_GLOBALS._player._position.y < 59) && (BF_GLOBALS._player._position.x > 137) &&
(_sceneMode != 6308) && (_sceneMode != 7308)) {
- // The original was setting a useless global variable (removed)
_sceneMode = 6308;
BF_GLOBALS._player.disableControl();
ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 20,
@@ -967,7 +966,6 @@ void Scene315::Action1::signal() {
/*--------------------------------------------------------------------------*/
Scene315::Scene315() {
- BF_GLOBALS._v51C44 = 1;
_field1B6C = _field139C = 0;
if (BF_GLOBALS._dayNumber == 0)
BF_GLOBALS._dayNumber = 1;
@@ -977,12 +975,19 @@ Scene315::Scene315() {
_doorOpened = false;
_invGreenCount = _bookGreenCount = 0;
_invGangCount = _bookGangCount = 0;
+
+ _stripNumber = 0;
+ _field1398 = 0;
+ _currentCursor = INV_NONE;
}
void Scene315::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1390);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_stripNumber);
s.syncAsSint16LE(_field1398);
s.syncAsSint16LE(_invGreenCount);
@@ -1399,7 +1404,7 @@ bool Scene325::Item1::startAction(CursorType action, Event &event) {
void Scene325::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(325);
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
BF_GLOBALS.clearFlag(fCanDrawGun);
if (BF_GLOBALS._dayNumber == 0)
@@ -1973,12 +1978,7 @@ void Scene340::Action8::signal() {
setDelay(6);
break;
- case 4:
- remove();
- break;
default:
- // This is present in the original game
- warning("Bugs");
remove();
break;
}
@@ -2868,9 +2868,9 @@ void Scene350::checkGun() {
void Scene355::Doorway::synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v1);
- s.syncAsSint16LE(_v2);
- s.syncAsSint16LE(_v3);
+ s.syncAsSint16LE(_mode1356Count);
+ s.syncAsSint16LE(_talkCount);
+ s.syncAsSint16LE(_onDuty);
}
bool Scene355::Doorway::startAction(CursorType action, Event &event) {
@@ -2890,9 +2890,9 @@ bool Scene355::Doorway::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
if (BF_GLOBALS._dayNumber >= 5) {
- switch (_v2) {
+ switch (_talkCount) {
case 0:
- ++_v2;
+ ++_talkCount;
BF_GLOBALS._sound1.play(109);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
@@ -2920,7 +2920,7 @@ bool Scene355::Doorway::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 3562;
scene->setAction(&scene->_sequenceManager, scene, 3562, &BF_GLOBALS._player, NULL);
- _v3 = !_v3 ? 1 : 0;
+ _onDuty = !_onDuty;
return true;
default:
break;
@@ -3355,14 +3355,14 @@ bool Scene355::Item11::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
if (BF_GLOBALS._dayNumber == 5) {
- switch (scene->_doorway._v2) {
+ switch (scene->_doorway._talkCount) {
case 0:
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
BF_GLOBALS.setFlag(fTookTrailerAmmo);
scene->_stripManager.start(3575, scene);
scene->_lyle._flag = 1;
- scene->_doorway._v2 = 1;
+ scene->_doorway._talkCount = 1;
break;
case 1:
BF_GLOBALS._player.disableControl();
@@ -3534,28 +3534,28 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
_doorway.setVisage(355);
_doorway.setPosition(Common::Point(193, 105));
_doorway.fixPriority(18);
- _doorway._v1 = 0;
- _doorway._v3 = 0;
+ _doorway._mode1356Count = 0;
+ _doorway._onDuty = false;
BF_GLOBALS._sceneItems.push_back(&_doorway);
switch (BF_GLOBALS._dayNumber) {
case 1:
if (!BF_GLOBALS.getFlag(onDuty))
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
else if (BF_INVENTORY.getObjectScene(INV_GREENS_GUN) == 320)
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
break;
case 2:
case 3:
case 4:
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
break;
default:
break;
}
if (BF_GLOBALS._dayNumber == 5)
- _doorway._v2 = BF_GLOBALS.getFlag(fTookTrailerAmmo) ? 1 : 0;
+ _doorway._talkCount = BF_GLOBALS.getFlag(fTookTrailerAmmo) ? 1 : 0;
_object8.postInit();
_object8.setVisage(355);
@@ -3614,8 +3614,8 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
_object11.animate(ANIM_MODE_2);
_doorway.setPosition(Common::Point(146, 107));
- _doorway._v3 = 0;
- _doorway._v2 = 2;
+ _doorway._onDuty = false;
+ _doorway._talkCount = 2;
_lyle._flag = 2;
_green.postInit();
@@ -3713,16 +3713,16 @@ void Scene355::signal() {
_stripManager.start(BF_GLOBALS.getFlag(fBackupIn350) ? 3559 : 3554, this);
break;
case 1356:
- switch (_doorway._v1) {
+ switch (_doorway._mode1356Count) {
case 0:
- ++_doorway._v1;
+ ++_doorway._mode1356Count;
_sceneMode = 9999;
_stripManager.start(3550, this);
break;
case 1:
_sceneMode = 9999;
_stripManager.start(3551, this);
- ++_doorway._v1;
+ ++_doorway._mode1356Count;
break;
default:
break;
@@ -3787,7 +3787,7 @@ void Scene355::signal() {
T2_GLOBALS._uiElements.addScore(10);
}
- SceneItem::display2(355, !_doorway._v3 ? 24 : 25);
+ SceneItem::display2(355, !_doorway._onDuty ? 24 : 25);
BF_GLOBALS._player.enableControl();
break;
case 4550:
@@ -3796,8 +3796,8 @@ void Scene355::signal() {
BF_GLOBALS._sound1.play(90);
BF_GLOBALS._player._regionBitList |= 0x10;
- _doorway._v3 = 0;
- _doorway._v2 = 2;
+ _doorway._onDuty = false;
+ _doorway._talkCount = 2;
_lyle._flag = 2;
BF_GLOBALS._player.enableControl();
break;
@@ -3867,13 +3867,13 @@ void Scene355::signal() {
case 9984:
if (BF_GLOBALS._dayNumber == 5) {
_sceneMode = 0;
- switch (_doorway._v2) {
+ switch (_doorway._talkCount) {
case 0:
BF_GLOBALS._sound1.play(109);
BF_GLOBALS.setFlag(fTookTrailerAmmo);
_stripManager.start(3575, this);
_lyle._flag = 1;
- ++_doorway._v2;
+ ++_doorway._talkCount;
break;
case 1:
_stripManager.start(3573, this);
@@ -3884,7 +3884,7 @@ void Scene355::signal() {
break;
}
} else if (BF_GLOBALS.getFlag(greenTaken) || (BF_GLOBALS._dayNumber > 1)) {
- if (_doorway._v3) {
+ if (_doorway._onDuty) {
SceneItem::display2(355, 23);
_sceneMode = 0;
signal();
@@ -4009,14 +4009,14 @@ void Scene355::signal() {
}
case 9997:
_sceneMode = 9999;
- _doorway._v1 = 2;
+ _doorway._mode1356Count = 2;
_stripManager.start(3562, this);
break;
case 9998:
error("Talkdoor state");
break;
case 9999:
- if (_doorway._v1 != 2) {
+ if (_doorway._mode1356Count != 2) {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._player._canWalk = false;
} else if (BF_GLOBALS.getFlag(gunDrawn)) {
@@ -4439,7 +4439,6 @@ void Scene360::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.enableControl();
if ((BF_GLOBALS._sceneManager._previousScene == 355) || (BF_GLOBALS._sceneManager._previousScene != 370)) {
- // The original was using there a useless variable (now removed)
BF_GLOBALS._player.setPosition(Common::Point(253, 135));
BF_GLOBALS._player.setStrip(2);
@@ -4527,7 +4526,7 @@ void Scene360::signal() {
BF_GLOBALS._player.enableControl();
break;
case 3608:
- BF_GLOBALS._sceneManager.changeScene(355);
+ BF_GLOBALS._sceneManager.changeScene(355);
break;
case 3610:
BF_GLOBALS._sceneManager.changeScene(666);
@@ -4652,10 +4651,10 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
- SceneItem::display2(370, (_v2 < 3) ? 10 : 0);
+ SceneItem::display2(370, (_talkCount < 3) ? 10 : 0);
return true;
case CURSOR_USE:
- if (_v2 != 3)
+ if (_talkCount != 3)
SceneItem::display2(370, 1);
else if (BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1)
SceneItem::display2(370, 26);
@@ -4671,14 +4670,14 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
BF_GLOBALS._player.disableControl();
- switch (_v2) {
+ switch (_talkCount) {
case 0:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3706;
scene->setAction(&scene->_sequenceManager, scene, 3706, NULL);
break;
case 1:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3707;
scene->_object5.postInit();
@@ -4690,7 +4689,7 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3707, &scene->_harrison, &scene->_object5, NULL);
break;
case 2:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3708;
scene->setAction(&scene->_sequenceManager, scene, 3708, this, &scene->_laura, &scene->_harrison,
&scene->_object5, &scene->_greensGun, NULL);
@@ -4716,7 +4715,7 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
}
return true;
case INV_HANDCUFFS:
- if (_v2 != 3)
+ if (_talkCount != 3)
SceneItem::display2(370, 2);
else {
T2_GLOBALS._uiElements.addScore(50);
@@ -4753,7 +4752,7 @@ bool Scene370::Harrison::startAction(CursorType action, Event &event) {
SceneItem::display2(370, 8);
return true;
case CURSOR_TALK:
- if (scene->_green._v2 != 3) {
+ if (scene->_green._talkCount != 3) {
scene->_sceneMode = 3;
scene->_stripManager.start(3714, scene);
} else if ((BF_INVENTORY.getObjectScene(INV_GREENS_KNIFE) == 1) ||
diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h
index ea9d5f7311..894c3e5ffd 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.h
+++ b/engines/tsage/blue_force/blueforce_scenes3.h
@@ -210,7 +210,6 @@ public:
WestExit _westExit;
SouthWestExit _swExit;
Action1 _action1;
- int _field1390;
int _stripNumber;
int _field1398;
int _invGreenCount, _bookGreenCount, _invGangCount;
@@ -494,9 +493,10 @@ class Scene355: public PalettedScene {
/* Objects */
class Doorway: public NamedObject {
public:
- int _v1, _v2, _v3;
+ int _mode1356Count, _talkCount;
+ bool _onDuty;
- Doorway() { _v1 = _v2 = _v3 = 0; }
+ Doorway() { _mode1356Count = _talkCount = 0; _onDuty = false; }
virtual Common::String getClassName() { return "Scene355_Doorway"; }
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
diff --git a/engines/tsage/blue_force/blueforce_scenes4.cpp b/engines/tsage/blue_force/blueforce_scenes4.cpp
index a10f311791..e4a349bc93 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes4.cpp
@@ -39,7 +39,7 @@ namespace BlueForce {
void Scene410::Action1::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
- switch (scene->_field1FB6++) {
+ switch (scene->_action1Count++) {
case 0:
if (BF_GLOBALS.getFlag(fTalkedDriverNoBkup)) {
setDelay(3);
@@ -136,11 +136,11 @@ void Scene410::Action5::signal() {
switch (_actionIndex++) {
case 0:
- if (scene->_field1FC4 == 0) {
+ if (!scene->_harrisonMovedFl) {
ADD_PLAYER_MOVER(114, 133);
} else {
ADD_PLAYER_MOVER(195, 139);
- }
+ }
break;
case 1:
BF_GLOBALS._player.updateAngle(scene->_passenger._position);
@@ -167,7 +167,7 @@ void Scene410::Action6::signal() {
switch (_actionIndex++) {
case 0:
- if (scene->_field1FC4 == 0) {
+ if (!scene->_harrisonMovedFl) {
ADD_PLAYER_MOVER(114, 133);
} else {
ADD_PLAYER_MOVER(126, 99);
@@ -243,7 +243,7 @@ bool Scene410::Motorcycle::startAction(CursorType action, Event &event) {
} else if (BF_GLOBALS.getFlag(fSearchedTruck) && !BF_GLOBALS._sceneObjects->contains(&scene->_harrison)) {
scene->_sceneMode = 4103;
scene->signal();
- } else if (scene->_field1FBC != 0) {
+ } else if (scene->_cuffedDriverFl) {
SceneItem::display2(410, 12);
} else {
scene->_sceneMode = 4103;
@@ -260,7 +260,7 @@ bool Scene410::TruckFront::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if ((BF_GLOBALS._bookmark < bStoppedFrankie) && (!scene->_field1FBC || !scene->_field1FBA))
+ if ((BF_GLOBALS._bookmark < bStoppedFrankie) && (!scene->_cuffedDriverFl || !scene->_harrissonTalkFl))
break;
else if (BF_GLOBALS.getFlag(fSearchedTruck))
SceneItem::display2(410, 13);
@@ -293,11 +293,11 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
} else {
SceneItem::display2(410, 7);
}
- } else if (!scene->_field1FBC) {
+ } else if (!scene->_cuffedDriverFl) {
SceneItem::display2(410, 7);
} else if (!scene->_field1FC0) {
scene->_sceneMode = 4124;
- scene->_field1FC0 = 1;
+ scene->_field1FC0 = true;
T2_GLOBALS._uiElements.addScore(30);
scene->signal();
} else {
@@ -309,13 +309,13 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
return true;
case INV_HANDCUFFS:
if (BF_GLOBALS.getFlag(fCalledBackup)) {
- if ((scene->_talkCount < 5) || (scene->_field1FB6 < 1) || (scene->_field1FBC != 0))
+ if ((scene->_talkCount < 5) || (scene->_action1Count < 1) || scene->_cuffedDriverFl)
break;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4123;
scene->_stripManager.start(4125, scene);
- scene->_field1FBC = 1;
+ scene->_cuffedDriverFl = true;
T2_GLOBALS._uiElements.addScore(30);
} else {
if (BF_GLOBALS.getFlag(fTalkedDriverNoBkup)) {
@@ -328,14 +328,14 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
case INV_TICKET_BOOK:
if (!BF_GLOBALS.getFlag(fDriverOutOfTruck)) {
return startAction(CURSOR_TALK, event);
- } else if (!scene->_field1FC4) {
+ } else if (!scene->_harrisonMovedFl) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
scene->setAction(&scene->_sequenceManager1, scene, 4120, &scene->_passenger, &BF_GLOBALS._player, NULL);
- } else if ((scene->_field1FBC != 0) || (scene->_field1FC2 != 0)) {
+ } else if (scene->_cuffedDriverFl || scene->_driverOutOfTruckFl) {
break;
} else {
- scene->_field1FC2 = 1;
+ scene->_driverOutOfTruckFl = true;
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4127;
@@ -343,7 +343,7 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
}
return true;
case INV_MIRANDA_CARD:
- if (scene->_field1FBC == 0)
+ if (!scene->_cuffedDriverFl)
return false;
if (BF_GLOBALS.getFlag(readFrankRights)) {
@@ -379,15 +379,15 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBA) {
+ } else if (!scene->_harrissonTalkFl) {
SceneItem::display(410, 5, SET_WIDTH, 300,
SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBE) {
+ } else if (!scene->_cuffedPassengerFl) {
scene->_sceneMode = 4121;
- scene->_field1FBE = 1;
+ scene->_cuffedPassengerFl = true;
T2_GLOBALS._uiElements.addScore(50);
scene->signal();
} else
@@ -398,7 +398,7 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
return true;
case INV_HANDCUFFS:
if (BF_GLOBALS.getFlag(fCalledBackup)) {
- if ((scene->_talkCount < 5) || (scene->_field1FBA != 0))
+ if ((scene->_talkCount < 5) || (scene->_harrissonTalkFl))
break;
BF_GLOBALS._player.disableControl();
@@ -413,7 +413,7 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
}
return true;
case INV_MIRANDA_CARD:
- if (!scene->_field1FBA)
+ if (!scene->_harrissonTalkFl)
break;
if (BF_GLOBALS.getFlag(readFrankRights)) {
@@ -455,7 +455,7 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
SET_EXT_FGCOLOR, 13, LIST_END);
}
- } else if ((scene->_field1FBA != 0) && (scene->_field1FBC != 0)) {
+ } else if (scene->_harrissonTalkFl && scene->_cuffedDriverFl) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4112;
scene->_stripManager.start(4113, scene);
@@ -463,27 +463,27 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
BF_GLOBALS.set2Flags(f1098Frankie);
BF_GLOBALS.clearFlag(f1098Marina);
} else if ((BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1) ||
- (!scene->_field1FBA && (scene->_talkCount < 5))) {
+ (!scene->_harrissonTalkFl && (scene->_talkCount < 5))) {
SceneItem::display(350, 13, SET_WIDTH, 300,
SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBA) {
+ } else if (!scene->_harrissonTalkFl) {
BF_GLOBALS._player.disableControl();
- scene->_field1FBA = 1;
- scene->_field1FBE = 1;
+ scene->_harrissonTalkFl = true;
+ scene->_cuffedPassengerFl = true;
BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4122;
scene->_stripManager.start(4112, scene);
- } else if (scene->_field1FB6 < 1) {
+ } else if (scene->_action1Count < 1) {
break;
- } else if (scene->_field1FBC != 0) {
+ } else if (scene->_cuffedDriverFl) {
error("Error - want to cuff driver, but he's cuffed already");
} else {
BF_GLOBALS._player.disableControl();
- scene->_field1FBC = 1;
- scene->_field1FC0 = 1;
+ scene->_cuffedDriverFl = true;
+ scene->_field1FC0 = true;
BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4109;
scene->_stripManager.start(4112, scene);
@@ -500,20 +500,24 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene410::Scene410(): SceneExt() {
- _field1FB6 = _talkCount = _field1FBA = _field1FBC = 0;
- _field1FBE = _field1FC0 = _field1FC2 = _field1FC4 = 0;
+ _cuffedDriverFl = _harrissonTalkFl = _driverOutOfTruckFl = false;
+ _harrisonMovedFl = false;
+
+ _action1Count = _talkCount = 0;
+ _cuffedPassengerFl = false;
+ _field1FC0 = false;
}
void Scene410::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1FB6);
+ s.syncAsSint16LE(_action1Count);
s.syncAsSint16LE(_talkCount);
- s.syncAsSint16LE(_field1FBA);
- s.syncAsSint16LE(_field1FBC);
- s.syncAsSint16LE(_field1FBE);
+ s.syncAsSint16LE(_harrissonTalkFl);
+ s.syncAsSint16LE(_cuffedDriverFl);
+ s.syncAsSint16LE(_cuffedPassengerFl);
s.syncAsSint16LE(_field1FC0);
- s.syncAsSint16LE(_field1FC2);
- s.syncAsSint16LE(_field1FC4);
+ s.syncAsSint16LE(_driverOutOfTruckFl);
+ s.syncAsSint16LE(_harrisonMovedFl);
}
void Scene410::postInit(SceneObjectList *OwnerList) {
@@ -593,7 +597,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_patrolCar.fixPriority(148);
_patrolCar.setPosition(Common::Point(39, 168));
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
_sceneMode = 0;
signal();
break;
@@ -603,10 +607,10 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_driver.remove();
_sceneMode = 0;
} else {
- _field1FC4 = BF_GLOBALS._v50CC8;
- _field1FBA = BF_GLOBALS._v50CC2;
- _talkCount = BF_GLOBALS._v50CC6;
- _field1FB6 = BF_GLOBALS._v50CC4;
+ _harrisonMovedFl = BF_GLOBALS._scene410HarrisonMovedFl;
+ _harrissonTalkFl = BF_GLOBALS._scene410HarrisonTalkFl;
+ _talkCount = BF_GLOBALS._scene410TalkCount;
+ _action1Count = BF_GLOBALS._scene410Action1Count;
_passenger.setVisage(418);
_passenger.setStrip(6);
@@ -617,7 +621,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_passenger.setStrip(2);
_passenger.setFrame(5);
}
- if (_field1FBA) {
+ if (_harrissonTalkFl) {
_passenger.setVisage(415);
_passenger.setStrip(6);
_passenger.setFrame(8);
@@ -651,7 +655,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_patrolCar.setDetails(410, 8, 9, 10, 1, (SceneItem *)NULL);
_patrolCar.fixPriority(148);
- if (_field1FC4) {
+ if (_harrisonMovedFl) {
_harrison.setPosition(Common::Point(108, 112));
_patrolCar.fixPriority(148);
_patrolCar.setPosition(Common::Point(39, 168));
@@ -664,7 +668,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
}
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
}
break;
case 50:
@@ -686,10 +690,10 @@ void Scene410::signal() {
BF_GLOBALS.set2Flags(f1097Frankie);
BF_GLOBALS.clearFlag(f1097Marina);
- BF_GLOBALS._v50CC8 = _field1FC4;
- BF_GLOBALS._v50CC2 = _field1FBA;
- BF_GLOBALS._v50CC6 = _talkCount;
- BF_GLOBALS._v50CC4 = _field1FB6;
+ BF_GLOBALS._scene410HarrisonMovedFl = _harrisonMovedFl;
+ BF_GLOBALS._scene410HarrisonTalkFl = _harrissonTalkFl;
+ BF_GLOBALS._scene410TalkCount = _talkCount;
+ BF_GLOBALS._scene410Action1Count = _action1Count;
BF_GLOBALS._sceneManager.changeScene(60);
break;
case 2:
@@ -730,7 +734,7 @@ void Scene410::signal() {
case 9:
_sceneMode = 4106;
_stripManager.start(4111, this);
- _field1FBA = 1;
+ _harrissonTalkFl = true;
BF_GLOBALS.setFlag(fCuffedFrankie);
T2_GLOBALS._uiElements.addScore(30);
break;
@@ -760,7 +764,7 @@ void Scene410::signal() {
break;
case 4104:
// After call for backup, patrol car is coming
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4104, &_patrolCar, &_harrison, NULL);
@@ -1432,21 +1436,21 @@ bool Scene450::Manager::startAction(CursorType action, Event &event) {
} else {
animate(ANIM_MODE_8, 1, NULL);
- if (scene->_field19AC) {
+ if (scene->_managerCallsWeaselFl) {
scene->_sceneMode = 2;
- if (scene->_field19AE) {
+ if (scene->_talkManagerFl) {
scene->_stripManager.start(4521, scene);
} else {
- scene->_field19AE = 1;
+ scene->_talkManagerFl = true;
scene->_stripManager.start(4512, scene);
}
} else {
scene->_sceneMode = 4506;
- if (scene->_field19AE) {
+ if (scene->_talkManagerFl) {
scene->setAction(&scene->_sequenceManager, scene, 4518, &BF_GLOBALS._player, this, NULL);
} else {
scene->_sceneMode = 4506;
- scene->_field19AE = 1;
+ scene->_talkManagerFl = true;
scene->setAction(&scene->_sequenceManager, scene, 4506, &BF_GLOBALS._player, this, NULL);
}
}
@@ -1524,13 +1528,13 @@ bool Scene450::Exit::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene450::Scene450(): SceneExt() {
- _field19AC = _field19AE = 0;
+ _managerCallsWeaselFl = _talkManagerFl = false;
}
void Scene450::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field19AC);
- s.syncAsSint16LE(_field19AE);
+ s.syncAsSint16LE(_managerCallsWeaselFl);
+ s.syncAsSint16LE(_talkManagerFl);
}
void Scene450::postInit(SceneObjectList *OwnerList) {
@@ -1654,7 +1658,7 @@ void Scene450::signal() {
case 4510:
case 4511:
BF_GLOBALS.setFlag(fMgrCallsWeasel);
- _field19AC = 1;
+ _managerCallsWeaselFl = true;
_sceneMode = 4503;
setAction(&_sequenceManager, this, 4503, &_weasel, &_door, &_manager, NULL);
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes4.h b/engines/tsage/blue_force/blueforce_scenes4.h
index 937c015a4c..92e91c93b2 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.h
+++ b/engines/tsage/blue_force/blueforce_scenes4.h
@@ -116,9 +116,12 @@ public:
SpeakerDriver _driverSpeaker;
SpeakerShooter _shooterSpeaker;
ASoundExt _sound1;
- int _field1FB6, _talkCount, _field1FBA;
- int _field1FBC, _field1FBE;
- int _field1FC0, _field1FC2, _field1FC4;
+ int _action1Count, _talkCount;
+ bool _harrissonTalkFl;
+ bool _cuffedDriverFl;
+ bool _cuffedPassengerFl;
+ bool _field1FC0;
+ bool _driverOutOfTruckFl, _harrisonMovedFl;
Scene410();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -254,7 +257,8 @@ public:
NamedObject _door, _counterDoor;
Exit _exit;
NamedHotspot _interior, _shelf, _counter;
- int _field19AC, _field19AE;
+ bool _managerCallsWeaselFl;
+ bool _talkManagerFl;
Scene450();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index abadc4300a..101a39c4b7 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);
@@ -1772,12 +1772,12 @@ void Scene570::IconManager::refreshList() {
}
void Scene570::IconManager::addItem(Icon *item) {
- item->_mode = _mode;
_list.push_back(item);
}
Scene570::Icon::Icon(): NamedObject() {
_iconId = _folderId = 0;
+ _parentFolderId = 0;
}
void Scene570::Icon::synchronize(Serializer &s) {
@@ -1785,7 +1785,10 @@ void Scene570::Icon::synchronize(Serializer &s) {
s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_folderId);
s.syncAsSint16LE(_parentFolderId);
- s.syncAsSint16LE(_mode);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene570::Icon::remove() {
@@ -1906,7 +1909,7 @@ bool Scene570::Icon::startAction(CursorType action, Event &event) {
}
}
-void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, int unused, const Common::String &msg) {
+void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, const Common::String &msg) {
Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
NamedObject::postInit();
@@ -2073,23 +2076,23 @@ void Scene570::signal() {
_printerIcon.setDetails(570, 14, 15, -1, 2, (SceneItem *)NULL);
_iconManager.setup(2);
- _folder1.setDetails(1, 1, 0, 2, SCENE570_C_DRIVE);
- _folder2.setDetails(1, 2, 1, 2, SCENE570_RING);
- _folder3.setDetails(1, 3, 1, 2, SCENE570_PROTO);
- _folder4.setDetails(1, 4, 1, 2, SCENE570_WACKY);
+ _folder1.setDetails(1, 1, 0, SCENE570_C_DRIVE);
+ _folder2.setDetails(1, 2, 1, SCENE570_RING);
+ _folder3.setDetails(1, 3, 1, SCENE570_PROTO);
+ _folder4.setDetails(1, 4, 1, SCENE570_WACKY);
if (!BF_GLOBALS.getFlag(fDecryptedBluePrints))
- _icon1.setDetails(3, 5, 0, 2, SCENE570_COBB);
- _icon2.setDetails(2, 7, 0, 2, SCENE570_LETTER);
+ _icon1.setDetails(3, 5, 0, SCENE570_COBB);
+ _icon2.setDetails(2, 7, 0, SCENE570_LETTER);
if (BF_GLOBALS.getFlag(fDecryptedBluePrints))
- _icon3.setDetails(7, 6, 0, 2, SCENE570_COBB);
+ _icon3.setDetails(7, 6, 0, SCENE570_COBB);
- _icon4.setDetails(6, 8, 1, 2, SCENE570_RINGEXE);
- _icon5.setDetails(5, 9, 1, 2, SCENE570_RINGDATA);
- _icon6.setDetails(6, 10, 2, 2, SCENE570_PROTOEXE);
- _icon7.setDetails(5, 11, 2, 2, SCENE570_PROTODATA);
- _icon8.setDetails(6, 12, 3, 2, SCENE570_WACKYEXE);
- _icon9.setDetails(5, 13, 3, 2, SCENE570_WACKYDATA);
+ _icon4.setDetails(6, 8, 1, SCENE570_RINGEXE);
+ _icon5.setDetails(5, 9, 1, SCENE570_RINGDATA);
+ _icon6.setDetails(6, 10, 2, SCENE570_PROTOEXE);
+ _icon7.setDetails(5, 11, 2, SCENE570_PROTODATA);
+ _icon8.setDetails(6, 12, 3, SCENE570_WACKYEXE);
+ _icon9.setDetails(5, 13, 3, SCENE570_WACKYDATA);
_iconManager.refreshList();
BF_GLOBALS._player.enableControl();
@@ -2104,7 +2107,7 @@ void Scene570::signal() {
_object3.setFrame(1);
_object3.fixPriority(1);
- _icon3.setDetails(7, 6, 0, 2, SCENE570_COBB);
+ _icon3.setDetails(7, 6, 0, SCENE570_COBB);
_iconManager.refreshList();
T2_GLOBALS._uiElements._active = true;
T2_GLOBALS._uiElements.show();
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 73d323fc54..71c7f3d8f1 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;
@@ -257,7 +257,7 @@ class Scene570: public SceneExt {
class Icon: public NamedObject {
public:
SceneText _sceneText;
- int _iconId, _folderId, _parentFolderId, _mode;
+ int _iconId, _folderId, _parentFolderId;
Common::String _text;
Icon();
@@ -266,7 +266,7 @@ class Scene570: public SceneExt {
virtual void remove();
virtual bool startAction(CursorType action, Event &event);
- void setDetails(int iconId, int folderId, int parentFolderId, int unused, const Common::String &msg);
+ void setDetails(int iconId, int folderId, int parentFolderId, const Common::String &msg);
};
class IconManager: public EventHandler {
public:
diff --git a/engines/tsage/blue_force/blueforce_scenes6.cpp b/engines/tsage/blue_force/blueforce_scenes6.cpp
index 9467df7917..b20092492f 100644
--- a/engines/tsage/blue_force/blueforce_scenes6.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes6.cpp
@@ -79,7 +79,6 @@ void Scene600::Action1::signal() {
}
BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0);
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(999);
setDelay(5);
break;
@@ -88,7 +87,6 @@ void Scene600::Action1::signal() {
setDelay(5);
break;
case 7:
- BF_GLOBALS._v51C44 = 0;
remove();
break;
default:
@@ -275,7 +273,7 @@ bool Scene666::Item1::startAction(CursorType action, Event &event) {
void Scene666::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.play(27);
SceneExt::postInit();
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
loadScene(999);
BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0);
diff --git a/engines/tsage/blue_force/blueforce_scenes7.cpp b/engines/tsage/blue_force/blueforce_scenes7.cpp
index 4cdd2f3f15..2f52c4df95 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes7.cpp
@@ -148,7 +148,7 @@ void Scene710::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.fadeSound(14);
_soundExt1.fadeSound(48);
- _v51C34.set(40, 0, 280, 240);
+
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.hide();
BF_GLOBALS._player._moveDiff = Common::Point(4, 2);
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index 5a60cd7c5e..f78a332be9 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -577,17 +577,15 @@ bool Scene810::Lyle::startAction(CursorType action, Event &event) {
if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))){
scene->_sceneMode = 8141;
} else {
- // Doublecheck on shownLyleCrate1 removed: useless
scene->_sceneMode = 8144;
}
} else {
if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))) {
scene->_sceneMode = 8129;
- } else { // if (BF_GLOBALS.getFlag(shownLyleCrate1)) {
+ } else {
scene->_sceneMode = 8132;
- // doublecheck Present in the original, may hide a bug in the original
- //} else
- // scene->_sceneMode = 8121;
+ // Double check on ShownLyleCrate1 present in the original, may hide a bug in the original
+ // The original was then setting _sceneMode 8121
}
}
}
@@ -1071,7 +1069,6 @@ void Scene810::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 8107, &BF_GLOBALS._player, &_lyle, NULL);
break;
case 935:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._scenePalette.loadPalette(2);
_lyle.remove();
@@ -1804,13 +1801,11 @@ void Scene830::signal() {
_sceneMode = 832;
BF_GLOBALS._scenePalette.clearListeners();
addFader((const byte *)&black, 5, this);
- BF_GLOBALS._v51C44 = 0;
break;
case 12:
_sceneMode = 831;
BF_GLOBALS._scenePalette.clearListeners();
addFader((const byte *)&black, 5, this);
- BF_GLOBALS._v51C44 = 0;
break;
case 13:
BF_GLOBALS._sceneManager.changeScene(850);
@@ -1963,7 +1958,7 @@ void Scene840::BoatKeysInset::postInit(SceneObjectList *OwnerList) {
_waveKeys.setDetails(840, 53, 8, -1, 2, (SceneItem *)NULL);
}
- _v1B4 = _v1B6 = 0;
+ _usedRentalKeys = _usedWaveKeys = false;
}
void Scene840::BoatKeysInset::remove() {
@@ -1984,7 +1979,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;
}
@@ -2072,7 +2067,7 @@ bool Scene840::BoatKeysInset::RentalKeys::startAction(CursorType action, Event &
BF_INVENTORY.setObjectScene(INV_RENTAL_KEYS, 1);
T2_GLOBALS._uiElements.addScore(30);
- scene->_boatKeysInset._v1B4 = 1;
+ scene->_boatKeysInset._usedRentalKeys = true;
remove();
}
return true;
@@ -2090,7 +2085,7 @@ bool Scene840::BoatKeysInset::WaveKeys::startAction(CursorType action, Event &ev
SceneItem::display2(840, 56);
BF_INVENTORY.setObjectScene(INV_WAVE_KEYS, 1);
T2_GLOBALS._uiElements.addScore(50);
- scene->_boatKeysInset._v1B6 = 1;
+ scene->_boatKeysInset._usedWaveKeys = true;
remove();
} else {
SceneItem::display2(840, 9);
@@ -2101,6 +2096,15 @@ bool Scene840::BoatKeysInset::WaveKeys::startAction(CursorType action, Event &ev
}
}
+void Scene840::BoatKeysInset::synchronize(Serializer &s) {
+ FocusObject::synchronize(s);
+
+ if (s.getVersion() >= 12) {
+ s.syncAsSint16LE(_usedWaveKeys);
+ s.syncAsSint16LE(_usedRentalKeys);
+ }
+}
+
bool Scene840::BoatKeys::startAction(CursorType action, Event &event) {
Scene840 *scene = (Scene840 *)BF_GLOBALS._sceneManager._scene;
@@ -2472,10 +2476,10 @@ void Scene840::signal() {
_boatKeysInset.setDetails(840, 50, 8, 51);
break;
case 8412:
- if (_boatKeysInset._v1B6) {
+ if (_boatKeysInset._usedWaveKeys) {
_sceneMode = 8409;
setAction(&_sequenceManager1, this, 8409, &BF_GLOBALS._player, &_carter, &_doors, NULL);
- } else if (!_boatKeysInset._v1B4) {
+ } else if (!_boatKeysInset._usedRentalKeys) {
BF_GLOBALS._player.enableControl();
} else {
_sceneMode = 3;
diff --git a/engines/tsage/blue_force/blueforce_scenes8.h b/engines/tsage/blue_force/blueforce_scenes8.h
index ef5ef81563..b9e6ebd640 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.h
+++ b/engines/tsage/blue_force/blueforce_scenes8.h
@@ -348,8 +348,9 @@ class Scene840: public PalettedScene {
public:
RentalKeys _rentalKeys;
WaveKeys _waveKeys;
- int _v1B4, _v1B6;
+ bool _usedRentalKeys,_usedWaveKeys;
+ virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void process(Event &event);
diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp
index 1cb8191640..2b42dc8625 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes9.cpp
@@ -705,6 +705,10 @@ void Scene900::process(Event &event) {
void Scene900::dispatch() {
SceneExt::dispatch();
+ // WORKAROUND:: Fix for invalid data in the Blue Force floppy version when opening gate
+ if (_sceneMode == 9006 && (g_vm->getFeatures() & GF_FLOPPY) && BF_GLOBALS._player._endFrame == 8)
+ BF_GLOBALS._player._endFrame = 6;
+
if (BF_GLOBALS.getFlag(fWithLyle) && _lyle.isNoMover()) {
_lyle.updateAngle(BF_GLOBALS._player._position);
}
@@ -836,14 +840,14 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
if (BF_GLOBALS._nico910State >= 4)
return NamedObject::startAction(action, event);
- if (BF_GLOBALS._v4CEE6 < 4)
- BF_GLOBALS._v4CEE6++;
+ if (BF_GLOBALS._nico910Talk < 4)
+ BF_GLOBALS._nico910Talk++;
- if (BF_GLOBALS._v4CEE6 == 2) {
+ if (BF_GLOBALS._nico910Talk == 2) {
scene->_sceneMode = 13;
scene->_stripManager.start(9105, scene);
} else
- scene->_stripManager.start(9103 + BF_GLOBALS._v4CEE6, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9103 + BF_GLOBALS._nico910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
case INV_COLT45:
@@ -883,14 +887,14 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
if (BF_GLOBALS._nico910State >= 4)
return NamedObject::startAction(action, event);
- if (BF_GLOBALS._v4CEE6 < 4)
- BF_GLOBALS._v4CEE6++;
+ if (BF_GLOBALS._nico910Talk < 4)
+ BF_GLOBALS._nico910Talk++;
- if (BF_GLOBALS._v4CEE6 == 2) {
+ if (BF_GLOBALS._nico910Talk == 2) {
scene->_sceneMode = 13;
scene->_stripManager.start(9105, scene);
} else
- scene->_stripManager.start(9103 + BF_GLOBALS._v4CEE6, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9103 + BF_GLOBALS._nico910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
@@ -962,16 +966,16 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
return true;
break;
case CURSOR_TALK:
- if (BF_GLOBALS._v4CEE8 < 3)
- BF_GLOBALS._v4CEE8++;
+ if (BF_GLOBALS._stuart910Talk < 3)
+ BF_GLOBALS._stuart910Talk++;
- scene->_stripManager.start(9107 + BF_GLOBALS._v4CEE8, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9107 + BF_GLOBALS._stuart910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
case INV_COLT45:
if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())){
BF_GLOBALS._player.disableControl();
- if (BF_GLOBALS._v4CEE4 == 2) {
+ if (BF_GLOBALS._stuart910State == 2) {
scene->_sceneMode = 9132;
scene->setAction(&scene->_sequenceManager1, scene, 9132, &scene->_stuart, NULL);
return NamedObject::startAction(action, event);
@@ -1418,6 +1422,10 @@ void Scene910::Object13::setupBreaker(int x, int y, int mode, int8 frameNumber)
BF_GLOBALS._sceneItems.push_front(this);
}
+Scene910::Object25::Object25() {
+ _field90 = _field92 = 0;
+}
+
void Scene910::Object25::synchronize(Serializer &s) {
NamedObject::synchronize(s);
s.syncAsSint16LE(_field90);
@@ -1870,7 +1878,7 @@ bool Scene910::Item2::startAction(CursorType action, Event &event) {
bool Scene910::Item3::startAction(CursorType action, Event &event) {
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_TALK) && (BF_GLOBALS._nico910State == 4) && (BF_GLOBALS._v4CEE4 == 0)) {
+ if ((action == CURSOR_TALK) && (BF_GLOBALS._nico910State == 4) && (BF_GLOBALS._stuart910State == 0)) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 15;
scene->_stripManager.start(9102, scene);
@@ -1958,7 +1966,6 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
loadScene(910);
BF_GLOBALS._sound1.changeSound(99);
- BF_GLOBALS._v51C44 = 0;
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_jakeJacketSpeaker);
@@ -2050,7 +2057,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
|| (BF_GLOBALS._sceneManager._previousScene == 300)) {
BF_GLOBALS._sceneManager._previousScene = 900;
BF_GLOBALS._nico910State = 0;
- BF_GLOBALS._v4CEE4 = 0;
+ BF_GLOBALS._stuart910State = 0;
}
_field2DE0 = 0;
@@ -2142,7 +2149,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_nico.setVisage(913);
_nico.setPosition(Common::Point(262, 124));
_nico.setStrip(6);
- BF_GLOBALS._v4CEE6 = 0;
+ BF_GLOBALS._nico910Talk = 0;
BF_GLOBALS._nico910State = 1;
_nico.setDetails(910, 63, 64, 67, 5, &_item4);
BF_GLOBALS._v4CECA = 2;
@@ -2269,7 +2276,6 @@ void Scene910::signal() {
break;
case 10:
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._v51C44 = 0;
BF_GLOBALS._sceneManager.changeScene(935);
break;
case 11:
@@ -2303,12 +2309,11 @@ void Scene910::signal() {
case 15:
_stuart.postInit();
_stuart.setDetails(910, 66, 67, 68, 5, &_nico);
- BF_GLOBALS._v4CEE8 = 0;
+ BF_GLOBALS._stuart910Talk = 0;
_sceneMode = 9121;
setAction(&_sequenceManager1, this, 9121, &_stuart, NULL);
break;
case 14:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(940);
break;
case 16:
@@ -2344,7 +2349,7 @@ void Scene910::signal() {
case 18:
BF_GLOBALS._player._strip = 7;
BF_GLOBALS._player._frame = 1;
- if (BF_GLOBALS._v4CEE4 == 3) {
+ if (BF_GLOBALS._stuart910State == 3) {
if (_field2DE4 == 0) {
_field2DE4 = 1;
_sceneMode = 9142;
@@ -2368,7 +2373,6 @@ void Scene910::signal() {
break;
case 19:
BF_GLOBALS._deathReason = 14;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 20:
@@ -2384,7 +2388,6 @@ void Scene910::signal() {
BF_GLOBALS.clearFlag(fGotPointsForSearchingDA);
else
BF_GLOBALS.setFlag(fGotPointsForSearchingDA);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(900);
break;
case 9102:
@@ -2457,7 +2460,7 @@ void Scene910::signal() {
BF_GLOBALS._player.disableControl();
_nico.postInit();
_nico.setDetails(910, 63, 64, 65, 5, &_item4);
- BF_GLOBALS._v4CEE6 = 0;
+ BF_GLOBALS._nico910Talk = 0;
_shadow.postInit();
_action2.remove();
_sceneMode = 9116;
@@ -2478,7 +2481,6 @@ void Scene910::signal() {
// No break on purpose
case 9137:
BF_GLOBALS._deathReason = 16;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9119:
@@ -2496,7 +2498,7 @@ void Scene910::signal() {
break;
case 9121:
_item3.setDetails(7, 910, 96, 60, 61, 3);
- BF_GLOBALS._v4CEE4 = 2;
+ BF_GLOBALS._stuart910State = 2;
if (BF_GLOBALS._nico910State == 4) {
_sceneMode = 20;
_stripManager.start(9115, this);
@@ -2580,7 +2582,7 @@ void Scene910::signal() {
_yellowCord.hide();
_sceneMode = 9136;
setAction(&_sequenceManager1, this, 9136, &BF_GLOBALS._player, &_stuart, &_yellowCord, NULL);
- BF_GLOBALS._v4CEE4 = 3;
+ BF_GLOBALS._stuart910State = 3;
break;
case 11:
_sceneMode = 9137;
@@ -2603,13 +2605,13 @@ void Scene910::signal() {
_stuart.postInit();
_nico.setDetails(910, 72, 73, 74, 3, (SceneItem *)NULL);
_stuart.setDetails(910, 66, 67, 68, 5, &_nico);
- BF_GLOBALS._v4CEE8 = 0;
+ BF_GLOBALS._stuart910Talk = 0;
_sceneMode = 9121;
setAction(&_sequenceManager1, this, 9121, &_stuart, NULL);
break;
case 9126:
_sceneMode = 19;
- if (BF_GLOBALS._v4CEE4 == 0)
+ if (BF_GLOBALS._stuart910State == 0)
signal();
else
_stripManager.start(9115, this);
@@ -2618,7 +2620,6 @@ void Scene910::signal() {
// No break on purpose
case 9134:
BF_GLOBALS._deathReason = 17;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9130:
@@ -2629,14 +2630,12 @@ void Scene910::signal() {
break;
case 9132:
BF_GLOBALS._player.enableControl();
- BF_GLOBALS._v4CEE4 = 4;
+ BF_GLOBALS._stuart910State = 4;
BF_GLOBALS._deathReason = 13;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9135:
BF_GLOBALS._deathReason = 15;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9136:
@@ -2681,7 +2680,6 @@ void Scene910::signal() {
break;
case 9143:
if (BF_GLOBALS._nico910State == 0) {
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(920);
} else {
SceneItem::display(910, 89, SET_WIDTH, 312,
@@ -2700,7 +2698,6 @@ void Scene910::signal() {
break;
case 9148:
BF_GLOBALS._deathReason = 23;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9149:
@@ -3573,7 +3570,7 @@ void Scene935::postInit(SceneObjectList *OwnerList) {
PalettedScene::postInit();
loadScene(935);
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
BF_GLOBALS._player.disableControl();
_visualSpeaker._textMode = ALIGN_CENTER;
_visualSpeaker._hideObjects = false;
@@ -3808,7 +3805,7 @@ void Scene940::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.play(115);
BF_GLOBALS._dayNumber = 6;
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
T2_GLOBALS._uiElements._active = false;
_gameTextSpeaker2._speakerName = "SENTTEXT";
diff --git a/engines/tsage/blue_force/blueforce_scenes9.h b/engines/tsage/blue_force/blueforce_scenes9.h
index 74708b94de..8bf7f343a1 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.h
+++ b/engines/tsage/blue_force/blueforce_scenes9.h
@@ -188,6 +188,7 @@ class Scene910: public PalettedScene {
class Object25: public NamedObject {
int _field90, _field92;
public:
+ Object25();
void setupHiddenSwitch(int x, int y, int arg8, int argA);
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
diff --git a/engines/tsage/blue_force/blueforce_speakers.cpp b/engines/tsage/blue_force/blueforce_speakers.cpp
index 2a57616640..b15d2f4716 100644
--- a/engines/tsage/blue_force/blueforce_speakers.cpp
+++ b/engines/tsage/blue_force/blueforce_speakers.cpp
@@ -63,8 +63,8 @@ void VisualSpeaker::synchronize(Serializer &s) {
s.syncAsSint16LE(_offsetPos.y);
}
-void VisualSpeaker::proc12(Action *action) {
- Speaker::proc12(action);
+void VisualSpeaker::startSpeaking(Action *action) {
+ Speaker::startSpeaking(action);
_textPos = Common::Point(_offsetPos.x + BF_GLOBALS._sceneManager._scene->_sceneBounds.left,
_offsetPos.y + BF_GLOBALS._sceneManager._scene->_sceneBounds.top);
_numFrames = 0;
diff --git a/engines/tsage/blue_force/blueforce_speakers.h b/engines/tsage/blue_force/blueforce_speakers.h
index e406a50fbe..e9150df056 100644
--- a/engines/tsage/blue_force/blueforce_speakers.h
+++ b/engines/tsage/blue_force/blueforce_speakers.h
@@ -51,7 +51,7 @@ public:
virtual Common::String getClassName() { return "VisualSpeaker"; }
virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void proc12(Action *action);
+ virtual void startSpeaking(Action *action);
virtual void setText(const Common::String &msg);
};
diff --git a/engines/tsage/configure.engine b/engines/tsage/configure.engine
new file mode 100644
index 0000000000..2b8edf8266
--- /dev/null
+++ b/engines/tsage/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tsage "TsAGE" yes
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index de5ac62425..f7c1dd24e6 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,12 +444,20 @@ 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();
g_globals->_events.showCursor();
+ // WORKAROUND: On-screen dialogs are really meant to use a GfxManager instance
+ // for their lifetime, which prevents saving or loading. Since I don't want to spend a lot
+ // of time refactoring this already working dialog, fake it by putting a dummy gfxmanager at
+ // the end of the gfx manager list so as to prevent saving or loading
+ GfxManager gfxManager;
+ GLOBALS._gfxManagers.push_back(&gfxManager);
+
// Event handling loop
Event event;
while (!g_vm->shouldQuit()) {
@@ -501,6 +509,7 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
// Remove the dialog
remove();
+ GLOBALS._gfxManagers.remove(&gfxManager);
return _selectedIndex;
}
@@ -513,6 +522,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 +534,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 +543,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 +564,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 +573,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 +600,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 +656,7 @@ void StripManager::reset() {
_activeSpeaker = NULL;
_textShown = false;
_callbackObject = NULL;
+ _exitMode = 0;
_obj44List.clear();
if (!_script.empty()) {
@@ -679,6 +704,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 +715,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 +735,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]->stopSpeaking();
+ }
+ }
+
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 +762,24 @@ void StripManager::remove() {
if (_onEnd)
_onEnd();
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endHandler = NULL;
+
Action::remove();
}
+void StripManager::dispatch() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (_activeSpeaker)
+ _activeSpeaker->dispatch();
+ }
+
+ Action::dispatch();
+}
+
void StripManager::signal() {
+ int strIndex = 0;
+
if (_textShown) {
_activeSpeaker->removeText();
_textShown = false;
@@ -760,12 +811,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:
@@ -782,39 +831,101 @@ void StripManager::signal() {
}
}
+ _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);
+ // If no entry found, get the default response
+ if (!delayFlag) {
+ idx = 0;
+ while (obj44._list[idx + 1]._id)
+ ++idx;
+
+ choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ strIndex = idx;
+ delayFlag = true;
}
} else {
// Standard choices loading
- for (idx = 0; idx < 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);
@@ -831,7 +942,7 @@ void StripManager::signal() {
g_globals->_sceneManager._scene->loadScene(_sceneNumber);
}
- _activeSpeaker->proc12(this);
+ _activeSpeaker->startSpeaking(this);
}
if (_callbackObject) {
@@ -843,11 +954,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);
- _textShown = true;
- _activeSpeaker->setText(choiceList[strIndex]);
+ if (speaker) {
+ speaker->_speakerMode = obj44._speakerMode;
+ if (!choiceList[strIndex].empty())
+ speaker->animateSpeaker();
+ }
+
+ if (!choiceList[strIndex].empty()) {
+ _textShown = true;
+ _activeSpeaker->setText(choiceList[strIndex]);
+ } else if (!obj44._speakerMode) {
+ _delayFrames = 1;
+ } else {
+ _delayFrames = 0;
+ speaker->animateSpeaker();
+ }
+ } else {
+ _textShown = true;
+ _activeSpeaker->setText(choiceList[strIndex]);
+ }
}
_obj44Index = getNewIndex(obj44._list[strIndex]._id);
@@ -915,6 +1043,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) {
@@ -966,7 +1096,7 @@ void Speaker::remove() {
SceneObjectList::deactivate();
}
-void Speaker::proc12(Action *action) {
+void Speaker::startSpeaking(Action *action) {
_action = action;
if (_newSceneNumber != -1) {
_oldSceneNumber = g_globals->_sceneManager._sceneNumber;
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index 0c4eb9539d..e7b8e811ca 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -91,9 +91,10 @@ public:
virtual Common::String getClassName() { return "Speaker"; }
virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void proc12(Action *action);
+ virtual void startSpeaking(Action *action);
virtual void setText(const Common::String &msg);
virtual void removeText();
+ virtual void stopSpeaking() {}
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;
@@ -230,6 +237,7 @@ public:
virtual void synchronize(Serializer &s);
virtual void remove();
+ virtual void dispatch();
virtual void signal();
virtual void process(Event &event);
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 4a90e23a33..596f056bfe 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -860,6 +860,8 @@ void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common
int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute) {
// Make a copy of the provided route. The first entry is the size.
int tempList[REGION_LIST_SIZE + 1];
+ memset(tempList, 0, sizeof(tempList));
+
foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -1151,6 +1153,13 @@ void PaletteRotation::signal() {
if (flag)
_currIndex = _start;
}
+
+ // Added in Return to Ringworld
+ if (_currIndex < _start) {
+ flag = decDuration();
+ if (flag)
+ _currIndex = _end;
+ }
break;
case 2:
_currIndex += _idxChange;
@@ -1179,7 +1188,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);
}
}
@@ -1516,6 +1525,10 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface,
tempRect, Rect(0, 0, tempRect.width(), tempRect.height()), NULL);
+ if (g_vm->getGameID() == GType_Ringworld2 && !GLOBALS._player._uiEnabled
+ && T2_GLOBALS._interfaceY == UI_INTERFACE_Y) {
+ g_globals->_screenSurface.fillRect(Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT - 1), 0);
+ }
for (SynchronizedList<PaletteModifier *>::iterator i = tempPalette._listeners.begin(); i != tempPalette._listeners.end(); ++i)
delete *i;
@@ -1532,7 +1545,11 @@ void ScenePalette::synchronize(Serializer &s) {
s.syncAsSint32LE(_colors.foreground);
s.syncAsSint32LE(_colors.background);
- s.syncAsSint32LE(_field412);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsByte(_redColor);
s.syncAsByte(_greenColor);
s.syncAsByte(_blueColor);
@@ -1615,7 +1632,8 @@ void SceneItem::display(int resNum, int lineNum, ...) {
Common::String msg = (!resNum || (resNum == -1)) ? Common::String() :
g_resourceManager->getMessage(resNum, lineNum);
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
if (g_globals->_sceneObjects->contains(&g_globals->_sceneText)) {
@@ -1725,9 +1743,13 @@ void SceneItem::display(int resNum, int lineNum, ...) {
font.setFontNumber(g_globals->_sceneText._fontNumber);
font.getStringBounds(msg.c_str(), textRect, maxWidth);
+ Rect screenBounds = g_globals->gfxManager()._bounds;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ screenBounds.collapse(20, 15);
+
// Center the text at the specified position, and then constrain it to be-
textRect.center(pos.x, pos.y);
- textRect.contain(g_globals->gfxManager()._bounds);
+ textRect.contain(screenBounds);
if (centerText) {
g_globals->_sceneText._color1 = g_globals->_sceneText._color2;
@@ -1745,9 +1767,22 @@ void SceneItem::display(int resNum, int lineNum, ...) {
}
g_globals->_sceneText.fixPriority(255);
+
+ // In Return to Ringworld, if in voice mode only, don't show the text
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT))
+ g_globals->_sceneText.hide();
+
g_globals->_sceneObjects->draw();
}
+ // For Return to Ringworld, play the voice overs in sequence
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ }
+
// Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it
if (!keepOnscreen && !msg.empty()) {
Event event;
@@ -1757,18 +1792,31 @@ void SceneItem::display(int resNum, int lineNum, ...) {
EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
- }
- // For Return to Ringworld, play the voice overs in sequence
- if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) {
- R2_GLOBALS._playStream.play(*playList.begin(), NULL);
- playList.pop_front();
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ // Allow the play stream to do processing
+ R2_GLOBALS._playStream.dispatch();
+ if (!R2_GLOBALS._playStream.isPlaying()) {
+ // Check if there are further voice samples to play
+ if (!playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ } else if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ // If not showing text, don't both waiting for a click to end
+ break;
+ }
+ }
+ }
}
+ if (g_vm->getGameID() == GType_Ringworld2)
+ R2_GLOBALS._playStream.stop();
+
g_globals->_sceneText.remove();
}
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) {
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active) {
// Show user interface
T2_GLOBALS._uiElements.show();
@@ -2062,18 +2110,18 @@ SceneObject::SceneObject() : SceneHotspot() {
_visage = 0;
_strip = 0;
_frame = 0;
- _effect = 0;
- _shade = _shade2 = 0;
+ _effect = EFFECT_NONE;
+ _shade = _oldShade = 0;
_linkedActor = NULL;
- _field8A = Common::Point(0, 0);
+ _actorDestPos = Common::Point(0, 0);
_angle = 0;
_xs = 0;
_xe = 0;
_endFrame = 0;
_field68 = 0;
_regionIndex = 0;
- _field9C = NULL;
+ _shadowMap = NULL;
}
SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() {
@@ -2111,8 +2159,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() {
@@ -2361,12 +2414,17 @@ void SceneObject::animate(AnimateMode animMode, ...) {
case ANIM_MODE_8:
case ANIM_MODE_9:
- _field68 = va_arg(va, int);
- _endAction = va_arg(va, Action *);
- _frameChange = 1;
- _endFrame = getFrameCount();
- if (_frame == _endFrame)
- setFrame(getNewFrame());
+ if (_animateMode == ANIM_MODE_9 && g_vm->getGameID() == GType_Ringworld2) {
+ _frameChange = -1;
+ _field2E = _position;
+ } else {
+ _field68 = va_arg(va, int);
+ _endAction = va_arg(va, Action *);
+ _frameChange = 1;
+ _endFrame = getFrameCount();
+ if (_frame == _endFrame)
+ setFrame(getNewFrame());
+ }
break;
}
va_end(va);
@@ -2450,8 +2508,8 @@ void SceneObject::synchronize(Serializer &s) {
s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y);
s.syncAsSint32LE(_moveRate);
if (g_vm->getGameID() == GType_Ringworld2) {
- s.syncAsSint16LE(_field8A.x);
- s.syncAsSint16LE(_field8A.y);
+ s.syncAsSint16LE(_actorDestPos.x);
+ s.syncAsSint16LE(_actorDestPos.y);
}
SYNC_POINTER(_endAction);
s.syncAsUint32LE(_regionBitList);
@@ -2459,7 +2517,7 @@ void SceneObject::synchronize(Serializer &s) {
if (g_vm->getGameID() == GType_Ringworld2) {
s.syncAsSint16LE(_effect);
s.syncAsSint16LE(_shade);
- s.syncAsSint16LE(_shade2);
+ s.syncAsSint16LE(_oldShade);
SYNC_POINTER(_linkedActor);
}
}
@@ -2468,10 +2526,11 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
if (!OwnerList)
OwnerList = g_globals->_sceneObjects;
- if (!OwnerList->contains(this)) {
+ bool isExisting = OwnerList->contains(this);
+ if (!isExisting || ((_flags & OBJFLAG_REMOVE) != 0)) {
_percent = 100;
_priority = 255;
- _flags = 4;
+ _flags = OBJFLAG_ZOOMED;
_visage = 0;
_strip = 1;
_frame = 1;
@@ -2487,7 +2546,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
_numFrames = 10;
_regionBitList = 0;
- OwnerList->push_back(this);
+ if (!isExisting)
+ OwnerList->push_back(this);
_flags |= OBJFLAG_PANES;
}
}
@@ -2505,9 +2565,9 @@ void SceneObject::remove() {
void SceneObject::dispatch() {
if (g_vm->getGameID() == GType_Ringworld2) {
- if (_shade != _shade2)
+ if (_shade != _oldShade)
_flags |= OBJFLAG_PANES;
- _shade2 = _shade;
+ _oldShade = _shade;
}
uint32 currTime = g_globals->_events.getFrameNumber();
@@ -2625,8 +2685,9 @@ void SceneObject::dispatch() {
_linkedActor->setFrame(_frame);
}
- if ((_effect == 1) && (getRegionIndex() < 11))
- _shade = 0;
+ int regionIndex = getRegionIndex();
+ if ((_effect == EFFECT_SHADED) && (regionIndex < 11))
+ _shade = regionIndex;
}
}
@@ -2655,11 +2716,46 @@ void SceneObject::removeObject() {
GfxSurface SceneObject::getFrame() {
_visageImages.setVisage(_visage, _strip);
- return _visageImages.getFrame(_frame);
+ GfxSurface frame = _visageImages.getFrame(_frame);
+
+ // Reset any centroid adjustment flags, in
+ frame._flags &= ~(FRAME_FLIP_CENTROID_X | FRAME_FLIP_CENTROID_Y);
+
+ // For later games, check whether the appropriate object flags are set for flipping
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if ((_flags & OBJFLAG_FLIP_CENTROID_X) || _visageImages._flipHoriz)
+ frame._flags |= FRAME_FLIP_CENTROID_X;
+ if ((_flags & OBJFLAG_FLIP_CENTROID_Y) || _visageImages._flipVert)
+ frame._flags |= FRAME_FLIP_CENTROID_Y;
+ }
+
+ // If shading is needed, post apply the shadiing onto the frame
+ if ((g_vm->getGameID() == GType_Ringworld2) && (_shade >= 1)) {
+ Graphics::Surface s = frame.lockSurface();
+ byte *p = (byte *)s.getPixels();
+ byte *endP = p + s.w * s.h;
+
+ while (p < endP) {
+ if (*p != frame._transColor)
+ *p = R2_GLOBALS._fadePaletteMap[_shade - 1][*p];
+ ++p;
+ }
+
+ frame.unlockSurface();
+ }
+
+ return frame;
}
void SceneObject::reposition() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (!(_flags & OBJFLAG_ZOOMED)) {
+ setZoom(g_globals->_sceneManager._scene->_zoomPercents[MIN(_position.y, (int16)255)]);
+ }
+ }
+
GfxSurface frame = getFrame();
+
_bounds.resize(frame, _position.x, _position.y - _yDiff, _percent);
_xs = _bounds.left;
_xe = _bounds.right;
@@ -2670,11 +2766,27 @@ void SceneObject::reposition() {
*/
void SceneObject::draw() {
Rect destRect = _bounds;
- destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left,
- -g_globals->_sceneManager._scene->_sceneBounds.top);
- Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority);
+ Scene *scene = g_globals->_sceneManager._scene;
+ destRect.translate(-scene->_sceneBounds.left, -scene->_sceneBounds.top);
GfxSurface frame = getFrame();
- g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+ Region *priorityRegion = scene->_priorities.find(_priority);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ switch (_effect) {
+ case EFFECT_SHADOW_MAP: {
+ if (!_shadowMap)
+ _shadowMap = static_cast<Ringworld2::SceneExt *>(scene)->_shadowPaletteMap;
+
+ GLOBALS.gfxManager().getSurface().copyFrom(frame, frame.getBounds(),
+ destRect, priorityRegion, _shadowMap);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+
+ GLOBALS.gfxManager().copyFrom(frame, destRect, priorityRegion);
}
/**
@@ -2724,7 +2836,9 @@ void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, i
}
void SceneObject::setup(int visage, int stripFrameNum, int frameNum) {
- postInit();
+ if (g_vm->getGameID() != GType_Ringworld2)
+ postInit();
+
setVisage(visage);
setStrip(stripFrameNum);
setFrame(frameNum);
@@ -2750,18 +2864,39 @@ void BackgroundSceneObject::draw() {
g_globals->_sceneManager._scene->_backSurface.copyFrom(frame, destRect, priorityRegion);
}
-void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int32 arg10) {
- warning("TODO: Implement properly BackgroundSceneObject::setup2()");
+SceneObject *BackgroundSceneObject::clone() const {
+ BackgroundSceneObject *obj = new BackgroundSceneObject(*this);
+ return obj;
+}
+
+void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int effect) {
+ // Check if the given object is already in the background object list
+ if (R2_GLOBALS._sceneManager._scene->_bgSceneObjects.contains(this)) {
+ _flags |= OBJFLAG_REMOVE;
+
+ // Clone the item
+ SceneObject *obj = clone();
+ obj->_flags |= OBJFLAG_CLONED;
+ R2_GLOBALS._sceneManager._scene->_bgSceneObjects.push_back(obj);
+
+ _flags |= ~OBJFLAG_REMOVE;
+ }
+
postInit();
setVisage(visage);
setStrip(stripFrameNum);
setFrame(frameNum);
- setPosition(Common::Point(posX, posY), 0);
+ setPosition(Common::Point(posX, posY));
fixPriority(priority);
}
-void BackgroundSceneObject::proc27() {
- warning("STUB: BackgroundSceneObject::proc27()");
+void BackgroundSceneObject::copySceneToBackground() {
+ GLOBALS._sceneManager._scene->_backSurface.copyFrom(g_globals->gfxManager().getSurface(), 0, 0);
+
+ // WORKAROUND: Since savegames don't store the active screen data, once we copy the
+ // foreground objects to the background, we have to prevent the scene being saved.
+ if (g_vm->getGameID() == GType_Ringworld2)
+ ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->_preventSaving = true;
}
/*--------------------------------------------------------------------------*/
@@ -3103,6 +3238,7 @@ Visage::Visage() {
_rlbNum = -1;
_data = NULL;
_flipHoriz = false;
+ _flipVert = false;
}
Visage::Visage(const Visage &v) {
@@ -3112,6 +3248,7 @@ Visage::Visage(const Visage &v) {
if (_data)
g_vm->_memoryManager.incLocks(_data);
_flipHoriz = false;
+ _flipVert = false;
}
Visage &Visage::operator=(const Visage &s) {
@@ -3155,8 +3292,11 @@ void Visage::setVisage(int resNum, int rlbNum) {
rlbNum = (int)(v & 0xff);
}
_flipHoriz = flags & 1;
+ _flipVert = flags & 2;
_data = g_resourceManager->getResource(RES_VISAGE, resNum, rlbNum);
+
+ DEALLOCATE(indexData);
}
}
@@ -3179,7 +3319,9 @@ GfxSurface Visage::getFrame(int frameNum) {
byte *frameData = _data + offset;
GfxSurface result = surfaceFromRes(frameData);
- if (_flipHoriz) flip(result);
+ if (_flipHoriz) flipHorizontal(result);
+ if (_flipVert) flipVertical(result);
+
return result;
}
@@ -3187,7 +3329,7 @@ int Visage::getFrameCount() const {
return READ_LE_UINT16(_data);
}
-void Visage::flip(GfxSurface &gfxSurface) {
+void Visage::flipHorizontal(GfxSurface &gfxSurface) {
Graphics::Surface s = gfxSurface.lockSurface();
for (int y = 0; y < s.h; ++y) {
@@ -3200,6 +3342,21 @@ void Visage::flip(GfxSurface &gfxSurface) {
gfxSurface.unlockSurface();
}
+void Visage::flipVertical(GfxSurface &gfxSurface) {
+ Graphics::Surface s = gfxSurface.lockSurface();
+
+ for (int y = 0; y < s.h / 2; ++y) {
+ // 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]);
+ }
+
+ gfxSurface.unlockSurface();
+}
+
/*--------------------------------------------------------------------------*/
Player::Player(): SceneObject() {
@@ -3236,8 +3393,9 @@ void Player::postInit(SceneObjectList *OwnerList) {
{
_moveDiff.x = 3;
_moveDiff.y = 2;
- _effect = 1;
+ _effect = EFFECT_SHADED;
_shade = 0;
+ _linkedActor = NULL;
setObjectWrapper(new SceneObjectWrapper());
setPosition(_characterPos[_characterIndex]);
@@ -3249,20 +3407,24 @@ void Player::postInit(SceneObjectList *OwnerList) {
void Player::disableControl() {
_canWalk = false;
- _uiEnabled = false;
g_globals->_events.setCursor(CURSOR_NONE);
_enabled = false;
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
- T2_GLOBALS._uiElements.hide();
+ if (g_vm->getGameID() != GType_Ringworld2) {
+ _uiEnabled = false;
+
+ if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ T2_GLOBALS._uiElements.hide();
+ }
}
void Player::enableControl() {
CursorType cursor;
_canWalk = true;
- _uiEnabled = true;
_enabled = true;
+ if (g_vm->getGameID() != GType_Ringworld2)
+ _uiEnabled = true;
switch (g_vm->getGameID()) {
case GType_BlueForce:
@@ -3270,7 +3432,7 @@ void Player::enableControl() {
cursor = g_globals->_events.getCursor();
g_globals->_events.setCursor(cursor);
- if (T2_GLOBALS._uiElements._active)
+ if (g_vm->getGameID() == GType_BlueForce && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.show();
break;
@@ -3968,7 +4130,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();
@@ -4180,11 +4342,11 @@ void SceneHandler::process(Event &event) {
g_vm->_debugger->onFrame();
}
- if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled && g_globals->_player._canWalk) {
+ if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled) {
// Keyboard shortcuts for different actions
switch (event.kbd.keycode) {
case Common::KEYCODE_w:
- g_globals->_events.setCursor(CURSOR_WALK);
+ g_globals->_events.setCursor(GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
event.handled = true;
break;
case Common::KEYCODE_l:
@@ -4218,9 +4380,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;
@@ -4267,10 +4430,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 296754011e..3286ee1448 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -466,17 +466,23 @@ enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MOD
ANIM_MODE_9 = 9
};
+// Actor effect enumeration used in Return to Ringworld 2
+enum Effect { EFFECT_NONE = 0, EFFECT_SHADED = 1, EFFECT_3 = 3,
+ EFFECT_SHADOW_MAP = 5, EFFECT_SHADED2 = 6 };
+
class SceneObject;
class Visage {
private:
byte *_data;
- void flip(GfxSurface &s);
+ void flipHorizontal(GfxSurface &s);
+ void flipVertical(GfxSurface &s);
public:
int _resNum;
int _rlbNum;
bool _flipHoriz;
+ bool _flipVert;
public:
Visage();
Visage(const Visage &v);
@@ -509,7 +515,8 @@ public:
enum ObjectFlags {OBJFLAG_FIXED_PRIORITY = 1, OBJFLAG_NO_UPDATES = 2, OBJFLAG_ZOOMED = 4,
OBJFLAG_SUPPRESS_DISPATCH = 8, OBJFLAG_HIDE = 0x100, OBJFLAG_HIDING = 0x200, OBJFLAG_REMOVE = 0x400,
OBJFLAG_CLONED = 0x800, OBJFLAG_CHECK_REGION = 0x1000, OBJFLAG_PANE_0 = 0x4000, OBJFLAG_PANE_1 = 0x8000,
- OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1
+ OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1,
+ OBJFLAG_FLIP_CENTROID_X = 0x10000, OBJFLAG_FLIP_CENTROID_Y = 0x20000
};
class SceneObject : public SceneHotspot {
@@ -542,13 +549,13 @@ public:
EventHandler *_mover;
Common::Point _moveDiff;
int _moveRate;
- Common::Point _field8A;
+ Common::Point _actorDestPos;
Action *_endAction;
uint32 _regionBitList;
// Ringworld 2 specific fields
- byte *_field9C;
- int _shade, _shade2;
+ byte *_shadowMap;
+ int _shade, _oldShade;
int _effect;
SceneObject *_linkedActor;
public:
@@ -573,7 +580,6 @@ public:
int getRegionIndex();
int checkRegion(const Common::Point &pt);
void animate(AnimateMode animMode, ...);
- SceneObject *clone() const;
void checkAngle(const SceneObject *obj);
void checkAngle(const Common::Point &pt);
void hide();
@@ -600,6 +606,7 @@ public:
virtual void changeAngle(int angle);
// New methods introduced by Ringworld 2
virtual void copy(SceneObject *src);
+ virtual SceneObject *clone() const;
void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);
void setup(int visage, int stripFrameNum, int frameNum);
@@ -610,8 +617,10 @@ public:
virtual Common::String getClassName() { return "BackgroundSceneObject"; }
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();
+ virtual SceneObject *clone() const;
+
+ void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority, int effect);
+ static void copySceneToBackground();
};
class SceneText : public SceneObject {
@@ -898,6 +907,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/debugger.cpp b/engines/tsage/debugger.cpp
index 82645f2d62..c7da5f5d30 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -632,57 +632,57 @@ bool Ringworld2Debugger::Cmd_ListObjects(int argc, const char **argv) {
DebugPrintf("Available objects for this game are:\n");
DebugPrintf("1 - R2_OPTO_DISK\n");
- DebugPrintf("2 - R2_2\n");
+ DebugPrintf("2 - R2_READER\n");
DebugPrintf("3 - R2_NEGATOR_GUN\n");
DebugPrintf("4 - R2_STEPPING_DISKS\n");
- DebugPrintf("5 - R2_5\n");
- DebugPrintf("6 - R2_6\n");
- DebugPrintf("7 - R2_7\n");
- DebugPrintf("8 - R2_8\n");
- DebugPrintf("9 - R2_9\n");
- DebugPrintf("10 - R2_10\n");
- DebugPrintf("11 - R2_11\n");
- DebugPrintf("12 - R2_12\n");
- DebugPrintf("13 - R2_13\n");
- DebugPrintf("14 - R2_14\n");
- DebugPrintf("15 - R2_15\n");
- DebugPrintf("16 - R2_16\n");
- DebugPrintf("17 - R2_17\n");
- DebugPrintf("18 - R2_18\n");
- DebugPrintf("19 - R2_19\n");
- DebugPrintf("20 - R2_20\n");
- DebugPrintf("21 - R2_21\n");
- DebugPrintf("22 - R2_22\n");
- DebugPrintf("23 - R2_23\n");
- DebugPrintf("24 - R2_24\n");
- DebugPrintf("25 - R2_25\n");
- DebugPrintf("26 - R2_26\n");
- DebugPrintf("27 - R2_27\n");
- DebugPrintf("28 - R2_28\n");
- DebugPrintf("29 - R2_29\n");
- DebugPrintf("30 - R2_30\n");
- DebugPrintf("31 - R2_31\n");
- DebugPrintf("32 - R2_32\n");
- DebugPrintf("33 - R2_33\n");
- DebugPrintf("34 - R2_34\n");
- DebugPrintf("35 - R2_35\n");
- DebugPrintf("36 - R2_36\n");
- DebugPrintf("37 - R2_37\n");
- DebugPrintf("38 - R2_38\n");
- DebugPrintf("39 - R2_39\n");
- DebugPrintf("40 - R2_40\n");
- DebugPrintf("41 - R2_41\n");
- DebugPrintf("42 - R2_42\n");
- DebugPrintf("43 - R2_43\n");
- DebugPrintf("44 - R2_44\n");
- DebugPrintf("45 - R2_45\n");
- DebugPrintf("46 - R2_46\n");
- DebugPrintf("47 - R2_47\n");
- DebugPrintf("48 - R2_48\n");
- DebugPrintf("49 - R2_49\n");
- DebugPrintf("50 - R2_50\n");
- DebugPrintf("51 - R2_51\n");
- DebugPrintf("52 - R2_52\n");
+ DebugPrintf("5 - R2_ATTRACTOR_UNIT\n");
+ DebugPrintf("6 - R2_SENSOR_PROBE\n");
+ DebugPrintf("7 - R2_SONIC_STUNNER\n");
+ DebugPrintf("8 - R2_CABLE_HARNESS\n");
+ DebugPrintf("9 - R2_COM_SCANNER\n");
+ DebugPrintf("10 - R2_SPENT_POWER_CAPSULE\n");
+ DebugPrintf("11 - R2_CHARGED_POWER_CAPSULE\n");
+ DebugPrintf("12 - R2_AEROSOL\n");
+ DebugPrintf("13 - R2_REMOTE_CONTROL\n");
+ DebugPrintf("14 - R2_OPTICAL_FIBRE\n");
+ DebugPrintf("15 - R2_CLAMP\n");
+ DebugPrintf("16 - R2_ATTRACTOR_CABLE_HARNESS\n");
+ DebugPrintf("17 - R2_FUEL_CELL\n");
+ DebugPrintf("18 - R2_GYROSCOPE\n");
+ DebugPrintf("19 - R2_AIRBAG\n");
+ DebugPrintf("20 - R2_REBREATHER_TANK\n");
+ DebugPrintf("21 - R2_RESERVE_REBREATHER_TANK\n");
+ DebugPrintf("22 - R2_GUIDANCE_MODULE\n");
+ DebugPrintf("23 - R2_THRUSTER_VALVE\n");
+ DebugPrintf("24 - R2_BALLOON_BACKPACK\n");
+ DebugPrintf("25 - R2_RADAR_MECHANISM\n");
+ DebugPrintf("26 - R2_JOYSTICK\n");
+ DebugPrintf("27 - R2_IGNITOR\n");
+ DebugPrintf("28 - R2_DIAGNOSTICS_DISPLAY\n");
+ DebugPrintf("29 - R2_GLASS_DOME\n");
+ DebugPrintf("30 - R2_WICK_LAMP\n");
+ DebugPrintf("31 - R2_SCRITH_KEY\n");
+ DebugPrintf("32 - R2_TANNER_MASK\n");
+ DebugPrintf("33 - R2_PURE_GRAIN_ALCOHOL\n");
+ DebugPrintf("34 - R2_SAPPHIRE_BLUE\n");
+ DebugPrintf("35 - R2_ANCIENT_SCROLLS\n");
+ DebugPrintf("36 - R2_FLUTE\n");
+ DebugPrintf("37 - R2_GUNPOWDER\n");
+ DebugPrintf("38 - R2_NONAME\n");
+ DebugPrintf("39 - R2_COM_SCANNER_2\n");
+ DebugPrintf("40 - R2_SUPERCONDUCTOR_WIRE\n");
+ DebugPrintf("41 - R2_PILLOW\n");
+ DebugPrintf("42 - R2_FOOD_TRAY\n");
+ DebugPrintf("43 - R2_LASER_HACKSAW\n");
+ DebugPrintf("44 - R2_PHOTON_STUNNER\n");
+ DebugPrintf("45 - R2_BATTERY\n");
+ DebugPrintf("46 - R2_SOAKED_FACEMASK\n");
+ DebugPrintf("47 - R2_LIGHT_BULB\n");
+ DebugPrintf("48 - R2_ALCOHOL_LAMP\n");
+ DebugPrintf("49 - R2_ALCOHOL_LAMP_2\n");
+ DebugPrintf("50 - R2_ALCOHOL_LAMP_3\n");
+ DebugPrintf("51 - R2_BROKEN_DISPLAY\n");
+ DebugPrintf("52 - R2_TOOLBOX\n");
return true;
}
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index a35d663b93..5eae7557d2 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -75,7 +75,6 @@ class TSageMetaEngine : public AdvancedMetaEngine {
public:
TSageMetaEngine() : AdvancedMetaEngine(TsAGE::gameDescriptions, sizeof(TsAGE::tSageGameDescription), tSageGameTitles) {
_singleid = "tsage";
- _guioptions = GUIO1(GUIO_NOSPEECH);
}
virtual const char *getName() const {
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index b374dbc98b..0f7f1e49bb 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -165,7 +165,7 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("r2rw.rlb", "df6c25622387007788ca36d99362c1f0", 47586928),
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO0()
},
GType_Ringworld2,
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..6baa654214 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -71,7 +71,7 @@ bool EventsClass::pollEvent() {
break;
default:
- break;
+ break;
}
return true;
@@ -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;
@@ -271,13 +271,18 @@ void EventsClass::setCursor(CursorType cursorType) {
_currentCursor = cursorType;
cursor = g_resourceManager->getSubResource(5, 1, cursorType - R2CURSORS_START, &size);
break;
+
+ case R2_CURSOR_ROPE:
+ _currentCursor = cursorType;
+ cursor = g_resourceManager->getSubResource(5, 4, 1, &size);
+ break;
}
// Decode the cursor
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 +338,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 +351,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 +360,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/events.h b/engines/tsage/events.h
index a1e9da3477..9ef4813e47 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -108,6 +108,7 @@ enum CursorType {
EXITCURSOR_NE = 0x800D, EXITCURSOR_SE = 0x800E, EXITCURSOR_SW = 0x800F, EXITCURSOR_NW = 0x8010,
SHADECURSOR_UP = 0x8011, SHADECURSOR_DOWN = 0x8012, SHADECURSOR_HAND = 0x8013,
R2_CURSOR_20 = 0x8014, R2_CURSOR_21 = 0x8015, R2_CURSOR_22 = 0x8016, R2_CURSOR_23 = 0x8017,
+ R2_CURSOR_ROPE = 0x8025,
// Cursors
CURSOR_WALK = 0x100, CURSOR_LOOK = 0x200, CURSOR_700 = 700, CURSOR_USE = 0x400, CURSOR_TALK = 0x800,
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 4589a926c9..388f6f7686 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -26,6 +26,8 @@
#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_scenes0.h"
+#include "tsage/staticres.h"
namespace TsAGE {
@@ -46,6 +48,11 @@ static SavedObject *classFactoryProc(const Common::String &className) {
if (className == "SceneObjectWrapper") return new SceneObjectWrapper();
if (className == "PaletteRotation") return new PaletteRotation();
if (className == "PaletteFader") return new PaletteFader();
+ if (className == "SceneText") return new SceneText();
+
+ // Return to Ringworld specific classes
+ if (className == "Scene205_Star") return new Ringworld2::Star();
+
return NULL;
}
@@ -118,8 +125,11 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_sounds.push_back(&_soundHandler);
_sounds.push_back(&_sequenceManager._soundHandler);
- _scrollFollower = NULL;
- _inventory = NULL;
+ _scrollFollower = nullptr;
+
+ _inventory = nullptr;
+ _game = nullptr;
+ _sceneHandler = nullptr;
switch (g_vm->getGameID()) {
case GType_Ringworld:
@@ -144,6 +154,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_sceneHandler = new Ringworld2::SceneHandlerExt();
break;
}
+
}
Globals::~Globals() {
@@ -203,6 +214,11 @@ void Globals::dispatchSounds() {
/*--------------------------------------------------------------------------*/
+TsAGE2Globals::TsAGE2Globals() {
+ _onSelectItem = NULL;
+ _interfaceY = 0;
+}
+
void TsAGE2Globals::reset() {
Globals::reset();
@@ -223,15 +239,46 @@ void TsAGE2Globals::synchronize(Serializer &s) {
namespace BlueForce {
BlueForceGlobals::BlueForceGlobals(): TsAGE2Globals() {
+ _hiddenDoorStatus = 0;
+ _nico910State = 0;
+ _stuart910State = 0;
+ _nico910Talk = 0;
+ _stuart910Talk = 0;
+ _deziTopic = 0;
+ _deathReason = 0;
+ _driveFromScene = 300;
+ _driveToScene = 0;
+ _subFlagBitArr1 = 0;
+ _subFlagBitArr2 = 0;
+ _scene410HarrisonTalkFl = false;
+ _scene410Action1Count = 0;
+ _scene410TalkCount = 0;
+ _scene410HarrisonMovedFl = false;
+ _bookmark = bNone;
+ _mapLocationId = 1;
+ _clip1Bullets = 8;
+ _clip2Bullets = 8;
+
+ _dayNumber = 0;
+ _tonyDialogCtr = 0;
+ _marinaWomanCtr = 0;
+ _kateDialogCtr = 0;
+ _v4CEB6 = 0;
+ _safeCombination = 0;
+ _gateStatus = 0;
+ _greenDay5TalkCtr = 0;
+ _v4CEC8 = 1;
+ _v4CECA = 0;
+ _v4CECC = 0;
}
void BlueForceGlobals::synchronize(Serializer &s) {
TsAGE2Globals::synchronize(s);
+ int16 useless = 0;
s.syncAsSint16LE(_dayNumber);
if (s.getVersion() < 9) {
- int tmpVar = 0;
- s.syncAsSint16LE(tmpVar);
+ s.syncAsSint16LE(useless);
}
s.syncAsSint16LE(_tonyDialogCtr);
s.syncAsSint16LE(_marinaWomanCtr);
@@ -240,7 +287,8 @@ void BlueForceGlobals::synchronize(Serializer &s) {
s.syncAsSint16LE(_safeCombination);
s.syncAsSint16LE(_gateStatus);
s.syncAsSint16LE(_greenDay5TalkCtr);
- s.syncAsSint16LE(_v4CEC4);
+ if (s.getVersion() < 11)
+ s.syncAsSint16LE(useless);
s.syncAsSint16LE(_v4CEC8);
s.syncAsSint16LE(_v4CECA);
s.syncAsSint16LE(_v4CECC);
@@ -248,26 +296,30 @@ void BlueForceGlobals::synchronize(Serializer &s) {
s.syncAsByte(_breakerBoxStatusArr[i]);
s.syncAsSint16LE(_hiddenDoorStatus);
s.syncAsSint16LE(_nico910State);
- s.syncAsSint16LE(_v4CEE4);
- s.syncAsSint16LE(_v4CEE6);
- s.syncAsSint16LE(_v4CEE8);
+ s.syncAsSint16LE(_stuart910State);
+ s.syncAsSint16LE(_nico910Talk);
+ s.syncAsSint16LE(_stuart910Talk);
s.syncAsSint16LE(_deziTopic);
s.syncAsSint16LE(_deathReason);
s.syncAsSint16LE(_driveFromScene);
s.syncAsSint16LE(_driveToScene);
- s.syncAsSint16LE(_v501F8);
- s.syncAsSint16LE(_v501FA);
- s.syncAsSint16LE(_v501FC);
- s.syncAsSint16LE(_v5020C);
- s.syncAsSint16LE(_v50696);
+ if (s.getVersion() < 11) {
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_subFlagBitArr1);
s.syncAsSint16LE(_subFlagBitArr2);
- s.syncAsSint16LE(_v50CC2);
- s.syncAsSint16LE(_v50CC4);
- s.syncAsSint16LE(_v50CC6);
- s.syncAsSint16LE(_v50CC8);
- s.syncAsSint16LE(_v51C42);
- s.syncAsSint16LE(_v51C44);
+ s.syncAsSint16LE(_scene410HarrisonTalkFl);
+ s.syncAsSint16LE(_scene410Action1Count);
+ s.syncAsSint16LE(_scene410TalkCount);
+ s.syncAsSint16LE(_scene410HarrisonMovedFl);
+ if (s.getVersion() < 11) {
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_bookmark);
s.syncAsSint16LE(_mapLocationId);
s.syncAsSint16LE(_clip1Bullets);
@@ -297,7 +349,6 @@ void BlueForceGlobals::reset() {
_safeCombination = 0;
_gateStatus = 0;
_greenDay5TalkCtr = 0;
- _v4CEC4 = 0;
_v4CEC8 = 1;
_v4CECA = 0;
_v4CECC = 0;
@@ -321,24 +372,17 @@ void BlueForceGlobals::reset() {
_breakerBoxStatusArr[17] = 0;
_hiddenDoorStatus = 0;
_nico910State = 0;
- _v4CEE4 = 0;
- _v4CEE6 = 0;
- _v4CEE8 = 0;
+ _stuart910State = 0;
+ _nico910Talk = 0;
+ _stuart910Talk = 0;
_deziTopic = 0;
_deathReason = 0;
- _v501F8 = 0;
- _v501FA = 0;
- _v501FC = 0;
- _v5020C = 0;
- _v50696 = 0;
_subFlagBitArr1 = 0;
_subFlagBitArr2 = 0;
- _v50CC2 = 0;
- _v50CC4 = 0;
- _v50CC6 = 0;
- _v50CC8 = 0;
- _v51C42 = 0;
- _v51C44 = 1;
+ _scene410HarrisonTalkFl = false;
+ _scene410Action1Count = 0;
+ _scene410TalkCount = 0;
+ _scene410HarrisonMovedFl = false;
_clip1Bullets = 8;
_clip2Bullets = 8;
}
@@ -366,107 +410,158 @@ bool BlueForceGlobals::removeFlag(int flagNum) {
namespace Ringworld2 {
+Ringworld2Globals::Ringworld2Globals() {
+ _scannerDialog = new ScannerDialog();
+ _speechSubtitles = SPEECH_TEXT;
+
+ // Register the inner sound objects for each of the global ASoundExt fields.
+ // Normally the ASound constructor would do this, but because they're fields
+ // of the globals, the g_globals reference isn't ready for them to use
+ _sounds.push_back(&_sound1);
+ _sounds.push_back(&_sound2);
+ _sounds.push_back(&_sound3);
+ _sounds.push_back(&_sound4);
+
+ // Initialize fields
+ _stripModifier = 0;
+ _flubMazeArea = 1;
+ _flubMazeEntryDirection = 0;
+ _maze3800SceneNumb = 3800;
+ _landerSuitNumber = 2;
+ _desertStepsRemaining = 5;
+ _desertCorrectDirection = 0;
+ _desertPreviousDirection = 0;
+ _desertWrongDirCtr = -1;
+ _balloonAltitude = 5;
+ _scene1925CurrLevel = 0;
+ _walkwaySceneNumber = 0;
+ _mirandaJailState = 0;
+ _scientistConvIndex = 0;
+ _ductMazePanel1State = 1;
+ _ductMazePanel2State = 1;
+ _ductMazePanel3State = 1;
+ _scene180Mode = -1;
+ _v57709 = 0;
+ _v5780C = 0;
+ _v5780E = 0;
+ _v57810 = 0;
+
+ _fadePaletteFlag = false;
+ _insetUp = 0;
+ _frameEdgeColor = 2;
+ _animationCtr = 0;
+ _electromagnetChangeAmount = 0;
+ _electromagnetZoom = 0;
+ _tractorField = false;
+ _cableAttached = 0;
+ _foodCount = 0;
+ _rimLocation = 0;
+ _rimTransportLocation = 0;
+}
+
+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;
- _v5589E.set(0, 0, 0, 0);
- _v558B6.set(0, 0, 0, 0);
- _v558C2 = 0;
- _animationCtr = 0;
- _v5657C = 0;
- _v565E1 = 0;
- _v565E3 = 0;
- _v565E5 = 0;
- _v565E7 = 0;
- _v565E9 = -5;
- _v565EB = 26;
- _v565F5 = 0;
- _v565F6 = 0;
- _v565FA = 0;
- _v565AE = 0;
- _v56605[0] = 0;
- _v56605[1] = 3;
- _v56605[2] = 5;
- _v56605[3] = 1;
- _v56605[4] = 2;
- _v56605[5] = 5;
- _v56605[6] = 9;
- _v56605[7] = 14;
- _v56605[8] = 15;
- _v56605[9] = 18;
- _v56605[10] = 20;
- _v56605[11] = 25;
- _v56605[12] = 27;
- _v56605[13] = 31;
+ Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[9][256], 0);
+ Common::fill(&_paletteMap[0], &_paletteMap[4096], 0);
+ _fadePaletteFlag = false;
+ _animationCtr = 0;
+ _electromagnetChangeAmount = 0;
+ _electromagnetZoom = 0;
+ _tractorField = false;
+ _cableAttached = 0;
+ _foodCount = 0;
+ _rimLocation = 0;
+ _rimTransportLocation = 0;
+ _stripModifier = 0;
+ _spillLocation[0] = 0;
+ _spillLocation[1] = 3;
+ _spillLocation[R2_SEEKER] = 5;
+ _spillLocation[3] = 1;
+ _spillLocation[4] = 2;
+ _spillLocation[5] = 5;
+ _spillLocation[6] = 9;
+ _spillLocation[7] = 14;
+ _spillLocation[8] = 15;
+ _spillLocation[9] = 18;
+ _spillLocation[10] = 20;
+ _spillLocation[11] = 25;
+ _spillLocation[12] = 27;
+ _spillLocation[13] = 31;
+
+ // Initialize the vampire data within the Flub maze
for (int i = 0; i < 18; i++) {
- _v56613[(i * 4) ] = 1;
- _v56613[(i * 4) + 2] = 0;
- _v56613[(i * 4) + 3] = 0;
+ _vampireData[i]._isAlive = true;
+ _vampireData[i]._position = Common::Point();
}
- _v56613[( 0 * 4) + 1] = 1;
- _v56613[( 1 * 4) + 1] = 2;
- _v56613[( 2 * 4) + 1] = 2;
- _v56613[( 3 * 4) + 1] = 3;
- _v56613[( 4 * 4) + 1] = 2;
- _v56613[( 5 * 4) + 1] = 2;
- _v56613[( 6 * 4) + 1] = 3;
- _v56613[( 7 * 4) + 1] = 1;
- _v56613[( 8 * 4) + 1] = 1;
- _v56613[( 9 * 4) + 1] = 3;
- _v56613[(10 * 4) + 1] = 3;
- _v56613[(11 * 4) + 1] = 1;
- _v56613[(12 * 4) + 1] = 2;
- _v56613[(13 * 4) + 1] = 3;
- _v56613[(14 * 4) + 1] = 2;
- _v56613[(15 * 4) + 1] = 3;
- _v56613[(16 * 4) + 1] = 1;
- _v56613[(17 * 4) + 1] = 1;
-
- _v566A6 = 3800;
- _v566A3 = 2;
- _v566A4 = 1;
- _v566A5 = 0;
- _v566A8 = 5;
- _v566A9 = 0;
- _v566AA = 0;
+ _vampireData[0]._shotsRequired = 1;
+ _vampireData[1]._shotsRequired = 2;
+ _vampireData[2]._shotsRequired = 2;
+ _vampireData[3]._shotsRequired = 3;
+ _vampireData[4]._shotsRequired = 2;
+ _vampireData[5]._shotsRequired = 2;
+ _vampireData[6]._shotsRequired = 3;
+ _vampireData[7]._shotsRequired = 1;
+ _vampireData[8]._shotsRequired = 1;
+ _vampireData[9]._shotsRequired = 3;
+ _vampireData[10]._shotsRequired = 3;
+ _vampireData[11]._shotsRequired = 1;
+ _vampireData[12]._shotsRequired = 2;
+ _vampireData[13]._shotsRequired = 3;
+ _vampireData[14]._shotsRequired = 2;
+ _vampireData[15]._shotsRequired = 3;
+ _vampireData[16]._shotsRequired = 1;
+ _vampireData[17]._shotsRequired = 1;
+
+ _maze3800SceneNumb = 3800;
+ _landerSuitNumber = 2;
+ _flubMazeArea = 1;
+ _flubMazeEntryDirection = 0;
+ _desertStepsRemaining = 5;
+ _desertCorrectDirection = 0;
+ _desertPreviousDirection = 0;
for (int i = 0; i < 1000; i++)
- _v566AB[i] = 0;
- _v56A93 = -1;
- _v56A99 = 5;
+ _desertMovements[i] = 0;
+ _desertWrongDirCtr = -1;
+ _balloonAltitude = 5;
_scene1925CurrLevel = 0; //_v56A9C
- _v56A9E = 0;
- _v56AA0 = 0;
- _v56AA1 = 0;
- _v56AA2 = 60;
- _v56AA4 = 660;
- _v56AA6 = 1;
- _v56AA7 = 1;
- _v56AA8 = 1;
- _v56AAB = 0;
+ _walkwaySceneNumber = 0;
+ _mirandaJailState = 0;
+ _scientistConvIndex = 0;
+ _ventCellPos = Common::Point(60, 660);
+ _ductMazePanel1State = 1;
+ _ductMazePanel2State = 1;
+ _ductMazePanel3State = 1;
_scene180Mode = -1;
_v57709 = 0;
_v5780C = 0;
_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);
- _speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
+ _s1550PlayerArea[R2_QUINN] = Common::Point(27, 4);
+ _s1550PlayerArea[R2_SEEKER] = Common::Point(27, 4);
+ Common::fill(&_scannerFrequencies[0], &_scannerFrequencies[MAX_CHARACTERS], 1);
_insetUp = 0;
- _frameEdgeColour = 2;
+ _frameEdgeColor = 2;
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
_stripManager_lookupList[0] = 1;
_stripManager_lookupList[1] = 1;
@@ -479,76 +574,86 @@ 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;
- _player._characterScene[2] = 300;
- _player._characterScene[3] = 300;
+ _player._characterScene[R2_QUINN] = 100;
+ _player._characterScene[R2_SEEKER] = 300;
+ _player._characterScene[R2_MIRANDA] = 300;
}
void Ringworld2Globals::synchronize(Serializer &s) {
TsAGE2Globals::synchronize(s);
int i;
- _v5589E.synchronize(s);
- _v558B6.synchronize(s);
-
- s.syncAsSint16LE(_v558C2);
s.syncAsSint16LE(_animationCtr);
- s.syncAsSint16LE(_v5657C);
- s.syncAsSint16LE(_v565E1);
- s.syncAsSint16LE(_v565E3);
- 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(_v566A6);
- s.syncAsSint16LE(_v56A93);
+ s.syncAsSint16LE(_electromagnetChangeAmount);
+ s.syncAsSint16LE(_electromagnetZoom);
+ s.syncAsSint16LE(_tractorField);
+ s.syncAsSint16LE(_cableAttached);
+ s.syncAsSint16LE(_foodCount);
+ s.syncAsSint32LE(_rimLocation);
+ s.syncAsSint16LE(_rimTransportLocation);
+ s.syncAsSint16LE(_landerSuitNumber);
+ s.syncAsSint16LE(_maze3800SceneNumb);
+ s.syncAsSint16LE(_desertWrongDirCtr);
s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
- s.syncAsSint16LE(_v56A9E);
- s.syncAsSint16LE(_v56AA2);
- s.syncAsSint16LE(_v56AA4);
- s.syncAsSint16LE(_v56AAB);
+ s.syncAsSint16LE(_walkwaySceneNumber);
+ s.syncAsSint16LE(_ventCellPos.x);
+ s.syncAsSint16LE(_ventCellPos.y);
s.syncAsSint16LE(_scene180Mode);
s.syncAsSint16LE(_v57709);
s.syncAsSint16LE(_v5780C);
s.syncAsSint16LE(_v5780E);
s.syncAsSint16LE(_v57810);
- s.syncAsSint16LE(_v57C2C);
- s.syncAsSint16LE(_speechSubtitles);
- for (i = 0; i < 5; i++)
- s.syncAsByte(_v565EC[i]);
+ 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(_v565AE);
- s.syncAsByte(_v566A4);
- s.syncAsByte(_v566A5);
- s.syncAsByte(_v566A8);
- s.syncAsByte(_v566A9);
- s.syncAsByte(_v566AA);
- s.syncAsByte(_v56AA0);
- s.syncAsByte(_v56AA1);
- s.syncAsByte(_v56AA6);
- s.syncAsByte(_v56AA7);
- s.syncAsByte(_v56AA8);
+ s.syncAsByte(_scannerFrequencies[i]);
+
+ s.syncAsByte(_stripModifier);
+ s.syncAsByte(_flubMazeArea);
+ s.syncAsByte(_flubMazeEntryDirection);
+ s.syncAsByte(_desertStepsRemaining);
+ s.syncAsByte(_desertCorrectDirection);
+ s.syncAsByte(_desertPreviousDirection);
+ s.syncAsByte(_mirandaJailState);
+ s.syncAsByte(_scientistConvIndex);
+ s.syncAsByte(_ductMazePanel1State);
+ s.syncAsByte(_ductMazePanel2State);
+ s.syncAsByte(_ductMazePanel3State);
for (i = 0; i < 14; ++i)
- s.syncAsByte(_v56605[i]);
+ s.syncAsByte(_spillLocation[i]);
for (i = 0; i < 1000; ++i)
- s.syncAsByte(_v566AB[i]);
- s.syncAsByte(_v56A99);
+ s.syncAsByte(_desertMovements[i]);
+ s.syncAsByte(_balloonAltitude);
for (i = 0; i < 12; ++i)
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]);
+
+ s.syncAsSint16LE(_balloonPosition.x);
+ s.syncAsSint16LE(_balloonPosition.y);
+
+ // Synchronize Flub maze vampire data
+ for (i = 0; i < 18; ++i) {
+ s.syncAsSint16LE(_vampireData[i]._isAlive);
+ s.syncAsSint16LE(_vampireData[i]._shotsRequired);
+ s.syncAsSint16LE(_vampireData[i]._position.x);
+ s.syncAsSint16LE(_vampireData[i]._position.y);
+ }
}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index d190b6a2a4..92c3d2e24b 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -110,7 +110,7 @@ public:
int _interfaceY;
ASoundExt _inventorySound;
- TsAGE2Globals() { _onSelectItem = NULL; }
+ TsAGE2Globals();
virtual void reset();
virtual void synchronize(Serializer &s);
};
@@ -194,33 +194,25 @@ public:
int _safeCombination;
int _gateStatus;
int _greenDay5TalkCtr;
- int _v4CEC4;
int _v4CEC8;
int _v4CECA;
int _v4CECC;
int8 _breakerBoxStatusArr[18];
int _hiddenDoorStatus;
int _nico910State;
- int _v4CEE4;
- int _v4CEE6;
- int _v4CEE8;
+ int _stuart910State;
+ int _nico910Talk;
+ int _stuart910Talk;
int _deziTopic;
int _deathReason;
int _driveFromScene;
int _driveToScene;
- int _v501F8;
- int _v501FA;
- int _v501FC;
- int _v5020C;
- int _v50696;
uint8 _subFlagBitArr1;
uint8 _subFlagBitArr2;
- int _v50CC2;
- int _v50CC4;
- int _v50CC6;
- int _v50CC8;
- int _v51C42;
- int _v51C44;
+ bool _scene410HarrisonTalkFl;
+ int _scene410Action1Count;
+ int _scene410TalkCount;
+ bool _scene410HarrisonMovedFl;
Bookmark _bookmark;
int _mapLocationId;
int _clip1Bullets, _clip2Bullets;
@@ -242,69 +234,69 @@ namespace Ringworld2 {
#define SPEECH_TEXT 1
#define SPEECH_VOICE 2
-#define k5A78C 15
-#define k5A78D 16
-#define k5A790 18
-#define k5A791 17
+class ScannerDialog;
+
+struct VampireData {
+ bool _isAlive;
+ int _shotsRequired;
+ Common::Point _position;
+};
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
- Rect _v5589E;
- Rect _v558B6;
- int _v558C2;
+ int _frameEdgeColor;
int _animationCtr;
- int _v565E1;
- int _v565E3;
- int _v565E5;
- int _v565E7;
- int _v565E9;
- int _v565EB;
- int _v565F5;
- int _v565F6;
- int _v565FA;
- int _v5657C;
- byte _v565AE;
- byte _v56605[14];
- int _v56613[76];
- byte _v566A4;
- byte _v566A5;
- int _v566A6;
- byte _v566A3;
- byte _v566A8;
- byte _v566A9;
- byte _v566AA;
- byte _v566AB[1000];
- int _v56A93;
- byte _v56A99;
+ int _electromagnetChangeAmount;
+ int _electromagnetZoom;
+ bool _tractorField;
+ bool _cableAttached;
+ int _foodCount;
+ int _rimLocation;
+ int _rimTransportLocation;
+ byte _stripModifier;
+ byte _spillLocation[14];
+ VampireData _vampireData[18];
+ byte _flubMazeArea;
+ byte _flubMazeEntryDirection;
+ int _maze3800SceneNumb;
+ byte _landerSuitNumber;
+ byte _desertStepsRemaining;
+ byte _desertCorrectDirection;
+ byte _desertPreviousDirection;
+ byte _desertMovements[1000];
+ int _desertWrongDirCtr;
+ byte _balloonAltitude;
int _scene1925CurrLevel; //_v56A9C
- int _v56A9E;
- byte _v56AA0;
- byte _v56AA1;
- int _v56AA2;
- int _v56AA4;
- byte _v56AA6;
- byte _v56AA7;
- byte _v56AA8;
- int _v56AAB;
+ int _walkwaySceneNumber;
+ byte _mirandaJailState;
+ byte _scientistConvIndex;
+ Common::Point _ventCellPos;
+ byte _ductMazePanel1State;
+ byte _ductMazePanel2State;
+ byte _ductMazePanel3State;
int _scene180Mode; // _v575f7
int _v57709;
int _v5780C;
int _v5780E;
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];
+ Common::Point _balloonPosition;
+
+ 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 fb0b0b0cbb..fa3ed33302 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);
@@ -68,15 +68,20 @@ GfxSurface surfaceFromRes(const byte *imgData) {
Rect r(0, 0, READ_LE_UINT16(imgData), READ_LE_UINT16(imgData + 2));
GfxSurface s;
s.create(r.width(), r.height());
- s._centroid.x = READ_LE_UINT16(imgData + 4);
- s._centroid.y = READ_LE_UINT16(imgData + 6);
s._transColor = *(imgData + 8);
- bool rleEncoded = (imgData[9] & 2) != 0;
+ byte flags = imgData[9];
+ s._flags = (g_vm->getGameID() != GType_Ringworld) ? flags : 0;
+
+ bool rleEncoded = (flags & 2) != 0;
+
+ // Figure out the centroid
+ s._centroid.x = READ_LE_UINT16(imgData + 4);
+ s._centroid.y = READ_LE_UINT16(imgData + 6);
const byte *srcP = imgData + 10;
Graphics::Surface destSurface = s.lockSurface();
- byte *destP = (byte *)destSurface.getBasePtr(0, 0);
+ byte *destP = (byte *)destSurface.getPixels();
if (!rleEncoded) {
Common::copy(srcP, srcP + (r.width() * r.height()), destP);
@@ -184,8 +189,9 @@ void Rect::contain(const Rect &r) {
* @percent Scaling percentage
*/
void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
- int xe = surface.getBounds().width() * percent / 100;
- int ye = surface.getBounds().height() * percent / 100;
+ const Rect &bounds = surface.getBounds();
+ int xe = bounds.width() * percent / 100;
+ int ye = bounds.height() * percent / 100;
this->set(0, 0, xe, ye);
if (!right) ++right;
@@ -193,8 +199,13 @@ void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
this->moveTo(xp, yp);
- int xd = surface._centroid.x * percent / 100;
- int yd = surface._centroid.y * percent / 100;
+ int xa = (surface._flags & FRAME_FLIP_CENTROID_X) == 0 ? surface._centroid.x :
+ bounds.width() - (surface._centroid.x + 1);
+ int ya = (surface._flags & FRAME_FLIP_CENTROID_Y) == 0 ? surface._centroid.y :
+ bounds.height() - (surface._centroid.y + 1);
+
+ int xd = xa * percent / 100;
+ int yd = ya * percent / 100;
this->translate(-xd, -yd);
}
@@ -224,6 +235,7 @@ GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
_customSurface = NULL;
_transColor = -1;
_trackDirtyRects = false;
+ _flags = 0;
}
GfxSurface::GfxSurface(const GfxSurface &s) {
@@ -234,9 +246,14 @@ GfxSurface::GfxSurface(const GfxSurface &s) {
}
GfxSurface::~GfxSurface() {
+ clear();
+}
+
+void GfxSurface::clear() {
if (_customSurface) {
_customSurface->free();
delete _customSurface;
+ _customSurface = NULL;
}
}
@@ -289,8 +306,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);
}
}
@@ -308,7 +328,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);
}
@@ -324,12 +344,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;
}
@@ -355,7 +370,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);
@@ -372,7 +387,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);
}
}
}
@@ -404,13 +419,14 @@ GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
_bounds = s._bounds;
_centroid = s._centroid;
_transColor = s._transColor;
+ _flags = s._flags;
if (_customSurface) {
// Surface owns the internal data, so replicate it so new surface owns it's own
_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);
}
@@ -556,9 +572,11 @@ static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int trans
}
/**
- * Copys an area from one GfxSurface to another
+ * Copys an area from one GfxSurface to another.
+ *
*/
-void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion) {
+void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds,
+ Region *priorityRegion, const byte *shadowMap) {
GfxSurface srcImage;
if (srcBounds.isEmpty())
return;
@@ -573,7 +591,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);
}
@@ -588,20 +606,24 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
Graphics::Surface srcSurface = srcImage.lockSurface();
Graphics::Surface destSurface = lockSurface();
+ // Get clipping area
+ Rect clipRect = !_clipRect.isEmpty() ? _clipRect :
+ Rect(0, 0, destSurface.w, destSurface.h);
+
// Adjust bounds to ensure destination will be on-screen
int srcX = 0, srcY = 0;
- if (destBounds.left < 0) {
- srcX = -destBounds.left;
- destBounds.left = 0;
+ if (destBounds.left < clipRect.left) {
+ srcX = clipRect.left - destBounds.left;
+ destBounds.left = clipRect.left;
}
- if (destBounds.top < 0) {
- srcY = -destBounds.top;
- destBounds.top = 0;
+ if (destBounds.top < clipRect.top) {
+ srcY = clipRect.top - destBounds.top;
+ destBounds.top = clipRect.top;
}
- if (destBounds.right > destSurface.w)
- destBounds.right = destSurface.w;
- if (destBounds.bottom > destSurface.h)
- destBounds.bottom = destSurface.h;
+ if (destBounds.right > clipRect.right)
+ destBounds.right = clipRect.right;
+ if (destBounds.bottom > clipRect.bottom)
+ destBounds.bottom = clipRect.bottom;
if (destBounds.isValidRect() && !((destBounds.right < 0) || (destBounds.bottom < 0)
|| (destBounds.left >= destSurface.w) || (destBounds.top >= destSurface.h))) {
@@ -624,8 +646,15 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
if (!priorityRegion || !priorityRegion->contains(Common::Point(
xp + g_globals->_sceneManager._scene->_sceneBounds.left,
destBounds.top + y + g_globals->_sceneManager._scene->_sceneBounds.top))) {
- if (*tempSrc != src._transColor)
- *tempDest = *tempSrc;
+ if (*tempSrc != src._transColor) {
+ if (shadowMap) {
+ // Using a shadow map, so translate the dest pixel using the mapping array
+ *tempDest = shadowMap[*tempDest];
+ } else {
+ // Otherwise, it's a standard pixel copy
+ *tempDest = *tempSrc;
+ }
+ }
}
++tempSrc;
++tempDest;
@@ -703,6 +732,11 @@ GfxElement::GfxElement() {
_owner = NULL;
_keycode = 0;
_flags = 0;
+
+ _fontNumber = 0;
+ _color1 = 0;
+ _color2 = 0;
+ _color3 = 0;
}
void GfxElement::setDefaults() {
@@ -790,35 +824,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();
}
@@ -1188,8 +1245,9 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) {
}
void GfxDialog::setPalette() {
- if (g_vm->getGameID() == GType_BlueForce) {
- g_globals->_scenePalette.loadPalette(2);
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if (g_vm->getGameID() == GType_BlueForce)
+ g_globals->_scenePalette.loadPalette(2);
g_globals->_scenePalette.setPalette(0, 1);
g_globals->_scenePalette.setPalette(g_globals->_gfxColors.background, 1);
g_globals->_scenePalette.setPalette(g_globals->_gfxColors.foreground, 1);
@@ -1322,6 +1380,12 @@ void GfxManager::copyFrom(GfxSurface &src, int destX, int destY) {
_surface.copyFrom(src, destX, destY);
}
+void GfxManager::copyFrom(GfxSurface &src, const Rect &srcBounds, const Rect &destBounds) {
+ _surface.setBounds(_bounds);
+
+ _surface.copyFrom(src, srcBounds, destBounds);
+}
+
/*--------------------------------------------------------------------------*/
@@ -1331,6 +1395,8 @@ GfxFont::GfxFont() {
_bpp = 0;
_fontData = NULL;
_fillFlag = false;
+
+ _gfxManager = nullptr;
}
GfxFont::~GfxFont() {
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index 826f2fef6f..47961dd02a 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -71,6 +71,8 @@ public:
LineSlice(int xStart, int xEnd) { xs = xStart; xe = xEnd; }
};
+enum FrameFlag { FRAME_FLIP_CENTROID_X = 4, FRAME_FLIP_CENTROID_Y = 8 };
+
class GfxSurface {
private:
Graphics::Surface *_customSurface;
@@ -88,6 +90,8 @@ private:
public:
Common::Point _centroid;
int _transColor;
+ Rect _clipRect;
+ byte _flags;
public:
GfxSurface();
GfxSurface(const GfxSurface &s);
@@ -100,10 +104,12 @@ public:
void unlockSurface();
void synchronize(Serializer &s);
void create(int width, int height);
+ void clear();
void setBounds(const Rect &bounds) { _bounds = bounds; }
const Rect &getBounds() const { return _bounds; }
- void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion = NULL);
+ void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds,
+ Region *priorityRegion = NULL, const byte *shadowMap = NULL);
void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) {
copyFrom(src, src.getBounds(), destBounds, priorityRegion);
}
@@ -302,6 +308,7 @@ public:
}
void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL);
void copyFrom(GfxSurface &src, int destX, int destY);
+ void copyFrom(GfxSurface &src, const Rect &srcBounds, const Rect &destBounds);
GfxSurface &getSurface() {
_surface.setBounds(_bounds);
diff --git a/engines/tsage/ringworld/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp
index 0584570ac2..1e9d14cdcf 100644
--- a/engines/tsage/ringworld/ringworld_logic.cpp
+++ b/engines/tsage/ringworld/ringworld_logic.cpp
@@ -270,6 +270,11 @@ bool DisplayObject::performAction(int action) {
SceneArea::SceneArea() {
_savedArea = NULL;
_pt.x = _pt.y = 0;
+
+ _resNum = 0;
+ _rlbNum = 0;
+ _subNum = 0;
+ _actionId = 0;
}
SceneArea::~SceneArea() {
diff --git a/engines/tsage/ringworld/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp
index 4d9d565705..5a42bc530d 100644
--- a/engines/tsage/ringworld/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes1.cpp
@@ -52,52 +52,52 @@ void Scene10::Action1::signal() {
scene->_stripManager.start(11, this, scene);
break;
case 3:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object3.setAction(NULL);
- scene->_object4.animate(ANIM_MODE_5, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_veeshkaRightArm.setAction(NULL);
+ scene->_centurion.animate(ANIM_MODE_5, this);
break;
case 4:
case 9:
- scene->_object1.animate(ANIM_MODE_5, this);
+ scene->_veeshkaBody.animate(ANIM_MODE_5, this);
break;
case 5:
- scene->_object2.setStrip(3);
- scene->_object2.setFrame(1);
- scene->_object2.setPosition(Common::Point(240, 51));
- scene->_object2.show();
+ scene->_veeshkaHead.setStrip(3);
+ scene->_veeshkaHead.setFrame(1);
+ scene->_veeshkaHead.setPosition(Common::Point(240, 51));
+ scene->_veeshkaHead.show();
- scene->_object3.setStrip(6);
- scene->_object3.setFrame(1);
- scene->_object3.setPosition(Common::Point(200, 76));
- scene->_object3._numFrames = 20;
- scene->_object3.show();
+ scene->_veeshkaRightArm.setStrip(6);
+ scene->_veeshkaRightArm.setFrame(1);
+ scene->_veeshkaRightArm.setPosition(Common::Point(200, 76));
+ scene->_veeshkaRightArm._numFrames = 20;
+ scene->_veeshkaRightArm.show();
scene->_stripManager.start(12, this, scene);
break;
case 6:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object1.animate(ANIM_MODE_6, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_veeshkaBody.animate(ANIM_MODE_6, this);
break;
case 7:
- scene->_object3.show();
- scene->_object3.setStrip2(5);
- scene->_object3._numFrames = 10;
- scene->_object3.setPosition(Common::Point(180, 87));
- scene->_object3.setAction(&scene->_action2);
+ scene->_veeshkaRightArm.show();
+ scene->_veeshkaRightArm.setStrip2(5);
+ scene->_veeshkaRightArm._numFrames = 10;
+ scene->_veeshkaRightArm.setPosition(Common::Point(180, 87));
+ scene->_veeshkaRightArm.setAction(&scene->_action2);
- scene->_object2.setStrip(4);
- scene->_object2.setFrame(1);
- scene->_object2.setPosition(Common::Point(204, 59));
- scene->_object2.show();
+ scene->_veeshkaHead.setStrip(4);
+ scene->_veeshkaHead.setFrame(1);
+ scene->_veeshkaHead.setPosition(Common::Point(204, 59));
+ scene->_veeshkaHead.show();
scene->_stripManager.start(13, this, scene);
break;
case 8:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object4.animate(ANIM_MODE_6, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_centurion.animate(ANIM_MODE_6, this);
break;
case 10:
g_globals->_soundHandler.fadeOut(this);
@@ -109,6 +109,7 @@ void Scene10::Action1::signal() {
}
}
+// Move Veeshka's fingers
void Scene10::Action2::signal() {
Scene10 *scene = (Scene10 *)g_globals->_sceneManager._scene;
@@ -117,8 +118,8 @@ void Scene10::Action2::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(179));
break;
case 1:
- scene->_object3.setFrame(1);
- scene->_object3.animate(ANIM_MODE_5, this);
+ scene->_veeshkaRightArm.setFrame(1);
+ scene->_veeshkaRightArm.animate(ANIM_MODE_5, this);
_actionIndex = 0;
break;
}
@@ -145,43 +146,43 @@ void Scene10::postInit(SceneObjectList *OwnerList) {
_stripManager.setCallback(this);
- _object1.postInit();
- _object1.setVisage(10);
- _object1.setPosition(Common::Point(232, 90));
- _object1.fixPriority(1);
-
- _object2.postInit();
- _object2.setVisage(10);
- _object2.setStrip(4);
- _object2.setFrame(1);
- _object2.setPosition(Common::Point(204, 59));
- _object2.fixPriority(198);
-
- _object3.postInit();
- _object3.setVisage(10);
- _object3.setStrip2(5);
- _object3.setPosition(Common::Point(180, 87));
- _object3.fixPriority(196);
- _object3.setAction(&_action2);
-
- _object4.postInit();
- _object4.setVisage(10);
- _object4.setStrip(2);
- _object4.setPosition(Common::Point(0, 209));
- _object4.animate(ANIM_MODE_1, NULL);
-
- _object5.postInit();
- _object5.setVisage(11);
- _object5.setPosition(Common::Point(107, 146));
- _object5.animate(ANIM_MODE_2, NULL);
- _object5._numFrames = 5;
-
- _object6.postInit();
- _object6.setVisage(11);
- _object6.setStrip(2);
- _object6.setPosition(Common::Point(287, 149));
- _object6.animate(ANIM_MODE_2, NULL);
- _object6._numFrames = 5;
+ _veeshkaBody.postInit();
+ _veeshkaBody.setVisage(10);
+ _veeshkaBody.setPosition(Common::Point(232, 90));
+ _veeshkaBody.fixPriority(1);
+
+ _veeshkaHead.postInit();
+ _veeshkaHead.setVisage(10);
+ _veeshkaHead.setStrip(4);
+ _veeshkaHead.setFrame(1);
+ _veeshkaHead.setPosition(Common::Point(204, 59));
+ _veeshkaHead.fixPriority(198);
+
+ _veeshkaRightArm.postInit();
+ _veeshkaRightArm.setVisage(10);
+ _veeshkaRightArm.setStrip2(5);
+ _veeshkaRightArm.setPosition(Common::Point(180, 87));
+ _veeshkaRightArm.fixPriority(196);
+ _veeshkaRightArm.setAction(&_action2);
+
+ _centurion.postInit();
+ _centurion.setVisage(10);
+ _centurion.setStrip(2);
+ _centurion.setPosition(Common::Point(0, 209));
+ _centurion.animate(ANIM_MODE_1, NULL);
+
+ _leftSmoke.postInit();
+ _leftSmoke.setVisage(11);
+ _leftSmoke.setPosition(Common::Point(107, 146));
+ _leftSmoke.animate(ANIM_MODE_2, NULL);
+ _leftSmoke._numFrames = 5;
+
+ _rightSmoke.postInit();
+ _rightSmoke.setVisage(11);
+ _rightSmoke.setStrip(2);
+ _rightSmoke.setPosition(Common::Point(287, 149));
+ _rightSmoke.animate(ANIM_MODE_2, NULL);
+ _rightSmoke._numFrames = 5;
g_globals->_sceneManager._scene->_sceneBounds.contain(g_globals->_sceneManager._scene->_backgroundBounds);
g_globals->_sceneOffset.x = (g_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
@@ -193,14 +194,14 @@ void Scene10::postInit(SceneObjectList *OwnerList) {
void Scene10::stripCallback(int v) {
switch (v) {
case 1:
- _object2.animate(ANIM_MODE_7, -1, NULL);
+ _veeshkaHead.animate(ANIM_MODE_7, -1, NULL);
break;
case 2:
- _object2.animate(ANIM_MODE_NONE);
+ _veeshkaHead.animate(ANIM_MODE_NONE);
break;
case 3:
- _object2.animate(ANIM_MODE_7, -1, NULL);
- _object3.animate(ANIM_MODE_5, NULL);
+ _veeshkaHead.animate(ANIM_MODE_7, -1, NULL);
+ _veeshkaRightArm.animate(ANIM_MODE_5, NULL);
break;
default:
break;
@@ -227,13 +228,13 @@ void Scene15::Action1::signal() {
case 2: {
SceneItem::display(15, 1, SET_Y, 20, SET_FONT, 2, SET_BG_COLOR, -1, SET_EXT_BGCOLOR, 7,
SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END);
- scene->_object1.postInit();
- scene->_object1.setVisage(15);
- scene->_object1.setPosition(Common::Point(160, -10));
- scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_ship.postInit();
+ scene->_ship.setVisage(15);
+ scene->_ship.setPosition(Common::Point(160, -10));
+ scene->_ship.animate(ANIM_MODE_2, NULL);
Common::Point pt(160, 100);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_ship.addMover(mover, &pt, this);
scene->_soundHandler.play(7);
break;
}
@@ -247,8 +248,8 @@ void Scene15::Action1::signal() {
void Scene15::Action1::dispatch() {
Scene15 *scene = (Scene15 *)g_globals->_sceneManager._scene;
- if (scene->_object1._position.y < 100)
- scene->_object1.changeZoom(100 - scene->_object1._position.y);
+ if (scene->_ship._position.y < 100)
+ scene->_ship.changeZoom(100 - scene->_ship._position.y);
Action::dispatch();
}
@@ -307,9 +308,9 @@ void Scene20::Action2::signal() {
Common::Point pt(455, 77);
g_globals->_player.addMover(mover, &pt, this);
ObjectMover2 *mover2 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover2, 5, 10, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover2, 5, 10, &g_globals->_player);
ObjectMover2 *mover3 = new ObjectMover2();
- scene->_sceneObject3.addMover(mover3, 10, 15, &g_globals->_player);
+ scene->_assassinShip2.addMover(mover3, 10, 15, &g_globals->_player);
break;
}
case 3: {
@@ -369,9 +370,9 @@ void Scene20::Action3::signal() {
Common::Point pt(615, 81);
g_globals->_player.addMover(npcMover, &pt, this);
ObjectMover2 *mover1 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover1, 5, 10, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover1, 5, 10, &g_globals->_player);
ObjectMover2 *mover2 = new ObjectMover2();
- scene->_sceneObject3.addMover(mover2, 20, 25, &g_globals->_player);
+ scene->_assassinShip2.addMover(mover2, 20, 25, &g_globals->_player);
break;
}
case 2: {
@@ -382,8 +383,8 @@ void Scene20::Action3::signal() {
}
case 3: {
g_globals->_player._moveDiff = Common::Point(10, 10);
- scene->_SceneObjectExt._moveDiff = Common::Point(10, 10);
- scene->_sceneObject3._moveDiff = Common::Point(10, 10);
+ scene->_assassinShip1._moveDiff = Common::Point(10, 10);
+ scene->_assassinShip2._moveDiff = Common::Point(10, 10);
npcMover = new NpcMover();
Common::Point pt(445, 132);
g_globals->_player.addMover(npcMover, &pt, this);
@@ -427,73 +428,73 @@ void Scene20::Action4::signal() {
Common::Point pt(486, 134);
g_globals->_player.addMover(npcMover, &pt, this);
ObjectMover2 *mover1 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover1, 20, 35, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover1, 20, 35, &g_globals->_player);
break;
}
case 2: {
g_globals->_player._moveDiff = Common::Point(12, 12);
- scene->_SceneObjectExt._moveDiff = Common::Point(12, 12);
+ scene->_assassinShip1._moveDiff = Common::Point(12, 12);
NpcMover *mover1 = new NpcMover();
Common::Point pt(486, 134);
- scene->_sceneObject3.addMover(mover1, &pt, this);
+ scene->_assassinShip2.addMover(mover1, &pt, this);
NpcMover *mover2 = new NpcMover();
pt = Common::Point(-15, 134);
g_globals->_player.addMover(mover2, &pt, NULL);
NpcMover *mover3 = new NpcMover();
pt = Common::Point(-15, 134);
- scene->_SceneObjectExt.addMover(mover3, &pt, NULL);
+ scene->_assassinShip1.addMover(mover3, &pt, NULL);
break;
}
case 3: {
- scene->_sceneObject3._moveDiff = Common::Point(20, 20);
+ scene->_assassinShip2._moveDiff = Common::Point(20, 20);
npcMover = new NpcMover();
Common::Point pt(320, 134);
- scene->_sceneObject3.addMover(npcMover, &pt, this);
+ scene->_assassinShip2.addMover(npcMover, &pt, this);
break;
}
case 4: {
scene->_sound.play(28);
- scene->_sceneObject4.postInit();
- scene->_sceneObject4.setVisage(21);
- scene->_sceneObject4.setStrip(3);
- scene->_sceneObject4.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
- scene->_sceneObject3._position.y - 1));
- scene->_sceneObject4._moveDiff.x = 48;
+ scene->_laserShot1.postInit();
+ scene->_laserShot1.setVisage(21);
+ scene->_laserShot1.setStrip(3);
+ Common::Point pt = Common::Point(scene->_assassinShip2._position.x - 36, scene->_assassinShip2._position.y - 1);
+ scene->_laserShot1.setPosition(pt);
+ scene->_laserShot1._moveDiff.x = 48;
ObjectMover3 *mover = new ObjectMover3();
- scene->_sceneObject4.addMover(mover, &scene->_SceneObjectExt, 4, this);
+ scene->_laserShot1.addMover(mover, &scene->_assassinShip1, 4, this);
break;
}
case 5: {
scene->_sound.play(42);
- scene->_sceneObject4.remove();
- scene->_SceneObjectExt.setVisage(21);
- scene->_SceneObjectExt.setStrip(1);
- scene->_SceneObjectExt.setFrame(1);
- scene->_SceneObjectExt.animate(ANIM_MODE_5, NULL);
+ scene->_laserShot1.remove();
+ scene->_assassinShip1.setVisage(21);
+ scene->_assassinShip1.setStrip(1);
+ scene->_assassinShip1.setFrame(1);
+ scene->_assassinShip1.animate(ANIM_MODE_5, NULL);
- scene->_SceneObjectExt._moveDiff.x = 4;
+ scene->_assassinShip1._moveDiff.x = 4;
NpcMover *mover1 = new NpcMover();
- Common::Point pt(scene->_SceneObjectExt._position.x - 12, scene->_SceneObjectExt._position.y + 5);
- scene->_SceneObjectExt.addMover(mover1, &pt, NULL);
+ Common::Point pt(scene->_assassinShip1._position.x - 12, scene->_assassinShip1._position.y + 5);
+ scene->_assassinShip1.addMover(mover1, &pt, NULL);
- scene->_sceneObject5.postInit();
- scene->_sceneObject5.setVisage(21);
- scene->_sceneObject5.setStrip(3);
- scene->_sceneObject5.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
- scene->_sceneObject3._position.y - 1));
- scene->_sceneObject5._moveDiff.x = 48;
+ scene->_laserShot2.postInit();
+ scene->_laserShot2.setVisage(21);
+ scene->_laserShot2.setStrip(3);
+ pt = Common::Point(scene->_assassinShip2._position.x - 36, scene->_assassinShip2._position.y - 1);
+ scene->_laserShot2.setPosition(pt);
+ scene->_laserShot2._moveDiff.x = 48;
ObjectMover3 *mover = new ObjectMover3();
- scene->_sceneObject5.addMover(mover, &g_globals->_player, 4, this);
+ scene->_laserShot2.addMover(mover, &g_globals->_player, 4, this);
break;
}
case 6: {
scene->_sound.play(42);
- scene->_SceneObjectExt.setStrip(2);
- scene->_SceneObjectExt.animate(ANIM_MODE_2, NULL);
+ scene->_assassinShip1.setStrip(2);
+ scene->_assassinShip1.animate(ANIM_MODE_2, NULL);
- scene->_sceneObject5.remove();
+ scene->_laserShot2.remove();
g_globals->_player.setVisage(21);
g_globals->_player.setStrip(1);
g_globals->_player.setFrame(1);
@@ -539,18 +540,18 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
g_globals->_player._moveDiff = Common::Point(10, 10);
g_globals->_player.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt.postInit();
- _SceneObjectExt.setVisage(20);
- _SceneObjectExt.setPosition(Common::Point(400, 69));
- _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+ _assassinShip1.postInit();
+ _assassinShip1.setVisage(20);
+ _assassinShip1.setPosition(Common::Point(400, 69));
+ _assassinShip1.animate(ANIM_MODE_1, NULL);
- _sceneObject3.postInit();
- _sceneObject3.setVisage(20);
- _sceneObject3.setPosition(Common::Point(395, 69));
- _sceneObject3.animate(ANIM_MODE_1, NULL);
+ _assassinShip2.postInit();
+ _assassinShip2.setVisage(20);
+ _assassinShip2.setPosition(Common::Point(395, 69));
+ _assassinShip2.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt._moveDiff = Common::Point(10, 10);
- _sceneObject3._moveDiff = Common::Point(10, 10);
+ _assassinShip1._moveDiff = Common::Point(10, 10);
+ _assassinShip2._moveDiff = Common::Point(10, 10);
g_globals->_soundHandler.play(20);
_sound.play(21);
_sound.holdAt(true);
@@ -567,16 +568,16 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
g_globals->_player.fixPriority(50);
g_globals->_player.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt.postInit();
- _SceneObjectExt.setVisage(20);
- _SceneObjectExt.setPosition(Common::Point(583, 79));
- _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+ _assassinShip1.postInit();
+ _assassinShip1.setVisage(20);
+ _assassinShip1.setPosition(Common::Point(583, 79));
+ _assassinShip1.animate(ANIM_MODE_1, NULL);
- _sceneObject3.postInit();
- _sceneObject3.setVisage(20);
- _sceneObject3.setStrip2(2);
- _sceneObject3.setPosition(Common::Point(595, 79));
- _sceneObject3.animate(ANIM_MODE_1, NULL);
+ _assassinShip2.postInit();
+ _assassinShip2.setVisage(20);
+ _assassinShip2.setStrip2(2);
+ _assassinShip2.setPosition(Common::Point(595, 79));
+ _assassinShip2.animate(ANIM_MODE_1, NULL);
if ((g_globals->getFlag(120) && g_globals->getFlag(116)) ||
(g_globals->getFlag(117) && g_globals->getFlag(119))) {
@@ -584,10 +585,10 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
setAction(&_action3);
} else if (g_globals->getFlag(104)) {
_sceneMode = 21;
- setAction(&_sequenceManager, this, 21, &g_globals->_player, &_SceneObjectExt, NULL);
+ setAction(&_sequenceManager, this, 21, &g_globals->_player, &_assassinShip1, NULL);
} else {
// Failed evasion
- _sceneObject3._moveDiff = Common::Point(8, 8);
+ _assassinShip2._moveDiff = Common::Point(8, 8);
setAction(&_action4);
}
_sceneBounds.center(g_globals->_player._position.x, g_globals->_player._position.y);
@@ -626,26 +627,37 @@ void Scene20::signal() {
*--------------------------------------------------------------------------*/
void Scene30::BeamObject::doAction(int action) {
- if (action == OBJECT_SCANNER)
+ switch (action) {
+ case OBJECT_SCANNER:
display2(30, 14);
- else if (action == CURSOR_LOOK)
+ break;
+ case CURSOR_LOOK:
display2(30, 2);
- else if (action == CURSOR_USE) {
+ break;
+ case CURSOR_USE: {
Scene30 *parent = (Scene30 *)g_globals->_sceneManager._scene;
parent->setAction(&parent->_beamAction);
- } else
+ }
+ break;
+ default:
SceneObject::doAction(action);
+ }
}
void Scene30::DoorObject::doAction(int action) {
- if (action == OBJECT_SCANNER)
+ switch (action) {
+ case OBJECT_SCANNER:
display2(30, 13);
- else if (action == CURSOR_LOOK)
+ break;
+ case CURSOR_LOOK:
display2(30, 1);
- else if (action == CURSOR_USE)
+ break;
+ case CURSOR_USE:
display2(30, 7);
- else
+ break;
+ default:
SceneObject::doAction(action);
+ }
}
void Scene30::BeamAction::signal() {
@@ -963,16 +975,16 @@ void Scene40::Action1::signal() {
scene->_doorway.hide();
scene->_dyingKzin.setPosition(Common::Point(296, 62));
g_globals->_player.animate(ANIM_MODE_5, NULL);
- scene->_object1.setVisage(43);
- scene->_object1.setStrip(3);
- scene->_object1.animate(ANIM_MODE_5, NULL);
- scene->_object2.hide();
- scene->_object3.hide();
+ scene->_seeker.setVisage(43);
+ scene->_seeker.setStrip(3);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
+ scene->_seekerTail.hide();
+ scene->_seekerHand.hide();
scene->_stripManager.start(45, this);
break;
case 4:
- scene->_object2.remove();
- scene->_object3.remove();
+ scene->_seekerTail.remove();
+ scene->_seekerHand.remove();
scene->_assassin.setVisage(42);
scene->_assassin.setStrip(2);
scene->_assassin.setFrame(1);
@@ -1049,10 +1061,10 @@ void Scene40::Action1::signal() {
break;
case 15:
g_globals->_player.disableControl();
- scene->_object1.setVisage(40);
- scene->_object1.setStrip(4);
- scene->_object1.setFrame(1);
- scene->_object1.animate(ANIM_MODE_5, NULL);
+ scene->_seeker.setVisage(40);
+ scene->_seeker.setStrip(4);
+ scene->_seeker.setFrame(1);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
g_globals->_player.setVisage(40);
g_globals->_player.setStrip(2);
g_globals->_player.setFrame(1);
@@ -1122,13 +1134,13 @@ void Scene40::Action2::signal() {
}
case 6: {
g_globals->_player.setStrip(7);
- scene->_object1.setVisage(2806);
- scene->_object1.animate(ANIM_MODE_1, NULL);
+ scene->_seeker.setVisage(2806);
+ scene->_seeker.animate(ANIM_MODE_1, NULL);
SceneObjectWrapper *wrapper = new SceneObjectWrapper();
- scene->_object1.setObjectWrapper(wrapper);
+ scene->_seeker.setObjectWrapper(wrapper);
Common::Point pt(200, 190);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_seeker.addMover(mover, &pt, this);
break;
}
case 7:
@@ -1137,12 +1149,12 @@ void Scene40::Action2::signal() {
case 8: {
Common::Point pt(170, 260);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_seeker.addMover(mover, &pt, this);
break;
}
case 9:
scene->_dyingKzin.setAction(&scene->_action7);
- scene->_object1.remove();
+ scene->_seeker.remove();
g_globals->_stripNum = 88;
g_globals->_events.setCursor(CURSOR_WALK);
g_globals->_player.enableControl();
@@ -1202,6 +1214,7 @@ void Scene40::Action4::signal() {
}
}
+// Animate the tail of Seeker, with random pauses
void Scene40::Action5::signal() {
Scene40 *scene = (Scene40 *)g_globals->_sceneManager._scene;
@@ -1210,7 +1223,7 @@ void Scene40::Action5::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(119) + 120);
break;
case 1:
- scene->_object2.animate(ANIM_MODE_8, 1, this);
+ scene->_seekerTail.animate(ANIM_MODE_8, 1, this);
_actionIndex = 0;
}
}
@@ -1220,17 +1233,17 @@ void Scene40::Action6::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_object1.postInit();
- scene->_object1.setVisage(16);
- scene->_object1.setStrip2(6);
- scene->_object1._moveDiff = Common::Point(40, 40);
- scene->_object1.setPosition(Common::Point(313, 53));
- scene->_object1._moveRate = 60;
+ scene->_seeker.postInit();
+ scene->_seeker.setVisage(16);
+ scene->_seeker.setStrip2(6);
+ scene->_seeker._moveDiff = Common::Point(40, 40);
+ scene->_seeker.setPosition(Common::Point(313, 53));
+ scene->_seeker._moveRate = 60;
Common::Point pt(141, 194);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, NULL);
- scene->_object1.animate(ANIM_MODE_5, NULL);
+ scene->_seeker.addMover(mover, &pt, NULL);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
scene->_doorway.postInit();
scene->_doorway.setVisage(46);
@@ -1260,21 +1273,21 @@ void Scene40::Action7::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(499) + 500);
break;
case 1:
- scene->_object7.postInit();
- scene->_object7.setVisage(46);
+ scene->_leftEntrance.postInit();
+ scene->_leftEntrance.setVisage(46);
if (g_globals->_randomSource.getRandomNumber(32767) >= 16384) {
- scene->_object7.setStrip(3);
- scene->_object7.setPosition(Common::Point(15, 185));
+ scene->_leftEntrance.setStrip(3);
+ scene->_leftEntrance.setPosition(Common::Point(15, 185));
} else {
- scene->_object7.setPosition(Common::Point(305, 61));
- scene->_object7.setFrame(15);
+ scene->_leftEntrance.setPosition(Common::Point(305, 61));
+ scene->_leftEntrance.setFrame(15);
}
- scene->_object7.animate(ANIM_MODE_5, this);
+ scene->_leftEntrance.animate(ANIM_MODE_5, this);
scene->_soundHandler.play(25);
break;
case 2:
- scene->_object7.remove();
+ scene->_leftEntrance.remove();
_actionIndex = 0;
setDelay(60);
break;
@@ -1465,12 +1478,12 @@ void Scene40::Item6::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene40::Scene40() :
- _item1(2, OBJECT_SCANNER, 40, 24, OBJECT_STUNNER, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END),
- _item3(5, OBJECT_SCANNER, 40, 28, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 2, CURSOR_USE, 40, 30, LIST_END),
- _item4(6, OBJECT_SCANNER, 40, 31, OBJECT_STUNNER, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END),
- _item5(0, CURSOR_LOOK, 40, 11, LIST_END),
- _item7(4, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
- _item8(8, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) {
+ _ball(2, OBJECT_SCANNER, 40, 24, OBJECT_STUNNER, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END),
+ _window(5, OBJECT_SCANNER, 40, 28, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 2, CURSOR_USE, 40, 30, LIST_END),
+ _entrance(6, OBJECT_SCANNER, 40, 31, OBJECT_STUNNER, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END),
+ _background(0, CURSOR_LOOK, 40, 11, LIST_END),
+ _emerald(4, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
+ _tree(8, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) {
}
void Scene40::postInit(SceneObjectList *OwnerList) {
@@ -1489,7 +1502,7 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
_speakerGameText._color1 = 9;
_speakerGameText.setTextPos(Common::Point(160, 30));
_speakerQText._npc = &g_globals->_player;
- _speakerSText._npc = &_object1;
+ _speakerSText._npc = &_seeker;
g_globals->_player.postInit();
g_globals->_player.setVisage(0);
@@ -1502,23 +1515,24 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
g_globals->_soundHandler.play(24);
g_globals->_player.setVisage(43);
- _object1.postInit();
- _object1.setVisage(41);
- _object1.setPosition(Common::Point(105, 220));
- _object2.postInit();
- _object2.setVisage(41);
- _object2.setStrip(6);
- _object2.fixPriority(200);
- _object2.setPosition(Common::Point(94, 189));
- _object2.setAction(&_action5);
-
- _object3.postInit();
- _object3.setVisage(41);
- _object3.setStrip(5);
- _object3.fixPriority(205);
- _object3.setPosition(Common::Point(110, 186));
- _object3._numFrames = 2;
- _object3.animate(ANIM_MODE_8, NULL, NULL);
+ _seeker.postInit();
+ _seeker.setVisage(41);
+ _seeker.setPosition(Common::Point(105, 220));
+
+ _seekerTail.postInit();
+ _seekerTail.setVisage(41);
+ _seekerTail.setStrip(6);
+ _seekerTail.fixPriority(200);
+ _seekerTail.setPosition(Common::Point(94, 189));
+ _seekerTail.setAction(&_action5);
+
+ _seekerHand.postInit();
+ _seekerHand.setVisage(41);
+ _seekerHand.setStrip(5);
+ _seekerHand.fixPriority(205);
+ _seekerHand.setPosition(Common::Point(110, 186));
+ _seekerHand._numFrames = 2;
+ _seekerHand.animate(ANIM_MODE_8, NULL, NULL);
_assassin.postInit();
_assassin.setPosition(Common::Point(-40, 191));
@@ -1563,12 +1577,12 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
setAction(&_action4);
}
- _item5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- _item6._sceneRegionId = 3;
- _item2._sceneRegionId = 7;
+ _background.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _pedestal._sceneRegionId = 3;
+ _statue._sceneRegionId = 7;
- g_globals->_sceneItems.addItems(&_dyingKzin, &_item8, &_item1, &_item2, &_item3, &_item4,
- &_item6, &_item7, &_item5, NULL);
+ g_globals->_sceneItems.addItems(&_dyingKzin, &_tree, &_ball, &_statue, &_window, &_entrance,
+ &_pedestal, &_emerald, &_background, NULL);
}
void Scene40::signal() {
@@ -1691,7 +1705,7 @@ void Scene50::Object1::doAction(int action) {
}
}
-void Scene50::Object2::doAction(int action) {
+void Scene50::LeftFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1715,7 +1729,7 @@ void Scene50::Object2::doAction(int action) {
}
}
-void Scene50::Object3::doAction(int action) {
+void Scene50::CenterFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1743,7 +1757,7 @@ void Scene50::Object3::doAction(int action) {
}
}
-void Scene50::Object4::doAction(int action) {
+void Scene50::RightFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1772,12 +1786,13 @@ void Scene50::Object4::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene50::Scene50() :
- _item0(0, CURSOR_LOOK, 50, 3, LIST_END),
+ _background(0, CURSOR_LOOK, 50, 3, LIST_END),
_item1(0, OBJECT_SCANNER, 50, 15, CURSOR_USE, 50, 16, CURSOR_LOOK, 50, 3, LIST_END),
- _item2(0, CURSOR_LOOK, 50, 7, LIST_END),
- _item3(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 50, 3, LIST_END),
- _item4(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END),
- _item5(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) {
+ _entrance(0, CURSOR_LOOK, 50, 7, LIST_END),
+ // The original was using dialog 50/3 for CURSOR_LOOK, which is too generic.
+ _bulwark(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 30, 0, LIST_END),
+ _tree(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END),
+ _flagstones(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) {
_doorwayRect = Rect(80, 108, 160, 112);
}
@@ -1806,25 +1821,25 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
g_globals->_player.setPosition(Common::Point(270, 143));
}
- _object2.postInit();
- _object2.setVisage(2331);
- _object2.setStrip(6);
- _object2.setPosition(Common::Point(136, 192));
- _object2.fixPriority(200);
+ _leftFlyCycle.postInit();
+ _leftFlyCycle.setVisage(2331);
+ _leftFlyCycle.setStrip(6);
+ _leftFlyCycle.setPosition(Common::Point(136, 192));
+ _leftFlyCycle.fixPriority(200);
- _object3.postInit();
- _object3.setVisage(2337);
- _object3.setStrip(6);
- _object3.setPosition(Common::Point(260, 180));
- _object3.fixPriority(200);
+ _centerFlyCycle.postInit();
+ _centerFlyCycle.setVisage(2337);
+ _centerFlyCycle.setStrip(6);
+ _centerFlyCycle.setPosition(Common::Point(260, 180));
+ _centerFlyCycle.fixPriority(200);
- _object4.postInit();
- _object4.setVisage(2331);
- _object4.setStrip(6);
- _object4.setPosition(Common::Point(295, 144));
- _object4.fixPriority(178);
+ _rightFlyCycle.postInit();
+ _rightFlyCycle.setVisage(2331);
+ _rightFlyCycle.setStrip(6);
+ _rightFlyCycle.setPosition(Common::Point(295, 144));
+ _rightFlyCycle.fixPriority(178);
- g_globals->_sceneItems.addItems(&_object2, &_object3, &_object4, NULL);
+ g_globals->_sceneItems.addItems(&_leftFlyCycle, &_centerFlyCycle, &_rightFlyCycle, NULL);
if (!g_globals->getFlag(101)) {
g_globals->_player.disableControl();
@@ -1840,8 +1855,8 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
}
}
- _item0.setBounds(Rect(200, 0, 320, 200));
- g_globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item0, NULL);
+ _background.setBounds(Rect(0, 0, 320, 200));
+ g_globals->_sceneItems.addItems(&_bulwark, &_tree, &_flagstones, &_background, NULL);
}
void Scene50::signal() {
@@ -1928,8 +1943,8 @@ void Scene60::Action1::signal() {
scene->_controlButton.remove();
scene->_slaveButton.remove();
scene->_masterButton.remove();
- scene->_item1.remove();
- scene->_item2.remove();
+ scene->_diskDrive.remove();
+ scene->_dashboard.remove();
scene->_nextButton.postInit();
scene->_nextButton.setVisage(65);
@@ -2030,11 +2045,11 @@ void Scene60::Action2::signal() {
/*--------------------------------------------------------------------------*/
void Scene60::PrevObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 16);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() > 5) {
@@ -2048,11 +2063,11 @@ void Scene60::PrevObject::doAction(int action) {
}
void Scene60::NextObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 17);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() < 8) {
@@ -2065,11 +2080,11 @@ void Scene60::NextObject::doAction(int action) {
}
void Scene60::ExitObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 18);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
scene->_soundHandler3.play(36);
animate(ANIM_MODE_8, 1, NULL);
scene->_nextButton.remove();
@@ -2111,11 +2126,11 @@ void Scene60::ExitObject::doAction(int action) {
if (scene->_masterButton._state)
scene->_masterButton.setFrame(2);
- g_globals->_sceneItems.push_front(&scene->_item1);
+ g_globals->_sceneItems.push_front(&scene->_diskDrive);
g_globals->_sceneItems.push_front(&scene->_controlButton);
g_globals->_sceneItems.push_front(&scene->_slaveButton);
g_globals->_sceneItems.push_front(&scene->_masterButton);
- g_globals->_sceneItems.push_back(&scene->_item2);
+ g_globals->_sceneItems.push_back(&scene->_dashboard);
g_globals->gfxManager()._font.setFontNumber(2);
g_globals->_sceneText._fontNumber = 2;
@@ -2130,11 +2145,11 @@ void Scene60::ExitObject::doAction(int action) {
}
void Scene60::MessageObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 9);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
scene->_action1.setDelay(1);
g_globals->setFlag(83);
} else {
@@ -2143,11 +2158,11 @@ void Scene60::MessageObject::doAction(int action) {
}
void Scene60::ControlObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 11);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (_animateMode == ANIM_MODE_NONE)
SceneItem::display2(60, 14);
else if (!scene->_slaveButton._state) {
@@ -2164,11 +2179,11 @@ void Scene60::ControlObject::doAction(int action) {
}
void Scene60::SlaveObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 8);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (scene->_masterButton._state)
scene->_sceneMode = 19;
else if (_state) {
@@ -2194,11 +2209,11 @@ void Scene60::SlaveObject::doAction(int action) {
}
void Scene60::MasterObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 7);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (!scene->_controlButton._animateMode)
scene->_sceneMode = 14;
else if (scene->_slaveButton._state)
@@ -2226,11 +2241,11 @@ void Scene60::MasterObject::doAction(int action) {
}
void Scene60::FloppyDrive::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 13);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
g_globals->setFlag(!g_globals->_stripNum ? 118 : 121);
scene->setAction(&scene->_action1);
} else {
@@ -2273,6 +2288,7 @@ void Scene60::Item1::doAction(int action) {
} else {
scene->setAction(&scene->_action2);
}
+ break;
default:
SceneHotspot::doAction(action);
break;
@@ -2299,11 +2315,11 @@ void Scene60::Item::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene60::Scene60() :
- _item2(0, 12, 12),
- _item3(8, 22, 23),
- _item4(9, 24, 25),
- _item5(10, 26, 27),
- _item6(11, 28, 29) {
+ _dashboard(0, 12, 12),
+ _intercomm(8, 22, 23),
+ _viewScreen(9, 24, 25),
+ _speedControl(10, 26, 27),
+ _speaker(11, 28, 29) {
}
void Scene60::postInit(SceneObjectList *OwnerList) {
@@ -2344,8 +2360,8 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 61, NULL);
}
- _item1.setBounds(Rect(130, 55, 174, 70));
- _item2.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _diskDrive.setBounds(Rect(130, 55, 174, 70));
+ _dashboard.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
if (g_globals->_stripNum == 0) {
if (g_globals->getFlag(117)) {
@@ -2418,8 +2434,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
}
}
- g_globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item6,
- &_item1, &_item2, NULL);
+ g_globals->_sceneItems.addItems(&_intercomm, &_viewScreen, &_speedControl, &_speaker, &_diskDrive, &_dashboard, NULL);
}
void Scene60::signal() {
@@ -2473,11 +2488,11 @@ void Scene90::Action1::signal() {
case 3: {
Common::Point pt(278, 191);
NpcMover *mover = new NpcMover();
- scene->_object2.addMover(mover, &pt, this);
+ scene->_guard.addMover(mover, &pt, this);
break;
}
case 4:
- scene->_object2.setStrip(3);
+ scene->_guard.setStrip(3);
setDelay(2);
break;
case 5:
@@ -2491,36 +2506,36 @@ void Scene90::Action1::signal() {
}
break;
case 6:
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
g_globals->_player._uiEnabled = true;
break;
case 7:
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
g_globals->_soundHandler.play(56);
- scene->_object3.animate(ANIM_MODE_5, this);
+ scene->_headGate.animate(ANIM_MODE_5, this);
break;
case 8: {
Common::Point pt(215, 127);
PlayerMover *mover = new PlayerMover();
- scene->_object5.addMover(mover, &pt, this);
+ scene->_quinnShip.addMover(mover, &pt, this);
break;
}
case 9: {
Common::Point pt1(215, 127);
PlayerMover *mover1 = new PlayerMover();
- scene->_object1.addMover(mover1, &pt1, this);
+ scene->_seekerShip.addMover(mover1, &pt1, this);
Common::Point pt2(86, 62);
PlayerMover *mover2 = new PlayerMover();
- scene->_object5.addMover(mover2, &pt2, this);
+ scene->_quinnShip.addMover(mover2, &pt2, this);
break;
}
case 10: {
PlayerMover2 *mover = new PlayerMover2();
- scene->_object1.addMover(mover, 10, 15, &scene->_object5);
+ scene->_seekerShip.addMover(mover, 10, 15, &scene->_quinnShip);
if (!g_globals->getFlag(104)) {
mover = new PlayerMover2();
- scene->_object4.addMover(mover, 10, 15, &scene->_object1);
+ scene->_emptyShip.addMover(mover, 10, 15, &scene->_seekerShip);
}
setDelay(60);
break;
@@ -2528,7 +2543,7 @@ void Scene90::Action1::signal() {
case 11:
g_globals->_soundHandler.play(57);
g_globals->_soundHandler.play(68);
- scene->_object3.animate(ANIM_MODE_6, NULL);
+ scene->_headGate.animate(ANIM_MODE_6, NULL);
SceneItem::display(90, g_globals->getFlag(104) ? 15 : 14,
SET_EXT_BGCOLOR, 13, SET_KEEP_ONSCREEN, -1, SET_X, 120, SET_Y, 20, LIST_END);
@@ -2543,7 +2558,7 @@ void Scene90::Action1::signal() {
/*--------------------------------------------------------------------------*/
-void Scene90::Object1::doAction(int action) {
+void Scene90::SeekerShip::doAction(int action) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -2561,23 +2576,23 @@ void Scene90::Object1::doAction(int action) {
}
}
-void Scene90::Object2::doAction(int action) {
+void Scene90::Guard::doAction(int action) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
switch (action) {
case OBJECT_STUNNER:
case CURSOR_USE:
g_globals->_player.disableControl();
- scene->_object6.postInit();
- scene->_object6.setVisage(90);
- scene->_object6.setStrip(6);
- scene->_object6.setPosition(Common::Point(184, 210));
- scene->_object6.hide();
+ scene->_bubble.postInit();
+ scene->_bubble.setVisage(90);
+ scene->_bubble.setStrip(6);
+ scene->_bubble.setPosition(Common::Point(184, 210));
+ scene->_bubble.hide();
scene->_sceneMode = 91;
scene->_soundHandler1.play(59);
scene->_soundHandler1.holdAt(true);
- scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_object6, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_bubble, NULL);
break;
case CURSOR_LOOK:
SceneItem::display2(90, 8);
@@ -2595,21 +2610,21 @@ void Scene90::Object2::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene90::Scene90() :
- _item1(0, CURSOR_LOOK, 90, 9, LIST_END),
- _item2(0, CURSOR_LOOK, 90, 10, LIST_END),
- _item3(0, CURSOR_LOOK, 90, 11, LIST_END),
- _object3(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END),
- _object4(CURSOR_LOOK, 90, 17, LIST_END),
- _object5(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) {
+ _guardShack(0, CURSOR_LOOK, 90, 9, LIST_END),
+ _shed(0, CURSOR_LOOK, 90, 10, LIST_END),
+ _background(0, CURSOR_LOOK, 90, 11, LIST_END),
+ _headGate(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END),
+ _emptyShip(CURSOR_LOOK, 90, 17, LIST_END),
+ _quinnShip(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) {
}
void Scene90::stripCallback(int v) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
if (v == 1)
- scene->_object2.animate(ANIM_MODE_7, 0, NULL);
+ scene->_guard.animate(ANIM_MODE_7, 0, NULL);
else if (v == 2)
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
}
void Scene90::postInit(SceneObjectList *OwnerList) {
@@ -2623,53 +2638,53 @@ void Scene90::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_speakerQL);
_stripManager.addSpeaker(&_speakerSR);
- _speakerMText._npc = &_object2;
+ _speakerMText._npc = &_guard;
_speakerQText._textWidth = 160;
- _speakerQText._npc = &_object5;
- _speakerSText._npc = &_object1;
-
- _object5.postInit();
- _object5.setVisage(2333);
- _object5.setObjectWrapper(new SceneObjectWrapper());
- _object5._strip = 7;
- _object5._moveDiff = Common::Point(22, 22);
- _object5.setPosition(Common::Point(151, 177));
- _object5.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object5);
-
- _object1.postInit();
- _object1.setVisage(2337);
- _object1.setObjectWrapper(new SceneObjectWrapper());
- _object1._strip = 4;
- _object1._moveDiff = Common::Point(20, 20);
- _object1.setPosition(Common::Point(212, 183));
- _object1.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object1);
+ _speakerQText._npc = &_quinnShip;
+ _speakerSText._npc = &_seekerShip;
+
+ _quinnShip.postInit();
+ _quinnShip.setVisage(2333);
+ _quinnShip.setObjectWrapper(new SceneObjectWrapper());
+ _quinnShip._strip = 7;
+ _quinnShip._moveDiff = Common::Point(22, 22);
+ _quinnShip.setPosition(Common::Point(151, 177));
+ _quinnShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_quinnShip);
+
+ _seekerShip.postInit();
+ _seekerShip.setVisage(2337);
+ _seekerShip.setObjectWrapper(new SceneObjectWrapper());
+ _seekerShip._strip = 4;
+ _seekerShip._moveDiff = Common::Point(20, 20);
+ _seekerShip.setPosition(Common::Point(212, 183));
+ _seekerShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_seekerShip);
if (!g_globals->getFlag(104)) {
- _object4.postInit();
- _object4.setVisage(2331);
- _object4.setObjectWrapper(new SceneObjectWrapper());
- _object4._strip = 4;
- _object4._moveDiff = Common::Point(20, 20);
- _object4.setPosition(Common::Point(251, 207));
- _object4.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object4);
- }
-
- _object2.postInit();
- _object2.setVisage(90);
- _object2.animate(ANIM_MODE_1, NULL);
- _object2.setPosition(Common::Point(315, 185));
- _object2._strip = 2;
- g_globals->_sceneItems.push_back(&_object2);
-
- _object3.postInit();
- _object3.setVisage(90);
- _object3.animate(ANIM_MODE_1, NULL);
- _object3.setPosition(Common::Point(196, 181));
- _object3.fixPriority(175);
- g_globals->_sceneItems.push_back(&_object3);
+ _emptyShip.postInit();
+ _emptyShip.setVisage(2331);
+ _emptyShip.setObjectWrapper(new SceneObjectWrapper());
+ _emptyShip._strip = 4;
+ _emptyShip._moveDiff = Common::Point(20, 20);
+ _emptyShip.setPosition(Common::Point(251, 207));
+ _emptyShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_emptyShip);
+ }
+
+ _guard.postInit();
+ _guard.setVisage(90);
+ _guard.animate(ANIM_MODE_1, NULL);
+ _guard.setPosition(Common::Point(315, 185));
+ _guard._strip = 2;
+ g_globals->_sceneItems.push_back(&_guard);
+
+ _headGate.postInit();
+ _headGate.setVisage(90);
+ _headGate.animate(ANIM_MODE_1, NULL);
+ _headGate.setPosition(Common::Point(196, 181));
+ _headGate.fixPriority(175);
+ g_globals->_sceneItems.push_back(&_headGate);
g_globals->_player.disableControl();
g_globals->_soundHandler.play(55);
@@ -2678,11 +2693,11 @@ void Scene90::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
- _item3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- _item1.setBounds(Rect(271, 65, 271, 186));
- _item2.setBounds(Rect(0, 17, 124, 77));
+ _background.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _guardShack.setBounds(Rect(271, 65, 271, 186));
+ _shed.setBounds(Rect(0, 17, 124, 77));
- g_globals->_sceneItems.addItems(&_item1, &_item2, &_item3, NULL);
+ g_globals->_sceneItems.addItems(&_guardShack, &_shed, &_background, NULL);
}
void Scene90::signal() {
diff --git a/engines/tsage/ringworld/ringworld_scenes1.h b/engines/tsage/ringworld/ringworld_scenes1.h
index bb98c89a8c..d52d4fb6ec 100644
--- a/engines/tsage/ringworld/ringworld_scenes1.h
+++ b/engines/tsage/ringworld/ringworld_scenes1.h
@@ -54,8 +54,12 @@ public:
Speaker _speakerQText;
Action1 _action1;
Action2 _action2;
- SceneObject _object1, _object2, _object3;
- SceneObject _object4, _object5, _object6;
+ SceneObject _veeshkaBody;
+ SceneObject _veeshkaHead;
+ SceneObject _veeshkaRightArm;
+ SceneObject _centurion;
+ SceneObject _leftSmoke;
+ SceneObject _rightSmoke;
virtual void stripCallback(int v);
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -70,7 +74,7 @@ class Scene15 : public Scene {
};
public:
Action1 _action1;
- SceneObject _object1;
+ SceneObject _ship;
ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -102,7 +106,10 @@ public:
Action2 _action2;
Action3 _action3;
Action4 _action4;
- SceneObject _sceneObject1, _SceneObjectExt, _sceneObject3, _sceneObject4, _sceneObject5;
+ SceneObject _assassinShip1;
+ SceneObject _assassinShip2;
+ SceneObject _laserShot1;
+ SceneObject _laserShot2;
ASound _sound;
public:
Scene20();
@@ -248,15 +255,21 @@ public:
Action6 _action6;
Action7 _action7;
Action8 _action8;
- SceneObject _object1, _object2, _object3;
+ SceneObject _seeker;
+ SceneObject _seekerTail;
+ SceneObject _seekerHand;
DyingKzin _dyingKzin;
Assassin _assassin;
- SceneObject _doorway, _object7, _object8;
- DisplayHotspot _item1;
- Item2 _item2;
- DisplayHotspot _item3, _item4, _item5;
- Item6 _item6;
- DisplayHotspot _item7, _item8;
+ SceneObject _doorway;
+ SceneObject _leftEntrance;
+ DisplayHotspot _ball;
+ Item2 _statue;
+ DisplayHotspot _window;
+ DisplayHotspot _entrance;
+ DisplayHotspot _background;
+ Item6 _pedestal;
+ DisplayHotspot _emerald;
+ DisplayHotspot _tree;
Scene40();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -284,15 +297,15 @@ class Scene50 : public Scene {
public:
virtual void doAction(int action);
};
- class Object2 : public SceneObject {
+ class LeftFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object3 : public SceneObject {
+ class CenterFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object4 : public SceneObject {
+ class RightFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
@@ -302,15 +315,18 @@ public:
Action1 _action1;
Action2 _action2;
Action3 _action3;
- Object1 _object1;
- Object2 _object2;
- Object3 _object3;
- Object4 _object4;
+ LeftFlyCycle _leftFlyCycle;
+ CenterFlyCycle _centerFlyCycle;
+ RightFlyCycle _rightFlyCycle;
Rect _doorwayRect;
SpeakerSText _speakerSText;
SpeakerQText _speakerQText;
- DisplayHotspot _item0, _item1, _item2;
- DisplayHotspot _item3, _item4, _item5;
+ DisplayHotspot _background;
+ DisplayHotspot _item1;
+ DisplayHotspot _entrance;
+ DisplayHotspot _bulwark;
+ DisplayHotspot _tree;
+ DisplayHotspot _flagstones;
Scene50();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -392,8 +408,12 @@ public:
MasterObject _masterButton;
FloppyDrive _floppyDrive;
SceneObject _redLights;
- Item1 _item1;
- Item _item2, _item3, _item4, _item5, _item6;
+ Item1 _diskDrive;
+ Item _dashboard;
+ Item _intercomm;
+ Item _viewScreen;
+ Item _speedControl;
+ Item _speaker;
ASound _soundHandler1;
ASound _soundHandler2;
ASound _soundHandler3;
@@ -409,11 +429,11 @@ class Scene90 : public Scene {
public:
virtual void signal();
};
- class Object1 : public SceneObject {
+ class SeekerShip : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object2 : public SceneObject {
+ class Guard : public SceneObject {
public:
virtual void doAction(int action);
};
@@ -425,11 +445,15 @@ public:
SpeakerSR _speakerSR;
SpeakerMText _speakerMText;
Action1 _action1;
- Object1 _object1;
- Object2 _object2;
- DisplayObject _object3, _object4, _object5;
- SceneObject _object6;
- DisplayHotspot _item1, _item2, _item3;
+ SeekerShip _seekerShip;
+ Guard _guard;
+ DisplayObject _headGate;
+ DisplayObject _emptyShip;
+ DisplayObject _quinnShip;
+ SceneObject _bubble;
+ DisplayHotspot _guardShack;
+ DisplayHotspot _shed;
+ DisplayHotspot _background;
ASound _soundHandler1, _soundHandler2;
Scene90();
diff --git a/engines/tsage/ringworld/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp
index f9a8e7996a..eac181e350 100644
--- a/engines/tsage/ringworld/ringworld_scenes10.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes10.cpp
@@ -1870,7 +1870,7 @@ void Scene9900::signal() {
setAction(&_sequenceManager, this, 9908, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
break;
case 162:
- warning("TBC: shutdown();");
+ // shutdown();
g_globals->_game->quitGame();
break;
case 9901:
diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp
index 004ccbbb6d..1b6cd78223 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes5.cpp
@@ -34,6 +34,9 @@ namespace Ringworld {
* Scene 4000 - Village
*
*--------------------------------------------------------------------------*/
+Scene4000::Hotspot8::Hotspot8() : SceneObject() {
+ _ctr = 0;
+}
void Scene4000::Action1::signal() {
// Quinn has the peg. Everybody enter the screen.
diff --git a/engines/tsage/ringworld/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h
index c93df2a1d8..2fe26d9712 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.h
+++ b/engines/tsage/ringworld/ringworld_scenes5.h
@@ -99,6 +99,7 @@ class Scene4000 : public Scene {
private:
int _ctr;
public:
+ Hotspot8();
virtual void synchronize(Serializer &s) {
SceneObject::synchronize(s);
s.syncAsUint16LE(_ctr);
diff --git a/engines/tsage/ringworld/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp
index 30a91b57aa..65c1ed39c6 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes6.cpp
@@ -2032,7 +2032,15 @@ void Scene5300::Hotspot8::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene5300::Scene5300() :
- _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) {
+ _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) {
+}
+
+void Scene5300::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene5300::postInit(SceneObjectList *OwnerList) {
@@ -2119,7 +2127,6 @@ void Scene5300::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 5306, &g_globals->_player, &_hotspot3, NULL);
}
- _field1B0A = 1;
if (RING_INVENTORY._bone._sceneNumber == 5300) {
_hotspot5.postInit();
_hotspot5.setVisage(5301);
diff --git a/engines/tsage/ringworld/ringworld_scenes6.h b/engines/tsage/ringworld/ringworld_scenes6.h
index bf353de415..4c10e4a711 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.h
+++ b/engines/tsage/ringworld/ringworld_scenes6.h
@@ -318,15 +318,11 @@ public:
Hotspot6 _hotspot6;
Hotspot7 _hotspot7;
Hotspot8 _hotspot8;
- int _field1B0A;
Scene5300();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
- virtual void synchronize(Serializer &s) {
- Scene::synchronize(s);
- s.syncAsSint16LE(_field1B0A);
- }
+ virtual void synchronize(Serializer &s);
};
} // End of namespace Ringworld
diff --git a/engines/tsage/ringworld/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp
index 9cb85a6930..f9156479e5 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes8.cpp
@@ -30,6 +30,10 @@ namespace TsAGE {
namespace Ringworld {
+NamedHotspotMult::NamedHotspotMult() : SceneHotspot() {
+ _useLineNum = _lookLineNum = 0;
+}
+
void NamedHotspotMult::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
s.syncAsSint16LE(_useLineNum);
@@ -2533,6 +2537,10 @@ Scene7700::Scene7700() {
_object5._state = 0;
_object6._state = 0;
_prof._state = 0;
+
+ _seatCountLeft1 = 0;
+ _seatCountLeft2 = 0;
+ _seatCountRight = 0;
}
void Scene7700::synchronize(Serializer &s) {
diff --git a/engines/tsage/ringworld/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h
index b24f220f8c..fa441f87da 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.h
+++ b/engines/tsage/ringworld/ringworld_scenes8.h
@@ -40,7 +40,7 @@ using namespace TsAGE;
class NamedHotspotMult : public SceneHotspot {
public:
int _useLineNum, _lookLineNum;
- NamedHotspotMult() : SceneHotspot() {}
+ NamedHotspotMult();
virtual Common::String getClassName() { return "NamedHotspotMult"; }
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 478fdcf5a5..a0675bc292 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -50,6 +50,7 @@ RightClickDialog::RightClickDialog() : GfxDialog() {
_btnList[5] = Common::Point(83, 47);
// Set the palette and change the cursor
+ _previousCursor = R2_GLOBALS._events.getCursor();
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
setPalette();
@@ -136,7 +137,7 @@ bool RightClickDialog::process(Event &event) {
return false;
}
-void RightClickDialog::execute() {
+int RightClickDialog::execute() {
// Draw the dialog
draw();
@@ -157,7 +158,8 @@ void RightClickDialog::execute() {
}
// Execute the specified action
- CursorType cursorNum = CURSOR_NONE;
+ CursorType cursorNum = _previousCursor;
+ int result = -1;
switch (_selectedAction) {
case 0:
// Look action
@@ -165,7 +167,7 @@ void RightClickDialog::execute() {
break;
case 1:
// Walk action
- cursorNum = CURSOR_WALK;
+ cursorNum = R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE;
break;
case 2:
// Use action
@@ -177,17 +179,18 @@ void RightClickDialog::execute() {
break;
case 4:
// Change player
- CharacterDialog::show();
+ result = 0;
break;
case 5:
// Options dialog
+ result = 1;
break;
}
- if (cursorNum != CURSOR_NONE)
- R2_GLOBALS._events.setCursor(cursorNum);
-
+ R2_GLOBALS._events.setCursor(cursorNum);
_gfxManager.deactivate();
+
+ return result;
}
/*--------------------------------------------------------------------------*/
@@ -234,9 +237,9 @@ void CharacterDialog::show() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
scene->saveCharacter(oldCharacter);
- // Play a transition sound as the character is changed
- if (R2_GLOBALS._player._characterScene[0] != 300) {
- switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) {
+ // Play the correctfrequency, if any, of the character being switched to's scanner device
+ if (R2_GLOBALS._player._characterScene[R2_NONE] != 300) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
R2_GLOBALS._sound4.stop();
break;
@@ -255,8 +258,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 +275,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[R2_QUINN] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -289,12 +292,12 @@ void CharacterDialog::show() {
default:
break;
}
- } else if (R2_GLOBALS._player._characterScene[2] != 300) {
+ } else if (R2_GLOBALS._player._characterScene[R2_SEEKER] != 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;
@@ -344,7 +347,7 @@ CharacterDialog::CharacterDialog() {
/*--------------------------------------------------------------------------*/
void HelpDialog::show() {
- // Set the palette and change the cursor
+ // change the cursor
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
// Create the dialog and draw it
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.h b/engines/tsage/ringworld2/ringworld2_dialogs.h
index 02a1aed81c..0c19ae4371 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.h
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.h
@@ -50,13 +50,14 @@ private:
int _highlightedAction;
int _selectedAction;
+ CursorType _previousCursor;
public:
RightClickDialog();
~RightClickDialog();
virtual void draw();
virtual bool process(Event &event);
- void execute();
+ int execute();
};
class CharacterDialog: public GfxDialog {
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index 97042cb621..e1d6e79423 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -21,6 +21,8 @@
*/
#include "common/config-manager.h"
+#include "common/rect.h"
+#include "tsage/graphics.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
@@ -36,8 +38,6 @@ namespace TsAGE {
namespace Ringworld2 {
Scene *Ringworld2Game::createScene(int sceneNumber) {
- warning("Switching to scene %d", sceneNumber);
-
switch (sceneNumber) {
/* Scene group #0 */
case 50:
@@ -86,8 +86,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
@@ -99,19 +101,24 @@ 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();
case 1020:
+ // Cutscene - trip in space 2
return new Scene1020();
case 1100:
+ // Canyon
return new Scene1100();
case 1200:
+ // ARM Base - Air Ducts Maze
return new Scene1200();
case 1337:
case 1330:
@@ -124,11 +131,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Ship
return new Scene1525();
case 1530:
- // Cutscene - Elevator
+ // Cutscene - Crashing on Rimwall
return new Scene1530();
case 1550:
+ // Spaceport
return new Scene1550();
case 1575:
+ // Spaceport - unused ship scene
return new Scene1575();
case 1580:
// Inside wreck
@@ -137,83 +146,93 @@ 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:
+ // Rim Lift Interior
return new Scene1850();
case 1875:
+ // Rim Lift Computer
return new Scene1875();
case 1900:
+ // Spill Mountains Elevator Exit
return new Scene1900();
case 1925:
+ // Spill Mountains Elevator Shaft
return new Scene1925();
case 1945:
+ // Spill Mountains Shaft Bottom
return new Scene1945();
case 1950:
+ // Flup Tube Corridor Maze
return new Scene1950();
/* Scene group #2 */
- //
case 2000:
- // Ice Maze
+ // Spill Mountains
return new Scene2000();
case 2350:
- // Ice Maze: Balloon Launch Platform
+ // Spill Mountains: Balloon Launch Platform
return new Scene2350();
case 2400:
- // Ice Maze: Large empty room
+ // Spill Mountains: Unused large empty room
return new Scene2400();
case 2425:
- // Ice Maze:
+ // Spill Mountains: The Hall of Records
return new Scene2425();
case 2430:
- // Ice Maze: Bedroom
+ // Spill Mountains: Bedroom
return new Scene2430();
case 2435:
- // Ice Maze: Throne room
+ // Spill Mountains: Throne room
return new Scene2435();
case 2440:
- // Ice Maze: Another bedroom
+ // Spill Mountains: Another bedroom
return new Scene2440();
case 2445:
- // Ice Maze:
+ // Spill Mountains:
return new Scene2445();
case 2450:
- // Ice Maze: Another bedroom
+ // Spill Mountains: Another bedroom
return new Scene2450();
case 2455:
- // Ice Maze: Inside crevasse
+ // Spill Mountains: Inside crevasse
return new Scene2455();
case 2500:
- // Ice Maze: Large Cave
+ // Spill Mountains: Large Ledge
return new Scene2500();
case 2525:
- // Ice Maze: Furnace room
+ // Spill Mountains: Furnace room
return new Scene2525();
case 2530:
- // Ice Maze: Well
+ // Spill Mountains: Well
return new Scene2530();
case 2535:
- // Ice Maze: Tannery
+ // Spill Mountains: Tannery
return new Scene2535();
case 2600:
- // Ice Maze: Exit
+ // Spill Mountains: Exit
return new Scene2600();
case 2700:
- // Forest Maze
+ // Outer Forest
return new Scene2700();
case 2750:
- // Forest Maze
+ // Inner Forest
return new Scene2750();
case 2800:
- // Exiting Forest
+ // Guard post
return new Scene2800();
case 2900:
- error("Missing scene %d from group 2", sceneNumber);
+ // Balloon Cutscene
+ return new Scene2900();
+
/* Scene group #3 */
- //
+ // ARM Base Hanager
case 3100:
return new Scene3100();
case 3125:
@@ -247,34 +266,43 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Room with large stasis field negator
return new Scene3250();
case 3255:
+ // Guard Post
return new Scene3255();
case 3260:
- // Computer room
+ // ARM Base - Computer room
return new Scene3260();
case 3275:
- // Hall
+ // ARM Base - Hall
return new Scene3275();
case 3350:
// Cutscene - Ship landing
return new Scene3350();
case 3375:
+ // Circular Walkway
return new Scene3375();
case 3385:
+ // Corridor
return new Scene3385();
case 3395:
+ // Walkway
return new Scene3395();
case 3400:
+ // Confrontation
return new Scene3400();
case 3500:
+ // Flub tube maze
return new Scene3500();
case 3600:
+ // Cutscene - walking at gunpoint
return new Scene3600();
case 3700:
// Cutscene - Teleport outside
return new Scene3700();
case 3800:
+ // Desert
return new Scene3800();
case 3900:
+ // Forest Entrance
return new Scene3900();
default:
error("Unknown scene number - %d", sceneNumber);
@@ -294,8 +322,11 @@ bool Ringworld2Game::canLoadGameStateCurrently() {
* Returns true if it is currently okay to save the game
*/
bool Ringworld2Game::canSaveGameStateCurrently() {
- // Don't allow a game to be saved if a dialog is active
- return g_globals->_gfxManagers.size() == 1;
+ // Don't allow a game to be saved if a dialog is active, or if an animation
+ // is playing, or if an active scene prevents it
+ return g_globals->_gfxManagers.size() == 1 && R2_GLOBALS._animationCtr == 0 &&
+ (!R2_GLOBALS._sceneManager._scene ||
+ !((SceneExt *)R2_GLOBALS._sceneManager._scene)->_preventSaving);
}
/*--------------------------------------------------------------------------*/
@@ -305,12 +336,28 @@ SceneExt::SceneExt(): Scene() {
_stripManager._onEnd = SceneExt::endStrip;
for (int i = 0; i < 256; i++)
- _field312[i] = 0;
- _field372 = _field37A = 0;
+ _shadowPaletteMap[i] = 0;
+
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
- _focusObject = NULL;
+ _preventSaving = false;
+
+ // Reset screen clipping area
+ R2_GLOBALS._screenSurface._clipRect = Rect();
+
+ // WORKAROUND: In the original, playing animations don't reset the global _animationCtr
+ // counter as scene changes unless the playing animation explicitly finishes. For now,
+ // 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(&_shadowPaletteMap[0], 256);
+ _sceneAreas.synchronize(s);
}
void SceneExt::postInit(SceneObjectList *OwnerList) {
@@ -319,18 +366,18 @@ 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;
+ static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
+
int prevScene = R2_GLOBALS._sceneManager._previousScene;
int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
|| (sceneNumber == 50)
- || ((prevScene == 205) && (sceneNumber == 100))
- || ((prevScene == 180) && (sceneNumber == 100))) {
- static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
+ || ((sceneNumber == 100) && (prevScene == 0 || prevScene == 180 || prevScene == 205))) {
R2_GLOBALS._uiElements._active = true;
R2_GLOBALS._uiElements.show();
} else {
@@ -341,6 +388,11 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
void SceneExt::remove() {
_sceneAreas.clear();
Scene::remove();
+ R2_GLOBALS._uiElements._active = true;
+
+ if (R2_GLOBALS._events.getCursor() >= EXITCURSOR_N &&
+ R2_GLOBALS._events.getCursor() <= SHADECURSOR_DOWN)
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
}
void SceneExt::process(Event &event) {
@@ -349,43 +401,9 @@ void SceneExt::process(Event &event) {
}
void SceneExt::dispatch() {
-/*
- _timerList.dispatch();
-
- if (_field37A) {
- if ((--_field37A == 0) && R2_GLOBALS._dayNumber) {
- if (R2_GLOBALS._uiElements._active && R2_GLOBALS._player._enabled) {
- R2_GLOBALS._uiElements.show();
- }
-
- _field37A = 0;
- }
- }
-*/
Scene::dispatch();
}
-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:
@@ -407,17 +425,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:
@@ -445,7 +465,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) {
@@ -461,7 +480,6 @@ void SceneExt::startStrip() {
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
R2_GLOBALS._player.enableControl();
@@ -509,10 +527,12 @@ 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();
+ R2_GLOBALS._screenSurface.addDirtyRect(_backSurface.getBounds());
+
// Free the resource data
DEALLOCATE(dataP);
}
@@ -553,14 +573,24 @@ void SceneExt::scalePalette(int RFactor, int GFactor, int BFactor) {
varC = tmp;
varD = j;
}
- this->_field312[i] = varD;
+ this->_shadowPaletteMap[i] = varD;
}
}
+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) {
SceneHandler::postInit(OwnerList);
+
+ if (!R2_GLOBALS._playStream.setFile("SND4K.RES"))
+ warning("Could not find SND4K.RES voice file");
}
void SceneHandlerExt::process(Event &event) {
@@ -573,7 +603,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);
}
@@ -583,11 +613,31 @@ void SceneHandlerExt::process(Event &event) {
SceneHandler::process(event);
}
+void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad) {
+ // Set up the shading maps used for showing the player in shadows
+ 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) {
@@ -617,7 +667,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) {
@@ -637,18 +687,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;
@@ -656,9 +707,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;
}
@@ -733,113 +784,113 @@ bool DisplayObject::performAction(int action) {
Ringworld2InvObjectList::Ringworld2InvObjectList():
_none(1, 1),
- _inv1(1, 2),
- _inv2(1, 3),
+ _optoDisk(1, 2),
+ _reader(1, 3),
_negatorGun(1, 4),
_steppingDisks(1, 5),
- _inv5(1, 6),
- _inv6(1, 7),
- _inv7(1, 8),
- _inv8(1, 9),
- _inv9(1, 10),
- _inv10(1, 11),
- _inv11(1, 12),
- _inv12(1, 13),
- _inv13(1, 14),
- _inv14(1, 15),
- _inv15(1, 16),
- _inv16(1, 17),
- _inv17(2, 2),
- _inv18(2, 3),
- _inv19(2, 4),
- _inv20(2, 5),
- _inv21(2, 5),
- _inv22(2, 6),
- _inv23(2, 7),
- _inv24(2, 8),
- _inv25(2, 9),
- _inv26(2, 10),
- _inv27(2, 11),
- _inv28(2, 12),
- _inv29(2, 13),
- _inv30(2, 14),
- _inv31(2, 15),
- _inv32(2, 16),
- _inv33(3, 2),
- _inv34(3, 3),
- _inv35(3, 4),
- _inv36(3, 5),
- _inv37(3, 6),
- _inv38(3, 7),
- _inv39(1, 10),
- _inv40(3, 8),
- _inv41(3, 9),
- _inv42(3, 10),
- _inv43(3, 11),
- _inv44(3, 12),
- _inv45(3, 13),
- _inv46(3, 17),
- _inv47(3, 14),
- _inv48(3, 14),
- _inv49(3, 15),
- _inv50(3, 15),
- _inv51(3, 17),
- _inv52(4, 2) {
+ _attractorUnit(1, 6),
+ _sensorProbe(1, 7),
+ _sonicStunner(1, 8),
+ _cableHarness(1, 9),
+ _comScanner(1, 10),
+ _spentPowerCapsule(1, 11), // 10
+ _chargedPowerCapsule(1, 12),
+ _aerosol(1, 13),
+ _remoteControl(1, 14),
+ _opticalFibre(1, 15),
+ _clamp(1, 16),
+ _attractorHarness(1, 17),
+ _fuelCell(2, 2),
+ _gyroscope(2, 3),
+ _airbag(2, 4),
+ _rebreatherTank(2, 5), // 20
+ _reserveTank(2, 5),
+ _guidanceModule(2, 6),
+ _thrusterValve(2, 7),
+ _balloonBackpack(2, 8),
+ _radarMechanism(2, 9),
+ _joystick(2, 10),
+ _ignitor(2, 11),
+ _diagnosticsDisplay(2, 12),
+ _glassDome(2, 13),
+ _wickLamp(2, 14), // 30
+ _scrithKey(2, 15),
+ _tannerMask(2, 16),
+ _pureGrainAlcohol(3, 2),
+ _blueSapphire(3, 3),
+ _ancientScrolls(3, 4),
+ _flute(3, 5),
+ _gunpowder(3, 6),
+ _unused(3, 7),
+ _comScanner2(1, 10),
+ _superconductorWire(3, 8), // 40
+ _pillow(3, 9),
+ _foodTray(3, 10),
+ _laserHacksaw(3, 11),
+ _photonStunner(3, 12),
+ _battery(3, 13),
+ _soakedFaceMask(2, 17),
+ _lightBulb(3, 14),
+ _alcoholLamp1(2, 14),
+ _alcoholLamp2(3, 15),
+ _alocholLamp3(3, 15), // 50
+ _brokenDisplay(3, 17),
+ _toolbox(4, 2) {
// Add the items to the list
_itemList.push_back(&_none);
- _itemList.push_back(&_inv1);
- _itemList.push_back(&_inv2);
+ _itemList.push_back(&_optoDisk);
+ _itemList.push_back(&_reader);
_itemList.push_back(&_negatorGun);
_itemList.push_back(&_steppingDisks);
- _itemList.push_back(&_inv5);
- _itemList.push_back(&_inv6);
- _itemList.push_back(&_inv7);
- _itemList.push_back(&_inv8);
- _itemList.push_back(&_inv9);
- _itemList.push_back(&_inv10);
- _itemList.push_back(&_inv11);
- _itemList.push_back(&_inv12);
- _itemList.push_back(&_inv13);
- _itemList.push_back(&_inv14);
- _itemList.push_back(&_inv15);
- _itemList.push_back(&_inv16);
- _itemList.push_back(&_inv17);
- _itemList.push_back(&_inv18);
- _itemList.push_back(&_inv19);
- _itemList.push_back(&_inv20);
- _itemList.push_back(&_inv21);
- _itemList.push_back(&_inv22);
- _itemList.push_back(&_inv23);
- _itemList.push_back(&_inv24);
- _itemList.push_back(&_inv25);
- _itemList.push_back(&_inv26);
- _itemList.push_back(&_inv27);
- _itemList.push_back(&_inv28);
- _itemList.push_back(&_inv29);
- _itemList.push_back(&_inv30);
- _itemList.push_back(&_inv31);
- _itemList.push_back(&_inv32);
- _itemList.push_back(&_inv33);
- _itemList.push_back(&_inv34);
- _itemList.push_back(&_inv35);
- _itemList.push_back(&_inv36);
- _itemList.push_back(&_inv37);
- _itemList.push_back(&_inv38);
- _itemList.push_back(&_inv39);
- _itemList.push_back(&_inv40);
- _itemList.push_back(&_inv41);
- _itemList.push_back(&_inv42);
- _itemList.push_back(&_inv43);
- _itemList.push_back(&_inv44);
- _itemList.push_back(&_inv45);
- _itemList.push_back(&_inv46);
- _itemList.push_back(&_inv47);
- _itemList.push_back(&_inv48);
- _itemList.push_back(&_inv49);
- _itemList.push_back(&_inv50);
- _itemList.push_back(&_inv51);
- _itemList.push_back(&_inv52);
+ _itemList.push_back(&_attractorUnit);
+ _itemList.push_back(&_sensorProbe);
+ _itemList.push_back(&_sonicStunner);
+ _itemList.push_back(&_cableHarness);
+ _itemList.push_back(&_comScanner);
+ _itemList.push_back(&_spentPowerCapsule); // 10
+ _itemList.push_back(&_chargedPowerCapsule);
+ _itemList.push_back(&_aerosol);
+ _itemList.push_back(&_remoteControl);
+ _itemList.push_back(&_opticalFibre);
+ _itemList.push_back(&_clamp);
+ _itemList.push_back(&_attractorHarness);
+ _itemList.push_back(&_fuelCell);
+ _itemList.push_back(&_gyroscope);
+ _itemList.push_back(&_airbag);
+ _itemList.push_back(&_rebreatherTank); // 20
+ _itemList.push_back(&_reserveTank);
+ _itemList.push_back(&_guidanceModule);
+ _itemList.push_back(&_thrusterValve);
+ _itemList.push_back(&_balloonBackpack);
+ _itemList.push_back(&_radarMechanism);
+ _itemList.push_back(&_joystick);
+ _itemList.push_back(&_ignitor);
+ _itemList.push_back(&_diagnosticsDisplay);
+ _itemList.push_back(&_glassDome);
+ _itemList.push_back(&_wickLamp); // 30
+ _itemList.push_back(&_scrithKey);
+ _itemList.push_back(&_tannerMask);
+ _itemList.push_back(&_pureGrainAlcohol);
+ _itemList.push_back(&_blueSapphire);
+ _itemList.push_back(&_ancientScrolls);
+ _itemList.push_back(&_flute);
+ _itemList.push_back(&_gunpowder);
+ _itemList.push_back(&_unused);
+ _itemList.push_back(&_comScanner2);
+ _itemList.push_back(&_superconductorWire); // 40
+ _itemList.push_back(&_pillow);
+ _itemList.push_back(&_foodTray);
+ _itemList.push_back(&_laserHacksaw);
+ _itemList.push_back(&_photonStunner);
+ _itemList.push_back(&_battery);
+ _itemList.push_back(&_soakedFaceMask);
+ _itemList.push_back(&_lightBulb);
+ _itemList.push_back(&_alcoholLamp1);
+ _itemList.push_back(&_alcoholLamp2);
+ _itemList.push_back(&_alocholLamp3); // 50
+ _itemList.push_back(&_brokenDisplay);
+ _itemList.push_back(&_toolbox);
_selectedItem = NULL;
}
@@ -904,6 +955,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) {
@@ -918,7 +972,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, R2_SEEKER);
+ } 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);
}
/*--------------------------------------------------------------------------*/
@@ -939,19 +1115,31 @@ void Ringworld2Game::start() {
if (slot >= 0)
R2_GLOBALS._sceneHandler->_loadGameSlot = slot;
else {
- // Switch to the first game scene
+ // Switch to the first title screen
R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._sceneManager.setNewScene(100);
+ R2_GLOBALS._sceneManager.setNewScene(180);
}
g_globals->_events.showCursor();
}
+void Ringworld2Game::restartGame() {
+ if (MessageDialog::show(Ringworld2::R2_RESTART_MSG, CANCEL_BTN_STRING, YES_MSG) == 1)
+ restart();
+}
+
void Ringworld2Game::restart() {
g_globals->_scenePalette.clearListeners();
g_globals->_soundHandler.stop();
+ // Reset the globals
+ g_globals->reset();
+
+ // Clear save/load slots
+ g_globals->_sceneHandler->_saveGameSlot = -1;
+ g_globals->_sceneHandler->_loadGameSlot = -1;
+
// Change to the first game scene
g_globals->_sceneManager.changeScene(100);
}
@@ -1008,25 +1196,25 @@ void Ringworld2Game::processEvent(Event &event) {
case Common::KEYCODE_F4:
// F4 - Restart
restartGame();
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
case Common::KEYCODE_F7:
// F7 - Restore
restoreGame();
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
case Common::KEYCODE_F8:
// F8 - Credits
- warning("TODO: Show Credits");
+ R2_GLOBALS._sceneManager.changeScene(205);
break;
case Common::KEYCODE_F10:
// F10 - Pause
GfxDialog::setPalette();
MessageDialog::show(GAME_PAUSED_MSG, OK_BTN_STRING);
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
default:
@@ -1037,8 +1225,13 @@ void Ringworld2Game::processEvent(Event &event) {
void Ringworld2Game::rightClick() {
RightClickDialog *dlg = new RightClickDialog();
- dlg->execute();
+ int option = dlg->execute();
delete dlg;
+
+ if (option == 0)
+ CharacterDialog::show();
+ else if (option == 1)
+ HelpDialog::show();
}
/*--------------------------------------------------------------------------*/
@@ -1083,6 +1276,14 @@ void SceneActor::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
}
+void SceneActor::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
+ _shadowMap = NULL;
+ _linkedActor = NULL;
+
+ SceneObject::remove();
+}
+
bool SceneActor::startAction(CursorType action, Event &event) {
bool handled = true;
@@ -1115,13 +1316,20 @@ bool SceneActor::startAction(CursorType action, Event &event) {
return handled;
}
+GfxSurface SceneActor::getFrame() {
+ GfxSurface frame = SceneObject::getFrame();
+
+ return frame;
+}
+
/*--------------------------------------------------------------------------*/
-SceneArea::SceneArea(): EventHandler() {
+SceneArea::SceneArea(): SceneItem() {
_enabled = true;
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
_cursorState = 0;
+ _cursorNum = CURSOR_NONE;
}
void SceneArea::synchronize(Serializer &s) {
@@ -1130,8 +1338,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);
}
@@ -1140,10 +1348,13 @@ void SceneArea::remove() {
}
void SceneArea::process(Event &event) {
+ Common::Point mousePos = event.mousePos;
+ mousePos.x += R2_GLOBALS._sceneManager._scene->_sceneBounds.left;
+
if (!R2_GLOBALS._insetUp && _enabled && R2_GLOBALS._events.isCursorVisible()) {
CursorType cursor = R2_GLOBALS._events.getCursor();
- if (_bounds.contains(event.mousePos)) {
+ if (_bounds.contains(mousePos)) {
// Cursor moving in bounded area
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
@@ -1151,7 +1362,7 @@ void SceneArea::process(Event &event) {
R2_GLOBALS._events.setCursor(_cursorNum);
}
_insideArea = true;
- } else if ((event.mousePos.y < 171) && _insideArea && (_cursorNum == cursor) &&
+ } else if ((mousePos.y < 171) && _insideArea && (_cursorNum == cursor) &&
(_savedCursorNum != CURSOR_NONE)) {
// Cursor moved outside bounded area
R2_GLOBALS._events.setCursor(_savedCursorNum);
@@ -1171,6 +1382,8 @@ void SceneArea::setDetails(const Rect &bounds, CursorType cursor) {
SceneExit::SceneExit(): SceneArea() {
_moving = false;
_destPos = Common::Point(-1, -1);
+
+ _sceneNumber = 0;
}
void SceneExit::synchronize(Serializer &s) {
@@ -1191,20 +1404,23 @@ void SceneExit::changeScene() {
}
void SceneExit::process(Event &event) {
+ Common::Point mousePos = event.mousePos;
+ mousePos.x += R2_GLOBALS._sceneManager._scene->_sceneBounds.left;
+
if (!R2_GLOBALS._insetUp) {
SceneArea::process(event);
if (_enabled) {
if (event.eventType == EVENT_BUTTON_DOWN) {
- if (!_bounds.contains(event.mousePos))
+ if (!_bounds.contains(mousePos))
_moving = false;
else if (!R2_GLOBALS._player._canWalk) {
_moving = false;
changeScene();
event.handled = true;
} else {
- Common::Point dest((_destPos.x == -1) ? event.mousePos.x : _destPos.x,
- (_destPos.y == -1) ? event.mousePos.y : _destPos.y);
+ Common::Point dest((_destPos.x == -1) ? mousePos.x : _destPos.x,
+ (_destPos.y == -1) ? mousePos.y : _destPos.y);
ADD_PLAYER_MOVER(dest.x, dest.y);
_moving = true;
@@ -1221,6 +1437,7 @@ void SceneExit::process(Event &event) {
/*--------------------------------------------------------------------------*/
void SceneAreaObject::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
_object1.remove();
SceneArea::remove();
--R2_GLOBALS._insetUp;
@@ -1230,19 +1447,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();
}
}
}
@@ -1262,293 +1482,214 @@ 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);
}
/*****************************************************************************/
-UnkObject1200::UnkObject1200() {
- _field16 = _field3A = NULL;
- _field12 = _field14 = 0;
- _field26 = _field28 = _field2A = _field2C = _field2E = _field30 = 0;
- _field32 = _field34 = _field36 = _field38 = _field3E = _field40 = 0;
+MazeUI::MazeUI() {
+ _mapData = NULL;
+ _cellsVisible.x = _cellsVisible.y = 0;
+ _mapCells.x = _mapCells.y = 0;
+ _cellSize.x = _cellSize.y = 0;
+ _mapOffset.x = _mapOffset.y = 0;
+ _resNum = _cellsResNum = 0;
+ _frameCount = _resCount = _mapImagePitch = 0;
}
-void UnkObject1200::synchronize(Serializer &s) {
- SavedObject::synchronize(s);
+MazeUI::~MazeUI() {
+ DEALLOCATE(_mapData);
+}
- _rect1.synchronize(s);
- _rect2.synchronize(s);
+void MazeUI::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
- // FIXME: syncrhonize _field16 and _field3A
+ s.syncAsSint16LE(_resNum);
+ if (s.isLoading())
+ load(_resNum);
- s.syncAsSint16LE(_field12);
- s.syncAsSint16LE(_field14);
- s.syncAsSint16LE(_field26);
- s.syncAsSint16LE(_field28);
- s.syncAsSint16LE(_field2A);
- s.syncAsSint16LE(_field2C);
- s.syncAsSint16LE(_field2E);
- s.syncAsSint16LE(_field30);
- s.syncAsSint16LE(_field32);
- s.syncAsSint16LE(_field34);
- s.syncAsSint16LE(_field36);
- s.syncAsSint16LE(_field38);
- s.syncAsSint16LE(_field3E);
- s.syncAsSint16LE(_field40);
-}
+ s.syncAsSint16LE(_mapOffset.x);
+ s.syncAsSint16LE(_mapOffset.y);
-void UnkObject1200::sub51AE9(int arg1) {
- warning("STUB: UnkObject1200::sub51AE9()");
+ int dummy = 0;
+ s.syncAsSint16LE(dummy);
}
-int UnkObject1200::sub51AF8(Common::Point pt) {
- if (!_rect1.contains(pt))
- return -1;
+void MazeUI::load(int resNum) {
+ clear();
+ _resNum = resNum;
- int tmp1 = (pt.x - _rect1.left + _field2E) / _field2A;
- int tmp2 = (pt.y - _rect1.top + _field30) / _field2C;
+ const byte *header = g_resourceManager->getResource(RT17, resNum, 0);
- if ((tmp1 >= 0) && (tmp2 >= 0) && (_field26 > tmp1) && (_field28 > tmp2))
- return _field16[(((_field26 * tmp2) + tmp1)* 2)];
+ _cellsResNum = resNum + 1000;
+ _mapCells.x = READ_LE_UINT16(header + 2);
+ _mapCells.y = READ_LE_UINT16(header + 4);
+ _frameCount = 10;
+ _resCount = _frameCount << 3;
- return -1;
+ Visage visage;
+ visage.setVisage(_cellsResNum, 1);
+
+ GfxSurface frame = visage.getFrame(2);
+ _cellSize.x = frame.getBounds().width();
+ _cellSize.y = frame.getBounds().height();
+
+ _mapData = g_resourceManager->getResource(RT17, resNum, 1);
+
+ _mapOffset.y = _mapOffset.x = 0;
+ _cellsVisible.x = (_bounds.width() + _cellSize.x - 1) / _cellSize.x;
+ _cellsVisible.y = (_bounds.height() + _cellSize.y - 1) / _cellSize.y;
+
+ _mapImagePitch = (_cellsVisible.x + 1) * _cellSize.x;
+ _mapImage.create(_mapImagePitch, _cellSize.y);
+
+ _mapBounds = Rect(0, 0, _cellSize.x * _mapCells.x, _cellSize.y * _mapCells.y);
}
-bool UnkObject1200::sub51AFD(Common::Point pt) {
- int retval = false;
+void MazeUI::clear() {
+ if (!_resNum)
+ _resNum = 1;
- _field2E = pt.x;
- _field30 = pt.y;
+ if (_mapData)
+ DEALLOCATE(_mapData);
+ _mapData = NULL;
- if (_field2E < _rect2.top) {
- _field2E = _rect2.top;
+ _mapImage.clear();
+}
+
+bool MazeUI::setMazePosition(const Common::Point &pt) {
+ bool retval = false;
+
+ _mapOffset = pt;
+
+ if (_mapOffset.x < _mapBounds.top) {
+ _mapOffset.x = _mapBounds.top;
retval = true;
}
- if (_field30 < _rect2.left) {
- _field30 = _rect2.left;
+ if (_mapOffset.y < _mapBounds.left) {
+ _mapOffset.y = _mapBounds.left;
retval = true;
}
- if (_field2E + _rect1.width() > _rect2.right) {
- _field2E = _rect2.right - _rect1.width();
+ if (_mapOffset.x + _bounds.width() > _mapBounds.right) {
+ _mapOffset.x = _mapBounds.right - _bounds.width();
retval = true;
}
- if (_field30 + _rect1.height() > _rect2.bottom) {
- _field30 = _rect2.bottom - _rect1.height();
+ if (_mapOffset.y + _bounds.height() > _mapBounds.bottom) {
+ _mapOffset.y = _mapBounds.bottom - _bounds.height();
retval = true;
}
return retval;
}
-void UnkObject1200::sub51B02() {
- warning("STUB: UnkObject1200::sub51B02()");
+void MazeUI::reposition() {
}
-void UnkObject1200::sub9EDE8(Rect rect) {
- _rect1 = rect;
- warning("FIXME: UnkObject1200::sub9EDE8()");
-// _rect1.clip(g_globals->gfxManager()._bounds);
-}
+void MazeUI::draw() {
+ int yPos = 0;
+ int ySize;
+ Visage visage;
-int UnkObject1200::sub9EE22(int &arg1, int &arg2) {
- arg1 /= _field2A;
- arg2 /= _field2C;
+ _cellsVisible.y = ((_mapOffset.y % _cellSize.y) + _bounds.height() +
+ (_cellSize.y - 1)) / _cellSize.y;
- if ((arg1 >= 0) && (arg2 >= 0) && (_field26 > arg1) && (_field28 > arg2)) {
- return _field16[(((_field26 * arg2) + arg1) * 2)];
- }
+ // 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;
- return -1;
-}
+ // Loop to iterate through the horizontal visible cells to build up
+ // an entire cell high horizontal slice of the map, plus one extra cell
+ // to allow for partial cell scrolling on-screen on the left/right sides
+ for (int xCtr = 0; xCtr <= _cellsVisible.x; ++xCtr) {
+ int cellX = _mapOffset.x / _cellSize.x + xCtr;
-void Scene1200::sub9DAD6(int indx) {
- _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4);
+ // Get the type of content to display in the cell
+ int cell = getCellFromCellXY(Common::Point(cellX, cellY)) - 1;
+ if (cell >= 0) {
+ int frameNum = (cell % _frameCount) + 1;
+ int rlbNum = (cell % _resCount) / _frameCount + 1;
+ int resNum = _cellsResNum + (cell / _resCount);
- switch (indx) {
- case 0:
- if ( ((_object1.sub51AF8(Common::Point(200, 50)) > 36) || (_object1.sub51AF8(Common::Point(200, 88)) > 36))
- && ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4))
- || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2))
- || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1))
- || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1200;
- setAction(&_sequenceManager, this, 1200, &_actor1, NULL);
- } else if (_object1.sub51AF8(Common::Point(200, 69)) == 36) {
- switch (_field412 - 1) {
- case 0:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 15;
- else
- _sceneMode = 10;
- break;
- case 1:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 76;
- else
- _sceneMode = 75;
- break;
- case 2:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 101;
- else
- _sceneMode = 100;
- break;
- case 3:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 111;
- else
- _sceneMode = 110;
- break;
- default:
- break;
- }
- R2_GLOBALS._player.disableControl();
- _field412 = 1;
- signal();
- }
- break;
- case 1:
- if ( ((_object1.sub51AF8(Common::Point(120, 50)) > 36) || (_object1.sub51AF8(Common::Point(120, 88)) > 36))
- && ( ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33) && (_field418 != 4))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21) && (_field418 != 2))
- || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17) && (_field418 != 1))
- || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1201;
- setAction(&_sequenceManager, this, 1201, &_actor1, NULL);
- } else if (_object1.sub51AF8(Common::Point(120, 69)) == 36) {
- switch (_field412 - 1) {
- case 0:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 56;
- else
- _sceneMode = 55;
- break;
- case 1:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 25;
- else
- _sceneMode = 20;
- break;
- case 2:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 91;
- else
- _sceneMode = 90;
- break;
- case 3:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 121;
- else
- _sceneMode = 120;
- break;
- default:
- break;
- }
- R2_GLOBALS._player.disableControl();
- _field412 = 2;
- signal();
- }
- break;
- case 2:
- if ( ((_object1.sub51AF8(Common::Point(140, 110)) > 36) || (_object1.sub51AF8(Common::Point(178, 110)) > 36))
- && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5) && (_field418 != 3))
- || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1203;
- setAction(&_sequenceManager, this, 1203, &_actor1, NULL);
- } else if (_object1.sub51AF8(Common::Point(160, 110)) == 36) {
- switch (_field412 - 1) {
- case 0:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 51;
- else
- _sceneMode = 50;
- break;
- case 1:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 81;
- else
- _sceneMode = 80;
- break;
- case 2:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 35;
- else
- _sceneMode = 30;
- break;
- case 3:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 116;
- else
- _sceneMode = 115;
- break;
- default:
- break;
+ visage.setVisage(resNum, rlbNum);
+ GfxSurface frame = visage.getFrame(frameNum);
+
+ _mapImage.copyFrom(frame, xCtr * _cellSize.x, 0);
+ } else {
+ GfxSurface emptyRect;
+ emptyRect.create(_cellSize.x, _cellSize.y);
+
+ _mapImage.copyFrom(emptyRect, xCtr * _cellSize.x, 0);
}
- R2_GLOBALS._player.disableControl();
- _field412 = 3;
- signal();
}
- break;
- case 3:
- if ( ((_object1.sub51AF8(Common::Point(140, 30)) > 36) || (_object1.sub51AF8(Common::Point(178, 30)) > 36))
- && ( ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9) && (_field418 != 3))
- || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17)) )
- ) {
- R2_GLOBALS._player.disableControl();
- _sceneMode = 1202;
- setAction(&_sequenceManager, this, 1202, &_actor1, NULL);
- } else if (_object1.sub51AF8(Common::Point(160, 30)) == 36) {
- switch (_field412 - 1) {
- case 0:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 61;
- else
- _sceneMode = 60;
- break;
- case 1:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 71;
- else
- _sceneMode = 70;
- break;
- case 2:
- if (R2_GLOBALS._player._visage == 3156)
- _sceneMode = 96;
- else
- _sceneMode = 95;
- break;
- case 3:
- if (R2_GLOBALS._player._visage == 3155)
- _sceneMode = 45;
- else
- _sceneMode = 40;
- break;
- default:
- _sceneMode = 1;
- R2_GLOBALS._player.setup(3156, 4, 6);
- break;
+
+ if (yPos == 0) {
+ // 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);
+
+ Rect srcBounds(_mapOffset.x % _cellSize.x, _mapOffset.y % _cellSize.y,
+ (_mapOffset.x % _cellSize.x) + _bounds.width(), _cellSize.y);
+ Rect destBounds(_bounds.left, yPos, _bounds.right, yPos + ySize);
+
+ R2_GLOBALS.gfxManager().copyFrom(_mapImage, srcBounds, destBounds);
+ } else {
+ if ((yPos + _cellSize.y) < _bounds.bottom) {
+ ySize = _cellSize.y;
+ } else {
+ ySize = _bounds.bottom - yPos;
}
- R2_GLOBALS._player.disableControl();
- _field412 = 4;
- signal();
+
+ Rect srcBounds(_mapOffset.x % _cellSize.x, 0,
+ (_mapOffset.x % _cellSize.x) + _bounds.width(), ySize);
+ Rect destBounds(_bounds.left, yPos, _bounds.right, yPos + ySize);
+
+ R2_GLOBALS.gfxManager().copyFrom(_mapImage, srcBounds, destBounds);
}
- break;
- default:
- break;
}
}
+int MazeUI::getCellFromPixelXY(const Common::Point &pt) {
+ if (!_bounds.contains(pt))
+ return -1;
+
+ int cellX = (pt.x - _bounds.left + _mapOffset.x) / _cellSize.x;
+ int cellY = (pt.y - _bounds.top + _mapOffset.y) / _cellSize.y;
+
+ if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y))
+ return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2);
+
+ return -1;
+}
+
+int MazeUI::getCellFromCellXY(const Common::Point &p) {
+ if (p.x < 0 || p.y < 0 || p.x >= _mapCells.x || p.y >= _mapCells.y) {
+ return -1;
+ } else {
+ return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * p.y + p.x) * 2);
+ }
+}
+
+int MazeUI::pixelToCellXY(Common::Point &pt) {
+ pt.x /= _cellSize.x;
+ pt.y /= _cellSize.y;
+
+ if ((pt.x >= 0) && (pt.y >= 0) && (pt.x < _mapCells.x) && (pt.y < _mapCells.y)) {
+ return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * pt.y + pt.x) * 2);
+ }
+
+ return -1;
+}
+
+void MazeUI::setDisplayBounds(const Rect &r) {
+ _bounds = r;
+ _bounds.clip(g_globals->gfxManager()._bounds);
+}
+
/*--------------------------------------------------------------------------*/
void AnimationSlice::load(Common::File &f) {
@@ -1563,6 +1704,12 @@ void AnimationSlice::load(Common::File &f) {
AnimationSlices::AnimationSlices() {
_pixelData = NULL;
+
+ _dataSize = 0;
+ _dataSize2 = 0;
+ _slices->_sliceOffset = 0;
+ _slices->_drawMode = 0;
+ _slices->_secondaryIndex = 0;
}
AnimationSlices::~AnimationSlices() {
@@ -1624,10 +1771,21 @@ AnimationPlayer::AnimationPlayer(): EventHandler() {
_screenBounds = R2_GLOBALS._gfxManagerInstance._bounds;
_rect1 = R2_GLOBALS._gfxManagerInstance._bounds;
_paletteMode = ANIMPALMODE_REPLACE_PALETTE;
- _field3A = 1;
+ _canSkip = true;
_sliceHeight = 1;
- _field58 = 1;
_endAction = NULL;
+
+ _sliceCurrent = nullptr;
+ _sliceNext = nullptr;
+ _animLoaded = false;
+ _objectMode = ANIMOBJMODE_1;
+ _dataNeeded = 0;
+ _playbackTick = 0;
+ _playbackTickPrior = 0;
+ _position = 0;
+ _nextSlicesPosition = 0;
+ _frameDelay = 0;
+ _gameFrame = 0;
}
AnimationPlayer::~AnimationPlayer() {
@@ -1637,7 +1795,9 @@ AnimationPlayer::~AnimationPlayer() {
void AnimationPlayer::synchronize(Serializer &s) {
EventHandler::synchronize(s);
- warning("TODO AnimationPlayer::load");
+
+ // TODO: Implement saving for animation player state. Currently, I disable saving
+ // when an animation is active, so saving it's state would a "nice to have".
}
void AnimationPlayer::remove() {
@@ -1648,8 +1808,7 @@ void AnimationPlayer::remove() {
}
void AnimationPlayer::process(Event &event) {
- if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) &&
- (_field3A)) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) && _canSkip) {
// Move the current position to the end
_position = _subData._duration;
}
@@ -1695,11 +1854,13 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
_playbackTickPrior = -1;
_playbackTick = 0;
- // The final multiplication is used to deliberately slow down playback, since the original
- // was slowed down by the amount of time spent to decode and display the frames
- _frameDelay = (60 / _subData._frameRate) * 8;
+ _frameDelay = (60 / _subData._frameRate);
_gameFrame = R2_GLOBALS._events.getFrameNumber();
+ // WORKAROUND: Slow down the title sequences to better match the original
+ if (animId <= 4 || animId == 15)
+ _frameDelay *= 8;
+
if (_subData._totalSize) {
_dataNeeded = _subData._totalSize;
} else {
@@ -1755,7 +1916,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];
@@ -1768,7 +1929,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
}
++R2_GLOBALS._animationCtr;
- _field38 = 1;
+ _animLoaded = true;
return true;
}
@@ -1865,7 +2026,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) {
// Unlock the screen surface
R2_GLOBALS._screenSurface.unlockSurface();
- if (_objectMode == 42) {
+ if (_objectMode == ANIMOBJMODE_42) {
_screenBounds.expandPanes();
// Copy the drawn frame to the back surface
@@ -1915,7 +2076,7 @@ bool AnimationPlayer::isCompleted() {
}
void AnimationPlayer::close() {
- if (_field38) {
+ if (_animLoaded) {
switch (_paletteMode) {
case 0:
R2_GLOBALS._scenePalette.replace(&_palette);
@@ -1934,7 +2095,7 @@ void AnimationPlayer::close() {
// Close the resource file
_resourceFile.close();
- if (_objectMode != 42) {
+ if (_objectMode != ANIMOBJMODE_42) {
// flip screen in original
}
@@ -1944,9 +2105,9 @@ void AnimationPlayer::close() {
_animData1 = NULL;
_animData2 = NULL;
- _field38 = 0;
+ _animLoaded = false;
if (g_globals != NULL)
- R2_GLOBALS._animationCtr = MAX(R2_GLOBALS._animationCtr, 0);
+ R2_GLOBALS._animationCtr = MAX(R2_GLOBALS._animationCtr - 1, 0);
}
void AnimationPlayer::rleDecode(const byte *pSrc, byte *pDest, int size) {
@@ -1992,15 +2153,358 @@ void AnimationPlayer::getSlices() {
/*--------------------------------------------------------------------------*/
AnimationPlayerExt::AnimationPlayerExt(): AnimationPlayer() {
- _v = 0;
- _field3A = 0;
+ _isActive = false;
+ _canSkip = false;
}
void AnimationPlayerExt::synchronize(Serializer &s) {
AnimationPlayer::synchronize(s);
- s.syncAsSint16LE(_v);
+ s.syncAsSint16LE(_isActive);
+}
+
+/*--------------------------------------------------------------------------*/
+
+ModalWindow::ModalWindow() {
+ _insetCount = 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(_insetCount);
+}
+
+void ModalWindow::process(Event &event) {
+ if (_insetCount != 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::setup2(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;
+ _insetCount = R2_GLOBALS._insetUp;
+}
+
+void ModalWindow::setup3(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._desertWrongDirCtr + 1) == 0 && R2_GLOBALS._desertCorrectDirection == 0) {
+ do {
+ R2_GLOBALS._desertCorrectDirection = R2_GLOBALS._randomSource.getRandomNumber(3) + 1;
+ } while (R2_GLOBALS._desertCorrectDirection == R2_GLOBALS._desertPreviousDirection);
+ }
+
+ scanner._obj4.setup(4, 7, R2_GLOBALS._desertCorrectDirection);
+ 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::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ // Stop player moving if currently doing so
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
+
+ setup3(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 0b573bf7f0..c9695c921d 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 {
@@ -79,27 +81,23 @@ private:
static void startStrip();
static void endStrip();
public:
- byte _field312[256];
- int _field372;
+ byte _shadowPaletteMap[256];
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
- int _field37A;
+ bool _preventSaving;
- 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 +106,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,60 +159,63 @@ public:
/*--------------------------------------------------------------------------*/
class Ringworld2InvObjectList : public InvObjectList {
+private:
+ static bool SelectItem(int objectNumber);
+ static void selectDefault(int obectNumber);
public:
InvObject _none;
- InvObject _inv1;
- InvObject _inv2;
+ InvObject _optoDisk;
+ InvObject _reader;
InvObject _negatorGun;
InvObject _steppingDisks;
- InvObject _inv5;
- InvObject _inv6;
- InvObject _inv7;
- InvObject _inv8;
- InvObject _inv9;
- InvObject _inv10;
- InvObject _inv11;
- InvObject _inv12;
- InvObject _inv13;
- InvObject _inv14;
- InvObject _inv15;
- InvObject _inv16;
- InvObject _inv17;
- InvObject _inv18;
- InvObject _inv19;
- InvObject _inv20;
- InvObject _inv21;
- InvObject _inv22;
- InvObject _inv23;
- InvObject _inv24;
- InvObject _inv25;
- InvObject _inv26;
- InvObject _inv27;
- InvObject _inv28;
- InvObject _inv29;
- InvObject _inv30;
- InvObject _inv31;
- InvObject _inv32;
- InvObject _inv33;
- InvObject _inv34;
- InvObject _inv35;
- InvObject _inv36;
- InvObject _inv37;
- InvObject _inv38;
- InvObject _inv39;
- InvObject _inv40;
- InvObject _inv41;
- InvObject _inv42;
- InvObject _inv43;
- InvObject _inv44;
- InvObject _inv45;
- InvObject _inv46;
- InvObject _inv47;
- InvObject _inv48;
- InvObject _inv49;
- InvObject _inv50;
- InvObject _inv51;
- InvObject _inv52;
+ InvObject _attractorUnit;
+ InvObject _sensorProbe;
+ InvObject _sonicStunner;
+ InvObject _cableHarness;
+ InvObject _comScanner;
+ InvObject _spentPowerCapsule; // 10
+ InvObject _chargedPowerCapsule;
+ InvObject _aerosol;
+ InvObject _remoteControl;
+ InvObject _opticalFibre;
+ InvObject _clamp;
+ InvObject _attractorHarness;
+ InvObject _fuelCell;
+ InvObject _gyroscope;
+ InvObject _airbag;
+ InvObject _rebreatherTank; // 20
+ InvObject _reserveTank;
+ InvObject _guidanceModule;
+ InvObject _thrusterValve;
+ InvObject _balloonBackpack;
+ InvObject _radarMechanism;
+ InvObject _joystick;
+ InvObject _ignitor;
+ InvObject _diagnosticsDisplay;
+ InvObject _glassDome;
+ InvObject _wickLamp; // 30
+ InvObject _scrithKey;
+ InvObject _tannerMask;
+ InvObject _pureGrainAlcohol;
+ InvObject _blueSapphire;
+ InvObject _ancientScrolls;
+ InvObject _flute;
+ InvObject _gunpowder;
+ InvObject _unused;
+ InvObject _comScanner2;
+ InvObject _superconductorWire; // 40
+ InvObject _pillow;
+ InvObject _foodTray;
+ InvObject _laserHacksaw;
+ InvObject _photonStunner;
+ InvObject _battery;
+ InvObject _soakedFaceMask;
+ InvObject _lightBulb;
+ InvObject _alcoholLamp1;
+ InvObject _alcoholLamp2;
+ InvObject _alocholLamp3; // 50
+ InvObject _brokenDisplay;
+ InvObject _toolbox;
Ringworld2InvObjectList();
void reset();
@@ -226,6 +229,7 @@ public:
class Ringworld2Game: public Game {
public:
virtual void start();
+ virtual void restartGame();
virtual void restart();
virtual void endGame(int resNum, int lineNum);
@@ -260,7 +264,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 {
@@ -276,6 +282,48 @@ public:
}
};
+enum MazeDirection { MAZEDIR_NONE = 0, MAZEDIR_NORTH = 1, MAZEDIR_NORTHEAST = 2, MAZEDIR_EAST = 3,
+ MAZEDIR_SOUTHEAST = 4, MAZEDIR_SOUTH = 5, MAZEDIR_SOUTHWEST = 6, MAZEDIR_WEST = 7,
+ MAZEDIR_NORTHWEST = 8 };
+
+class MazeUI: public SceneObject {
+private:
+ void clear();
+public:
+ // The dimensions (in cells) of the entire maze map
+ Rect _mapBounds;
+
+ // Encoded cell map specifying the features of the maze
+ byte *_mapData;
+ // Image surface used to store a line of the map for rendering
+ GfxSurface _mapImage;
+
+ Common::Point _cellsVisible;
+ Common::Point _mapCells;
+ Common::Point _cellSize;
+ Common::Point _mapOffset;
+ int _resNum;
+ int _cellsResNum;
+ int _frameCount;
+ int _resCount;
+ int _mapImagePitch;
+public:
+ MazeUI();
+ virtual ~MazeUI();
+
+ void setDisplayBounds(const Rect &r);
+ bool setMazePosition(const Common::Point &pt);
+ void load(int resNum);
+ int getCellFromPixelXY(const Common::Point &pt);
+ int getCellFromCellXY(const Common::Point &p);
+ int pixelToCellXY(Common::Point &pt);
+
+ virtual Common::String getClassName() { return "MazeUI"; }
+ void synchronize(Serializer &s);
+ virtual void reposition();
+ virtual void draw();
+};
+
class SceneAreaObject: public SceneArea {
class Object1: public SceneActor {
public:
@@ -290,41 +338,6 @@ public:
void setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
-class UnkObject1200 : public SavedObject {
-public:
- Rect _rect1;
- Rect _rect2;
-
- int *_field16;
- int *_field3A;
-
- int _field12;
- int _field14;
- int _field26;
- int _field28;
- int _field2A;
- int _field2C;
- int _field2E;
- int _field30;
- int _field32;
- int _field34;
- int _field36;
- int _field38;
- int _field3E;
- int _field40;
-
- UnkObject1200();
- void synchronize(Serializer &s);
-
- void sub51AE9(int arg1);
- int sub51AF8(Common::Point pt);
- bool sub51AFD(Common::Point pt);
- void sub51B02();
- void sub9EDE8(Rect rect);
- int sub9EE22(int &arg1, int &arg2);
- virtual Common::String getClassName() { return "UnkObject1200"; }
-};
-
/*--------------------------------------------------------------------------*/
class AnimationSlice {
@@ -378,6 +391,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);
@@ -391,10 +406,11 @@ public:
AnimationData *_sliceNext;
Common::File _resourceFile;
Rect _rect1, _screenBounds;
- int _field38;
- int _field3A, _paletteMode;
- int _objectMode;
- int _field58, _sliceHeight;
+ bool _animLoaded;
+ bool _canSkip;
+ AnimationPaletteMode _paletteMode;
+ AnimationObjectMode _objectMode;
+ int _sliceHeight;
byte _palIndexes[256];
ScenePalette _palette;
AnimationPlayerSubData _subData;
@@ -418,6 +434,7 @@ public:
virtual void changePane() {}
virtual void closing() {}
+
bool load(int animId, Action *endAction = NULL);
bool isCompleted();
void close();
@@ -425,13 +442,81 @@ public:
class AnimationPlayerExt: public AnimationPlayer {
public:
- int _v;
+ bool _isActive;
public:
AnimationPlayerExt();
virtual void synchronize(Serializer &s);
};
+class ModalWindow: public SceneArea {
+public:
+ SceneActor _object1;
+ int _insetCount;
+public:
+ ModalWindow();
+
+ virtual void remove();
+ virtual void synchronize(Serializer &s);
+ virtual Common::String getClassName() { return "ModalWindow"; }
+ virtual void process(Event &event);
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+};
+
+class ScannerDialog: public ModalWindow {
+
+ 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();
+ virtual void setup2(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..2592bde19a 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -31,6 +31,11 @@ namespace TsAGE {
namespace Ringworld2 {
+/*--------------------------------------------------------------------------
+ * Scene 50 - Waking up cutscene
+ *
+ *--------------------------------------------------------------------------*/
+
void Scene50::Action1::signal() {
switch (_actionIndex++) {
case 0:
@@ -48,8 +53,8 @@ void Scene50::Action1::signal() {
}
void Scene50::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit(OwnerList);
loadScene(110);
+ SceneExt::postInit(OwnerList);
R2_GLOBALS._uiElements._active = false;
R2_GLOBALS._scenePalette.loadPalette(0);
@@ -111,7 +116,7 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
if (_strip == 2) {
scene->_sceneMode = 108;
- scene->_object3.postInit();
+ scene->_tableLocker.postInit();
scene->_stasisNegator.postInit();
if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
@@ -121,11 +126,13 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_object3,
+ // Open table locker
+ scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_tableLocker,
&scene->_stasisNegator, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 109;
- scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_object3,
+ // Close table locker
+ scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_tableLocker,
&scene->_stasisNegator, &R2_GLOBALS._player, NULL);
}
return true;
@@ -135,7 +142,7 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
if (_strip == 2) {
SceneItem::display2(100, 18);
scene->_sceneMode = 102;
- scene->_object3.postInit();
+ scene->_tableLocker.postInit();
scene->_stasisNegator.postInit();
if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
@@ -145,12 +152,12 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_object3,
+ scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_tableLocker,
&scene->_stasisNegator, NULL);
} else {
SceneItem::display2(100, 19);
scene->_sceneMode = 103;
- scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_object3,
+ scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_tableLocker,
&scene->_stasisNegator, NULL);
}
return true;
@@ -160,22 +167,21 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
}
bool Scene100::StasisNegator::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 107;
scene->setAction(&scene->_sequenceManager1, scene, 107, &R2_GLOBALS._player, &scene->_stasisNegator, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_LOOK:
SceneItem::display2(100, _state ? 24 : 25);
@@ -183,25 +189,29 @@ bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) {
case CURSOR_TALK:
SceneItem::display2(100, _state ? 26 : 27);
return true;
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 110;
scene->setAction(&scene->_sequenceManager1, scene, 110, &R2_GLOBALS._player, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene100::SteppingDisks::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 111;
scene->setAction(&scene->_sequenceManager1, scene, 111, &R2_GLOBALS._player, this, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
@@ -210,14 +220,15 @@ bool Scene100::SteppingDisks::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene100::Terminal::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 105;
scene->setAction(&scene->_sequenceManager1, scene, 105, &R2_GLOBALS._player, this, NULL);
return true;
+ }
default:
return NamedHotspot::startAction(action, event);
}
@@ -226,9 +237,8 @@ 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);
@@ -291,10 +301,10 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 50:
case 180:
- _object5.postInit();
- _object4.postInit();
+ _wardrobeColorAnim.postInit();
+ _wardrobeTopAnim.postInit();
_sceneMode = 104;
- setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_wardrobeTopAnim, &_wardrobeColorAnim, NULL);
break;
case 125:
_sceneMode = 100;
@@ -327,14 +337,14 @@ void Scene100::signal() {
_table.setStrip(2);
_table.setFrame(3);
- _object3.remove();
+ _tableLocker.remove();
_stasisNegator.remove();
R2_GLOBALS._player.enableControl();
break;
case 104:
_sceneMode = 0;
- _object5.remove();
- _object4.remove();
+ _wardrobeColorAnim.remove();
+ _wardrobeTopAnim.remove();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player._numFrames = 10;
@@ -383,7 +393,7 @@ void Scene100::dispatch() {
SceneExt::dispatch();
if ((_sceneMode == 101) && (_door._frame == 2) && (_table._strip == 5)) {
- _table.setAction(&_sequenceManager2, NULL, 103, &_table, &_object3, &_stasisNegator, NULL);
+ _table.setAction(&_sequenceManager2, NULL, 103, &_table, &_tableLocker, &_stasisNegator, NULL);
}
}
@@ -392,27 +402,27 @@ 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);
}
/*--------------------------------------------------------------------------*/
Scene125::Icon::Icon(): SceneActor() {
_lookLineNum = 0;
- _field98 = 0;
+ _iconId = 0;
_pressed = false;
}
void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
- _object1.postInit();
- _object1.fixPriority(255);
- _object1.hide();
+ _glyph.postInit();
+ _glyph.fixPriority(255);
+ _glyph.hide();
_sceneText1._color1 = 92;
_sceneText1._color2 = 0;
@@ -426,7 +436,7 @@ void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
void Scene125::Icon::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_pressed);
}
@@ -455,15 +465,15 @@ void Scene125::Icon::process(Event &event) {
scene->_sound1.play(14);
setFrame(2);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 1:
- _object1.setStrip(2);
+ _glyph.setStrip(2);
break;
case 3:
- _object1.setStrip(4);
+ _glyph.setStrip(4);
break;
case 5:
- _object1.setStrip(6);
+ _glyph.setStrip(6);
break;
default:
break;
@@ -482,15 +492,15 @@ void Scene125::Icon::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
setFrame(1);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 2:
- _object1.setStrip(1);
+ _glyph.setStrip(1);
break;
case 4:
- _object1.setStrip(3);
+ _glyph.setStrip(3);
break;
case 6:
- _object1.setStrip(5);
+ _glyph.setStrip(5);
break;
default:
break;
@@ -504,18 +514,18 @@ void Scene125::Icon::process(Event &event) {
}
void Scene125::Icon::setIcon(int id) {
- Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
-
- _lookLineNum = _field98 = id;
+ _lookLineNum = _iconId = id;
SceneActor::_lookLineNum = id;
_sceneText1.remove();
_sceneText2.remove();
if (_lookLineNum) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
showIcon();
- _object1.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
- _object1.setPosition(_position);
+ _glyph.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _glyph.setPosition(_position);
_sceneText1._fontNumber = scene->_iconFontNumber;
_sceneText1.setup(CONSOLE125_MESSAGES[id]);
@@ -558,38 +568,38 @@ void Scene125::Icon::setIcon(int id) {
void Scene125::Icon::showIcon() {
_sceneText1.show();
_sceneText2.show();
- _object1.show();
- _object2.show();
+ _glyph.show();
+ _horizLine.show();
show();
}
void Scene125::Icon::hideIcon() {
_sceneText1.hide();
_sceneText2.hide();
- _object1.hide();
- _object2.hide();
+ _glyph.hide();
+ _horizLine.hide();
hide();
}
/*--------------------------------------------------------------------------*/
-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]) {
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
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;
@@ -613,29 +623,29 @@ Scene125::Scene125(): SceneExt() {
}
void Scene125::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(160);
+ SceneExt::postInit();
_palette.loadPalette(0);
if (R2_GLOBALS._sceneManager._previousScene != 125)
// Save the prior scene to return to when the console is turned off
- R2_GLOBALS._player._oldCharacterScene[1] = R2_GLOBALS._sceneManager._previousScene;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = R2_GLOBALS._sceneManager._previousScene;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
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));
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
+ _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,34 +666,34 @@ 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);
_icon1.setPosition(Common::Point(65, 17));
- _icon1._object2.postInit();
- _icon1._object2.setup(160, 7, 1);
- _icon1._object2.setPosition(Common::Point(106, 41));
+ _icon1._horizLine.postInit();
+ _icon1._horizLine.setup(160, 7, 1);
+ _icon1._horizLine.setPosition(Common::Point(106, 41));
_icon2.setup(160, 1, 1);
_icon2.setPosition(Common::Point(80, 32));
- _icon2._object2.postInit();
- _icon2._object2.setup(160, 7, 2);
- _icon2._object2.setPosition(Common::Point(106, 56));
+ _icon2._horizLine.postInit();
+ _icon2._horizLine.setup(160, 7, 2);
+ _icon2._horizLine.setPosition(Common::Point(106, 56));
_icon3.setup(160, 1, 1);
_icon3.setPosition(Common::Point(65, 47));
- _icon3._object2.postInit();
- _icon3._object2.setup(160, 7, 1);
- _icon3._object2.setPosition(Common::Point(106, 71));
+ _icon3._horizLine.postInit();
+ _icon3._horizLine.setup(160, 7, 1);
+ _icon3._horizLine.setPosition(Common::Point(106, 71));
_icon4.setup(160, 1, 1);
_icon4.setPosition(Common::Point(80, 62));
_icon4._sceneRegionId = 5;
- _icon4._object2.postInit();
- _icon4._object2.setup(160, 7, 2);
- _icon4._object2.setPosition(Common::Point(106, 86));
+ _icon4._horizLine.postInit();
+ _icon4._horizLine.setup(160, 7, 2);
+ _icon4._horizLine.setPosition(Common::Point(106, 86));
_icon5.postInit();
_icon5.setup(160, 1, 1);
@@ -698,24 +708,27 @@ 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:
- switch (_consoleMode) {
+ switch (_consoleMode) {
case 12:
_sceneMode = 129;
- _object1.postInit();
- _object2.postInit();
- _object3.postInit();
+ _starchart1.postInit();
+ _starchart2.postInit();
+ _starchart3.postInit();
if (R2_GLOBALS.getFlag(13)) {
- _object4.postInit();
- setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_object1, &_object2,
- &_object3, &_object4, NULL);
+ // Show starchart with Ringworld present
+ _starchart4.postInit();
+ setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_starchart1, &_starchart2,
+ &_starchart3, &_starchart4, NULL);
} else {
- setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_object1, &_object2, &_object3, NULL);
+ // Show starchart without Ringworld
+ setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_starchart1, &_starchart2,
+ &_starchart3, NULL);
}
break;
case 13:
@@ -772,7 +785,7 @@ void Scene125::signal() {
case 12:
if (_soundCount > 0)
--_soundCount;
- if (!_soundCount || (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ if (!_soundCount || !(R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
_soundIndex = 0;
R2_GLOBALS._playStream.stop();
} else {
@@ -781,11 +794,12 @@ void Scene125::signal() {
}
break;
case 125:
- R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[1]);
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[R2_QUINN]);
+ 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;
@@ -831,7 +845,7 @@ void Scene125::process(Event &event) {
void Scene125::dispatch() {
if (_soundCount)
- R2_GLOBALS._playStream.proc1();
+ R2_GLOBALS._playStream.dispatch();
Scene::dispatch();
}
@@ -882,7 +896,7 @@ void Scene125::consoleAction(int id) {
_icon2.setIcon(23);
break;
case 6:
- R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldCharacterScene[1]);
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldCharacterScene[R2_QUINN]);
break;
case 7:
if (_consoleMode == 11)
@@ -915,7 +929,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -945,7 +959,7 @@ void Scene125::consoleAction(int id) {
break;
case 13:
consoleAction(2);
- if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldCharacterScene[1]) {
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
SceneItem::display2(126, 17);
} else {
R2_GLOBALS._player.disableControl();
@@ -958,7 +972,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -970,14 +984,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 +1003,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._v565F5;
+ ++R2_GLOBALS._foodCount;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 15);
}
@@ -1000,13 +1020,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._foodCount;
- ++R2_GLOBALS._v565F5;
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 16);
}
@@ -1033,7 +1056,7 @@ void Scene125::consoleAction(int id) {
break;
case 24:
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
if (_consoleMode == 10) {
setDetails(127, --_logIndex);
@@ -1045,7 +1068,7 @@ void Scene125::consoleAction(int id) {
break;
case 25:
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
if (_consoleMode == 10) {
setDetails(127, ++_logIndex);
@@ -1063,10 +1086,10 @@ void Scene125::consoleAction(int id) {
_icon4.hideIcon();
R2_GLOBALS._player.hide();
- _object1.hide();
- _object2.hide();
- _object3.hide();
- _object4.hide();
+ _starchart1.hide();
+ _starchart2.hide();
+ _starchart3.hide();
+ _starchart4.hide();
_sceneMode = 11;
_palette.loadPalette(160);
@@ -1089,7 +1112,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -1149,7 +1172,7 @@ void Scene125::setDetails(int resNum, int lineNum) {
if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
_sceneMode = 12;
- R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this);
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex++], this);
}
} else {
// Passed the start or end of the message set, so return to the menu
@@ -1203,8 +1226,8 @@ Common::String Scene125::parseMessage(const Common::String &msg) {
*--------------------------------------------------------------------------*/
void Scene150::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(100);
+ SceneExt::postInit();
_door.postInit();
_door._state = 0;
@@ -1410,8 +1433,9 @@ Scene160::Scene160(): SceneExt() {
}
void Scene160::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(4001);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
R2_GLOBALS._player._uiEnabled = false;
R2_GLOBALS._player.enableControl();
@@ -1432,6 +1456,8 @@ void Scene160::synchronize(Serializer &s) {
s.syncAsSint16LE(_frameNumber);
s.syncAsSint16LE(_yChange);
s.syncAsSint16LE(_lineNum);
+
+ _creditsList.synchronize(s);
}
void Scene160::remove() {
@@ -1470,14 +1496,14 @@ void Scene180::Action1::signal() {
case 0:
case 1:
case 2:
- scene->_object5.setStrip((_actionIndex == 1) ? 1 : 2);
- scene->_object5.setFrame(1);
- scene->_object5.animate(ANIM_MODE_5, this);
+ scene->_shipDisplay.setStrip((_actionIndex == 1) ? 1 : 2);
+ scene->_shipDisplay.setFrame(1);
+ scene->_shipDisplay.animate(ANIM_MODE_5, this);
break;
case 4:
- scene->_object5.setStrip(3);
- scene->_object5.setFrame(1);
- scene->_object5.animate(ANIM_MODE_5, this);
+ scene->_shipDisplay.setStrip(3);
+ scene->_shipDisplay.setFrame(1);
+ scene->_shipDisplay.animate(ANIM_MODE_5, this);
_actionIndex = 0;
break;
}
@@ -1485,12 +1511,10 @@ void Scene180::Action1::signal() {
/*--------------------------------------------------------------------------*/
-Scene180::Scene180(): SceneExt(), _webbsterSpeaker(27) {
- _field412 = 0;
+Scene180::Scene180(): SceneExt() {
+ _helpEnabled = false;
_frameInc = 0;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
- _field480 = 1;
- _field482 = -1;
_fontNumber = R2_GLOBALS.gfxManager()._font._fontNumber;
GfxFont font;
@@ -1521,6 +1545,9 @@ void Scene180::remove() {
// _stripManager._field2EA = -1;
SceneExt::remove();
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 255, 255, 255);
+
R2_GLOBALS._events.setCursor(CURSOR_WALK);
// word_575F7 = 0;
R2_GLOBALS._playStream.stop();
@@ -1532,9 +1559,7 @@ void Scene180::synchronize(Serializer &s) {
SceneExt::synchronize(s);
s.syncAsSint16LE(_frameNumber);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field480);
- s.syncAsSint16LE(_field482);
+ s.syncAsSint16LE(_helpEnabled);
s.syncAsSint16LE(_frameInc);
s.syncAsSint16LE(_fontNumber);
s.syncAsSint16LE(_fontHeight);
@@ -1549,11 +1574,11 @@ void Scene180::signal() {
break;
case 1:
- _field412 = 1;
+ _helpEnabled = true;
R2_GLOBALS._sceneManager._hasPalette = true;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._isActive = true;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 1;
_animationPlayer.load(1);
@@ -1587,7 +1612,8 @@ void Scene180::signal() {
case 30:
case 43:
case 47:
- _field412 = 0;
+ _helpEnabled = false;
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
_palette.loadPalette(0);
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
@@ -1595,12 +1621,12 @@ void Scene180::signal() {
case 5:
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._isActive = true;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 2;
_animationPlayer.load(2);
- _field412 = 1;
+ _helpEnabled = true;
R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL);
R2_GLOBALS._sound1.play(2);
break;
@@ -1637,10 +1663,10 @@ void Scene180::signal() {
break;
case 11:
- _field412 = 1;
- _object4.postInit();
- _object5.postInit();
- setAction(&_sequenceManager, this, 4000, &_object4, &_object5, NULL);
+ _helpEnabled = true;
+ _door.postInit();
+ _shipDisplay.postInit();
+ setAction(&_sequenceManager, this, 4000, &_door, &_shipDisplay, NULL);
break;
case 12:
@@ -1656,52 +1682,52 @@ void Scene180::signal() {
break;
case 13:
- setAction(&_sequenceManager, this, 4001, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4001, &_door, &_shipDisplay, NULL);
break;
case 15:
- setAction(&_sequenceManager, this, 4002, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4002, &_door, &_shipDisplay, NULL);
break;
case 17:
- setAction(&_sequenceManager, this, 4003, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4003, &_door, &_shipDisplay, NULL);
break;
case 19:
- setAction(&_sequenceManager, this, 4004, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4004, &_door, &_shipDisplay, NULL);
break;
case 21:
- setAction(&_sequenceManager, this, 4005, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4005, &_door, &_shipDisplay, NULL);
break;
case 23:
- setAction(&_sequenceManager, this, 4006, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4006, &_door, &_shipDisplay, NULL);
break;
case 25:
- setAction(&_sequenceManager, this, 4007, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4007, &_door, &_shipDisplay, NULL);
break;
case 27:
- _field412 = 0;
- _object4.remove();
- _object5.remove();
+ _helpEnabled = false;
+ _door.remove();
+ _shipDisplay.remove();
setSceneDelay(2);
break;
case 28:
- _field412 = 0;
+ _helpEnabled = false;
_palette.loadPalette(0);
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 100, this);
break;
case 29:
- _field412 = 1;
+ _helpEnabled = true;
_animationPlayer._paletteMode = ANIMPALMODE_REPLACE_PALETTE;
- _animationPlayer._v = 1;
- _animationPlayer._objectMode = 42;
+ _animationPlayer._isActive = true;
+ _animationPlayer._objectMode = ANIMOBJMODE_42;
R2_GLOBALS._scene180Mode = 3;
_animationPlayer.load(3);
break;
@@ -1709,12 +1735,12 @@ void Scene180::signal() {
case 31:
R2_GLOBALS._sound2.play(7);
- _object4.postInit();
- _object4.setVisage(76);
- _object4.setStrip(1);
- _object4.setFrame(1);
- _object4.setPosition(Common::Point(288, 143));
- _object4.fixPriority(210);
+ _door.postInit();
+ _door.setVisage(76);
+ _door.setStrip(1);
+ _door.setFrame(1);
+ _door.setPosition(Common::Point(288, 143));
+ _door.fixPriority(210);
loadScene(75);
@@ -1727,70 +1753,71 @@ void Scene180::signal() {
break;
case 32:
- _field412 = 1;
+ _helpEnabled = true;
- _object2.postInit();
- _object2.setPosition(Common::Point(161, 97));
- _object2.hide();
+ _teal.postInit();
+ _teal.setPosition(Common::Point(161, 97));
+ _teal.hide();
- _object3.postInit();
- _object3.setPosition(Common::Point(60, 96));
- _object3.hide();
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 11, this);
+ _webbster.postInit();
+ _webbster.setPosition(Common::Point(60, 96));
+ _webbster.hide();
+ _stripManager.start(11, this);
break;
case 33:
- _object2.hide();
+ _teal.hide();
- _object3.setup(76, 4, 1);
- _object3.setFrame(_object3.getFrameCount());
+ _webbster.setup(76, 4, 1);
+ _webbster.setFrame(_webbster.getFrameCount());
- _object5.postInit();
- _object5.setup(75, 1, 1);
- _object5.setPosition(Common::Point(221, 125));
- _object5.fixPriority(210);
- _object5.setAction(&_action1);
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 12, this);
+ _shipDisplay.postInit();
+ _shipDisplay.setup(75, 1, 1);
+ _shipDisplay.setPosition(Common::Point(221, 125));
+ _shipDisplay.fixPriority(210);
+ _shipDisplay.setAction(&_action1);
+ _stripManager.start(12, this);
break;
case 34:
- _object2.hide();
- _object3.hide();
+ _teal.hide();
+ _webbster.remove();
- _object1.postInit();
- _object1.setup(76, 2, 1);
- _object1.setPosition(Common::Point(287, 135));
- _object1.fixPriority(200);
+ _dutyOfficer.postInit();
+ _dutyOfficer.setup(76, 2, 1);
+ _dutyOfficer.setPosition(Common::Point(287, 135));
+ _dutyOfficer.fixPriority(200);
_sound1.play(19);
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ _door.animate(ANIM_MODE_5, this);
break;
case 35:
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 13, this);
+ _stripManager.start(13, this);
break;
case 36:
- _object2.remove();
+ _teal.remove();
_sound1.play(19);
-
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 6, this);
+ _door.animate(ANIM_MODE_6, this);
break;
case 37:
- _field412 = 0;
- _object1.remove();
+ _helpEnabled = false;
+ _dutyOfficer.remove();
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
break;
case 38:
- _object4.remove();
- _object5.setAction(NULL);
- _object5.remove();
+ _door.remove();
+ _shipDisplay.setAction(NULL);
+ _shipDisplay.remove();
+ _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
R2_GLOBALS._sound2.fadeOut2(NULL);
- R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(this);
break;
case 39:
@@ -1800,7 +1827,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();
@@ -1812,8 +1839,8 @@ void Scene180::signal() {
break;
case 41:
- _field412 = 1;
- _animationPlayer._v = 1;
+ _helpEnabled = true;
+ _animationPlayer._isActive = true;
break;
case 42:
@@ -1832,14 +1859,15 @@ void Scene180::signal() {
break;
case 45:
- R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 28, this);
+ _helpEnabled = true;
+ _stripManager.start(28, this);
break;
case 48:
- _field412 = 1;
+ _helpEnabled = true;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
- _animationPlayer._objectMode = 1;
+ _animationPlayer._isActive = true;
+ _animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 15;
_animationPlayer.load(15, NULL);
@@ -1850,13 +1878,21 @@ void Scene180::signal() {
case 49:
R2_GLOBALS._scene180Mode = 15;
R2_GLOBALS._paneRefreshFlag[0] = 3;
+
+ _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+
setSceneDelay(1);
break;
case 50:
R2_GLOBALS._scene180Mode = 0;
- _field412 = 0;
- R2_GLOBALS._sceneManager.changeScene(100);
+ _helpEnabled = false;
+
+ // WORKAROUND: The original changed to scene 100 here, Quinn's Bedroom,
+ // but instead we're changing to the previously unused scene 50, which shows
+ // a closeup of Quinn in the floatation bed first
+ R2_GLOBALS._sceneManager.changeScene(50);
break;
}
}
@@ -1868,11 +1904,10 @@ void Scene180::setSceneDelay(int v) {
void Scene180::process(Event &event) {
if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- event.handled = 1;
- if (!_field412) {
- if (R2_GLOBALS._scenePalette._listeners.size() == 0) {
+ event.handled = true;
+ if (_helpEnabled) {
+ if (R2_GLOBALS._scenePalette._listeners.size() == 0)
HelpDialog::show();
- }
}
}
@@ -1895,9 +1930,9 @@ void Scene180::dispatch() {
}
}
- if (_animationPlayer._v) {
+ if (_animationPlayer._isActive) {
if (_animationPlayer.isCompleted()) {
- _animationPlayer._v = 0;
+ _animationPlayer._isActive = false;
_animationPlayer.close();
_animationPlayer.remove();
@@ -1923,7 +1958,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 +1967,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 +1977,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 +1986,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 +1996,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:
@@ -1981,9 +2016,9 @@ void Scene180::restore() {
*--------------------------------------------------------------------------*/
bool Scene200::NorthDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 202;
scene->setAction(&scene->_sequenceManager, scene, 202, &R2_GLOBALS._player, this, NULL);
@@ -1994,9 +2029,9 @@ bool Scene200::NorthDoor::startAction(CursorType action, Event &event) {
}
bool Scene200::EastDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 200;
scene->setAction(&scene->_sequenceManager, scene, 200, &R2_GLOBALS._player, this, NULL);
@@ -2007,9 +2042,9 @@ bool Scene200::EastDoor::startAction(CursorType action, Event &event) {
}
bool Scene200::WestDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 204;
scene->setAction(&scene->_sequenceManager, scene, 204, &R2_GLOBALS._player, this, NULL);
@@ -2025,7 +2060,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 +2069,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 +2077,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 +2346,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;
@@ -2332,11 +2354,21 @@ Scene205::Scene205(): SceneExt() {
GfxFont font;
font.setFontNumber(4);
_fontHeight = font.getHeight();
+
+ for (int i = 0; i < 3; i++) {
+ _starList1[i] = nullptr;
+ _starList2[i] = nullptr;
+ }
+
+ for (int i = 0; i < 4; i++)
+ _starList3[i] = nullptr;
}
void Scene205::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(4000);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player._uiEnabled = false;
R2_GLOBALS._sound1.play(337);
@@ -2351,11 +2383,11 @@ void Scene205::synchronize(Serializer &s) {
SceneExt::synchronize(s);
for (int idx = 0; idx < 3; ++idx)
- SYNC_POINTER(_objList1[idx]);
+ SYNC_POINTER(_starList1[idx]);
for (int idx = 0; idx < 3; ++idx)
- SYNC_POINTER(_objList2[idx]);
+ SYNC_POINTER(_starList2[idx]);
for (int idx = 0; idx < 4; ++idx)
- SYNC_POINTER(_objList3[idx]);
+ SYNC_POINTER(_starList3[idx]);
s.syncAsSint16LE(_textIndex);
s.syncAsSint16LE(_lineNum);
@@ -2377,9 +2409,9 @@ void Scene205::process(Event &event) {
}
void Scene205::dispatch() {
- processList(_objList3, 4, Common::Rect(0, 0, 319, 200), 1, 1, 160, 100);
- processList(_objList2, 3, Common::Rect(0, 0, 319, 200), 2, 2, 160, 100);
- processList(_objList1, 3, Common::Rect(0, 0, 319, 200), 4, 3, 160, 100);
+ processList(_starList3, 4, Common::Rect(0, 0, 319, 200), 1, 1, 160, 100);
+ processList(_starList2, 3, Common::Rect(0, 0, 319, 200), 2, 2, 160, 100);
+ processList(_starList1, 3, Common::Rect(0, 0, 319, 200), 4, 3, 160, 100);
Scene::dispatch();
}
@@ -2391,10 +2423,10 @@ void Scene205::setup() {
Common::Point(140, 149), Common::Point(91, 166), Common::Point(299, 46), Common::Point(314, 10)
};
- // Set up the first object list
+ // Set up the first star list
for (int idx = 0; idx < 3; ++idx) {
- Object *obj = new Object();
- _objList1[idx] = obj;
+ Star *obj = new Star();
+ _starList1[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2407,10 +2439,10 @@ void Scene205::setup() {
obj->fixPriority(12);
}
- // Setup the second object list
+ // Setup the second star list
for (int idx = 0; idx < 3; ++idx) {
- Object *obj = new Object();
- _objList2[idx] = obj;
+ Star *obj = new Star();
+ _starList2[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2423,10 +2455,10 @@ void Scene205::setup() {
obj->fixPriority(11);
}
- // Setup the third object list
+ // Setup the third star list
for (int idx = 0; idx < 4; ++idx) {
- Object *obj = new Object();
- _objList3[idx] = obj;
+ Star *obj = new Star();
+ _starList3[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2443,10 +2475,10 @@ void Scene205::setup() {
/**
* Handles moving a group of stars in the scene background
*/
-void Scene205::processList(Object **ObjList, int count, const Common::Rect &bounds,
+void Scene205::processList(Star **ObjList, int count, const Common::Rect &bounds,
int xMultiply, int yMultiply, int xCenter, int yCenter) {
for (int idx = 0; idx < count; ++idx) {
- Object *obj = ObjList[idx];
+ Star *obj = ObjList[idx];
Common::Point pt(obj->_position.x - xCenter, obj->_position.y - yCenter);
if ((obj->_position.x <= 319) && (obj->_position.x >= 0) &&
@@ -2492,22 +2524,21 @@ 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) {
- Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
- if (scene->_field414) {
+ case CURSOR_USE: {
+ Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_destButtonY) {
SceneItem::display2(250, 15);
} else {
switch (_floorNumber) {
@@ -2529,6 +2560,7 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
}
}
return true;
+ }
case CURSOR_LOOK:
switch (_floorNumber) {
@@ -2558,7 +2590,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 +2614,25 @@ 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);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
@@ -2610,12 +2644,12 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
_currentFloor.setup(250, 1, 5);
_currentFloor.setDetails(250, 13, -1, -1, 1, (SceneItem *)NULL);
- _button1.setFloor(11);
- _button1.setup(250, 1, 3);
- _button1.setPosition(Common::Point(400, 100));
- _button1.setDetails(250, 14, -1, -1, 1, (SceneItem *)NULL);
- _button1.fixPriority(190);
- _button1.hide();
+ _destinationFloor.setFloor(11);
+ _destinationFloor.setup(250, 1, 3);
+ _destinationFloor.setPosition(Common::Point(400, 100));
+ _destinationFloor.setDetails(250, 14, -1, -1, 1, (SceneItem *)NULL);
+ _destinationFloor.fixPriority(190);
+ _destinationFloor.hide();
_floor1.setFloor(1);
_floor2.setFloor(2);
@@ -2627,36 +2661,36 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
_floor8.setFloor(8);
_floor9.setFloor(9);
- _item2.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL);
- _item4.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL);
+ _door.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL);
+ _directionIndicator.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 250, 0, 1, -1, 1, NULL);
R2_GLOBALS._events.setCursor(CURSOR_USE);
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 +2701,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 +2740,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 +2773,7 @@ void Scene250::signal() {
break;
case 20:
// Handle changing scene
- switch (_field414) {
+ switch (_destButtonY) {
case 55:
R2_GLOBALS._sceneManager.changeScene(200);
break;
@@ -2741,7 +2781,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 +2796,13 @@ void Scene250::signal() {
}
void Scene250::changeFloor(int floorNumber) {
- _field414 = (floorNumber - 1) * 12 + 43;
- _button1.setPosition(Common::Point(111, _field414));
- _button1.show();
+ _destButtonY = (floorNumber - 1) * 12 + 43;
+ _destinationFloor.setPosition(Common::Point(111, _destButtonY));
+ _destinationFloor.show();
- _sceneMode = (_field412 >= _field414) ? 6 : 1;
- if (_field414 == _field412)
+ _skippableFl = true;
+ _sceneMode = (_currButtonY >= _destButtonY) ? 6 : 1;
+ if (_destButtonY == _currButtonY)
_sceneMode = 20;
signal();
@@ -2769,8 +2810,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 +2822,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;
}
}
@@ -2802,12 +2843,12 @@ void Scene300::Action1::signal() {
switch (_actionIndex) {
case 0:
- setAction(&scene->_sequenceManager2, this, 311, (R2_GLOBALS._player._characterIndex == 1) ?
+ setAction(&scene->_sequenceManager2, this, 311, (R2_GLOBALS._player._characterIndex == R2_QUINN) ?
(SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn);
_actionIndex = 2;
break;
case 1:
- setAction(&scene->_sequenceManager2, this, 312, (R2_GLOBALS._player._characterIndex == 1) ?
+ setAction(&scene->_sequenceManager2, this, 312, (R2_GLOBALS._player._characterIndex == R2_QUINN) ?
(SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn);
_actionIndex = 0;
break;
@@ -2868,14 +2909,14 @@ void Scene300::Action3::signal() {
void Scene300::Action4::signal() {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
if (!R2_GLOBALS._playStream.isPlaying()) {
- scene->_object7.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2));
- scene->_object7.setFrame(1);
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
- scene->_object9.setStrip2(3);
- scene->_object9.setFrame(1);
+ scene->_mirandaScreen.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2));
+ scene->_mirandaScreen.setFrame(1);
+
+ scene->_quinnScreen.setStrip2(3);
+ scene->_quinnScreen.setFrame(1);
}
setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(479));
@@ -2884,8 +2925,6 @@ void Scene300::Action4::signal() {
/*--------------------------------------------------------------------------*/
bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_USE:
if (R2_GLOBALS._player._characterIndex != 1)
@@ -2894,6 +2933,8 @@ bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._sceneManager.changeScene(325);
} else {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 306;
scene->setAction(&scene->_sequenceManager1, scene, 306, &R2_GLOBALS._player, NULL);
@@ -2901,7 +2942,7 @@ bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
return true;
case CURSOR_LOOK:
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
SceneItem::display2(300, 47);
return true;
}
@@ -2924,7 +2965,7 @@ bool Scene300::MirandaWorkstation::startAction(CursorType action, Event &event)
return true;
case CURSOR_LOOK:
- if (R2_GLOBALS._player._characterIndex == 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
SceneItem::display2(300, 47);
return true;
}
@@ -2940,7 +2981,7 @@ bool Scene300::MirandaWorkstation::startAction(CursorType action, Event &event)
bool Scene300::SeekerWorkstation::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
SceneItem::display2(300, 47);
return true;
}
@@ -2986,14 +3027,14 @@ 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;
if (!R2_GLOBALS.getFlag(57)) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_stripManager.start3(434, scene, R2_GLOBALS._stripManager_lookupList);
- } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] != 500) {
+ } else if (R2_GLOBALS._player._characterScene[R2_SEEKER] != 500) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_stripManager.start3(407, scene, R2_GLOBALS._stripManager_lookupList);
} else {
@@ -3048,7 +3089,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 +3131,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:
@@ -3114,10 +3155,10 @@ bool Scene300::Seeker::startAction(CursorType action, Event &event) {
}
bool Scene300::Quinn::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_TALK:
+ case CURSOR_TALK: {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_sceneMode = 10;
@@ -3126,33 +3167,31 @@ bool Scene300::Quinn::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)
scene->_stripId = 442;
else if (!R2_GLOBALS.getFlag(44))
- scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2);
else if (!R2_GLOBALS.getFlag(55))
- scene->_stripId = 208;
+ scene->_stripId = 439;
else
- scene->_stripId = 441;
- } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) {
- scene->_stripId = 442;
+ scene->_stripId = 210;
} else if (R2_GLOBALS.getFlag(44)) {
- scene->_stripId = R2_GLOBALS.getFlag(55) ? 441 : 208;
+ scene->_stripId = R2_GLOBALS.getFlag(55) ? 439 : 210;
} else {
- scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2);
}
scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
return true;
-
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene300::Doorway::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
- (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) {
+ (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_SEEKER] == 500)) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 301;
scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
@@ -3171,6 +3210,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 +3223,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 +3234,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);
@@ -3206,75 +3247,75 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_rotation->_countdown = 1;
if (R2_GLOBALS.getFlag(51) && !R2_GLOBALS.getFlag(25)) {
- _object1.postInit();
- _object1.setup(301, 7, 2);
- _object1.setPosition(Common::Point(65, 24));
+ _atmosphereLeftWindow.postInit();
+ _atmosphereLeftWindow.setup(301, 7, 2);
+ _atmosphereLeftWindow.setPosition(Common::Point(65, 24));
- _object2.postInit();
- _object2.setup(301, 8, 2);
- _object2.setPosition(Common::Point(254, 24));
+ _atmosphereRightWindow.postInit();
+ _atmosphereRightWindow.setup(301, 8, 2);
+ _atmosphereRightWindow.setPosition(Common::Point(254, 24));
}
_doorway.postInit();
_doorway.setVisage(300);
_doorway.setPosition(Common::Point(159, 79));
- _object3.postInit();
- _object3.setup(300, 4, 1);
- _object3.setPosition(Common::Point(84, 48));
- _object3.animate(ANIM_MODE_2, NULL);
- _object3._numFrames = 5;
+ _leftVerticalBarsAnim.postInit();
+ _leftVerticalBarsAnim.setup(300, 4, 1);
+ _leftVerticalBarsAnim.setPosition(Common::Point(84, 48));
+ _leftVerticalBarsAnim.animate(ANIM_MODE_2, NULL);
+ _leftVerticalBarsAnim._numFrames = 5;
- _object4.postInit();
- _object4.setup(300, 5, 1);
- _object4.setPosition(Common::Point(236, 48));
- _object4.animate(ANIM_MODE_2, NULL);
+ _rightVerticalBarsAnim.postInit();
+ _rightVerticalBarsAnim.setup(300, 5, 1);
+ _rightVerticalBarsAnim.setPosition(Common::Point(236, 48));
+ _rightVerticalBarsAnim.animate(ANIM_MODE_2, NULL);
_protocolDisplay.postInit();
_protocolDisplay.setup(300, 6, 1);
_protocolDisplay.setPosition(Common::Point(287, 71));
- _protocolDisplay.animate(ANIM_MODE_7, NULL);
+ _protocolDisplay.animate(ANIM_MODE_7, 0, NULL);
_protocolDisplay._numFrames = 5;
- _object6.postInit();
- _object6.setup(300, 7, 1);
- _object6.setPosition(Common::Point(214, 37));
- _object6.animate(ANIM_MODE_2, NULL);
- _object6._numFrames = 3;
-
- _object7.postInit();
- _object7.setup(301, 1, 1);
- _object7.setPosition(Common::Point(39, 97));
- _object7.fixPriority(124);
- _object7.animate(ANIM_MODE_2, NULL);
- _object7._numFrames = 5;
- _object7.setAction(&_action4);
-
- _object8.postInit();
- _object8.setup(300, 8, 1);
- _object8.setPosition(Common::Point(105, 37));
- _object8.animate(ANIM_MODE_2, NULL);
- _object8._numFrames = 5;
-
- _object9.postInit();
- _object9.setup(301, 6, 1);
- _object9.setPosition(Common::Point(274, 116));
- _object9.fixPriority(143);
- _object9.animate(ANIM_MODE_2, NULL);
- _object9._numFrames = 5;
+ _rightTextDisplay.postInit();
+ _rightTextDisplay.setup(300, 7, 1);
+ _rightTextDisplay.setPosition(Common::Point(214, 37));
+ _rightTextDisplay.animate(ANIM_MODE_2, NULL);
+ _rightTextDisplay._numFrames = 3;
+
+ _mirandaScreen.postInit();
+ _mirandaScreen.setup(301, 1, 1);
+ _mirandaScreen.setPosition(Common::Point(39, 97));
+ _mirandaScreen.fixPriority(124);
+ _mirandaScreen.animate(ANIM_MODE_2, NULL);
+ _mirandaScreen._numFrames = 5;
+ _mirandaScreen.setAction(&_action4);
+
+ _leftTextDisplay.postInit();
+ _leftTextDisplay.setup(300, 8, 1);
+ _leftTextDisplay.setPosition(Common::Point(105, 37));
+ _leftTextDisplay.animate(ANIM_MODE_2, NULL);
+ _leftTextDisplay._numFrames = 5;
+
+ _quinnScreen.postInit();
+ _quinnScreen.setup(301, 6, 1);
+ _quinnScreen.setPosition(Common::Point(274, 116));
+ _quinnScreen.fixPriority(143);
+ _quinnScreen.animate(ANIM_MODE_2, NULL);
+ _quinnScreen._numFrames = 5;
_quinnWorkstation1.setDetails(Rect(243, 148, 315, 167), 300, 30, 31, 32, 1, NULL);
_mirandaWorkstation1.setDetails(Rect(4, 128, 69, 167), 300, 33, 31, 35, 1, NULL);
switch (R2_GLOBALS._player._characterIndex) {
- case 1:
+ case R2_QUINN:
_miranda.postInit();
_miranda.setup(302, 2, 1);
_miranda.setPosition(Common::Point(47, 128));
_miranda.setAction(&_action3);
_miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
- if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_SEEKER] == 300) || (R2_GLOBALS._player._characterScene[R2_SEEKER] == 325)) {
_seeker.postInit();
_seeker.setVisage(302);
_seeker.setPosition(Common::Point(158, 108));
@@ -3289,14 +3330,14 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
break;
- case 2:
+ case R2_SEEKER:
_miranda.postInit();
_miranda.setup(302, 2, 1);
_miranda.setPosition(Common::Point(47, 128));
_miranda.setAction(&_action3);
_miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
- if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == 300) || (R2_GLOBALS._player._characterScene[R2_QUINN] == 325)) {
_quinn.postInit();
_quinn.setup(302, 3, 1);
_quinn.setPosition(Common::Point(271, 150));
@@ -3309,10 +3350,11 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(158, 108));
R2_GLOBALS._player.fixPriority(130);
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
- case 3:
- if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ case R2_MIRANDA:
+ if ((R2_GLOBALS._player._characterScene[R2_SEEKER] == 300) || (R2_GLOBALS._player._characterScene[R2_SEEKER] == 325)) {
_seeker.postInit();
_seeker.setVisage(302);
_seeker.setPosition(Common::Point(158, 108));
@@ -3321,7 +3363,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_seeker.setDetails(300, 42, 43, 44, 1, (SceneItem *)NULL);
}
- if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == 300) || (R2_GLOBALS._player._characterScene[R2_QUINN] == 325)) {
_quinn.postInit();
_quinn.setup(302, 3, 1);
_quinn.setPosition(Common::Point(271, 150));
@@ -3333,6 +3375,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setup(302, 2, 1);
R2_GLOBALS._player.setPosition(Common::Point(47, 128));
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
default:
@@ -3365,7 +3408,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 +3445,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);
}
@@ -3445,9 +3490,9 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
case 3:
if (R2_GLOBALS._sceneManager._previousScene == 1500) {
- R2_GLOBALS._player._oldCharacterScene[3] = 3150;
- R2_GLOBALS._player._characterScene[3] = 3150;
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3150;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._player.disableControl();
@@ -3484,27 +3529,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:
- if (R2_GLOBALS._stripManager_lookupList[1] == 6)
+ case 5:
+ if (R2_GLOBALS._stripManager_lookupList[0] == 6)
R2_GLOBALS.setFlag(40);
break;
- case 5:
+ case 6:
R2_GLOBALS._sceneManager.changeScene(1000);
break;
default:
@@ -3565,7 +3610,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,13 +3669,15 @@ 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;
case 313:
_sceneMode = 14;
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
_seeker.setAction(&_sequenceManager3, this, 314, &_seeker, &_doorway, NULL);
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(301, this);
@@ -3639,7 +3686,7 @@ void Scene300::signal() {
case 314:
R2_GLOBALS._player.disableControl();
_sceneMode = 315;
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
setAction(&_sequenceManager1, this, 315, &R2_GLOBALS._player, &_doorway, NULL);
break;
@@ -3648,9 +3695,9 @@ void Scene300::signal() {
break;
case 316:
- R2_GLOBALS._player._characterScene[2] = 500;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 500;
_seeker.remove();
- R2_GLOBALS._player.enableControl(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 317:
@@ -3671,6 +3718,8 @@ void Scene300::signal() {
}
void Scene300::signal309() {
+ // Sets up what conversation items will be available when to talking to the
+ // others on the Bridge, and will be set dependent on game flags
if (R2_GLOBALS.getFlag(2))
R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_READER) == 1) ? 3 : 2;
@@ -3720,16 +3769,16 @@ const double ADJUST_FACTOR = 0.06419999999999999;
Scene325::Icon::Icon(): SceneActor() {
_lookLineNum = 0;
- _field98 = 0;
+ _iconId = 0;
_pressed = false;
}
void Scene325::Icon::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
- _object1.postInit();
- _object1.fixPriority(21);
- _object1.hide();
+ _glyph.postInit();
+ _glyph.fixPriority(21);
+ _glyph.hide();
_sceneText1._color1 = 92;
_sceneText1._color2 = 0;
@@ -3743,7 +3792,7 @@ void Scene325::Icon::postInit(SceneObjectList *OwnerList) {
void Scene325::Icon::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_pressed);
}
@@ -3768,18 +3817,18 @@ void Scene325::Icon::process(Event &event) {
scene->_sound1.play(14);
setFrame(2);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 1:
- _object1.setStrip(2);
+ _glyph.setStrip(2);
break;
case 3:
- _object1.setStrip(4);
+ _glyph.setStrip(4);
break;
case 5:
- _object1.setStrip(6);
+ _glyph.setStrip(6);
break;
case 7:
- _object1.setStrip(8);
+ _glyph.setStrip(8);
break;
default:
break;
@@ -3798,15 +3847,15 @@ void Scene325::Icon::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
setFrame(1);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 2:
- _object1.setStrip(1);
+ _glyph.setStrip(1);
break;
case 4:
- _object1.setStrip(3);
+ _glyph.setStrip(3);
break;
case 6:
- _object1.setStrip(5);
+ _glyph.setStrip(5);
break;
default:
break;
@@ -3820,18 +3869,18 @@ void Scene325::Icon::process(Event &event) {
}
void Scene325::Icon::setIcon(int id) {
- Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
-
- _lookLineNum = _field98 = id;
+ _lookLineNum = _iconId = id;
SceneActor::_lookLineNum = id;
_sceneText1.remove();
_sceneText2.remove();
if (_lookLineNum) {
+ Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
+
showIcon();
- _object1.setup(325, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
- _object1.setPosition(_position);
+ _glyph.setup(325, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _glyph.setPosition(_position);
_sceneText1._fontNumber = scene->_iconFontNumber;
_sceneText1.setup(CONSOLE325_MESSAGES[id]);
@@ -3872,26 +3921,26 @@ void Scene325::Icon::setIcon(int id) {
void Scene325::Icon::showIcon() {
_sceneText1.show();
_sceneText2.show();
- _object1.show();
- _object2.show();
+ _glyph.show();
+ _horizLine.show();
show();
}
void Scene325::Icon::hideIcon() {
_sceneText1.hide();
_sceneText2.hide();
- _object1.hide();
- _object2.hide();
+ _glyph.hide();
+ _horizLine.hide();
hide();
}
/*--------------------------------------------------------------------------*/
Scene325::Scene325(): SceneExt() {
- _field412 = 7;
+ _consoleAction = 7;
_iconFontNumber = 50;
- _field416 = _field418 = 0;
- _field41A = _field41C = _field41E = _field420 = 0;
+ _databasePage = _priorConsoleAction = 0;
+ _moveCounter = _yChange = _yDirection = _scannerLocation = 0;
_soundCount = _soundIndex = 0;
for (int idx = 0; idx < 10; ++idx)
@@ -3899,8 +3948,8 @@ Scene325::Scene325(): SceneExt() {
}
void Scene325::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(325);
+ SceneExt::postInit();
R2_GLOBALS.clearFlag(50);
_stripManager.addSpeaker(&_quinnSpeaker);
@@ -3910,7 +3959,7 @@ void Scene325::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _item2.setDetails(1, 325, 3, 4, 5);
+ _terminal.setDetails(1, 325, 3, 4, 5);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 325, 0, 1, 2, 1, (SceneItem *)NULL);
_sceneMode = 1;
signal();
@@ -3919,14 +3968,14 @@ void Scene325::postInit(SceneObjectList *OwnerList) {
void Scene325::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_consoleAction);
s.syncAsSint16LE(_iconFontNumber);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
- s.syncAsSint16LE(_field41C);
- s.syncAsSint16LE(_field41E);
- s.syncAsSint16LE(_field420);
+ s.syncAsSint16LE(_databasePage);
+ s.syncAsSint16LE(_priorConsoleAction);
+ s.syncAsSint16LE(_moveCounter);
+ s.syncAsSint16LE(_yChange);
+ s.syncAsSint16LE(_yDirection);
+ s.syncAsSint16LE(_scannerLocation);
s.syncAsSint16LE(_soundCount);
s.syncAsSint16LE(_soundIndex);
@@ -3958,28 +4007,28 @@ void Scene325::signal() {
case 1:
_icon1.setup(160, 1, 1);
_icon1.setPosition(Common::Point(65, 17));
- _icon1._object2.postInit();
- _icon1._object2.setup(160, 7, 1);
- _icon1._object2.setPosition(Common::Point(106, 41));
+ _icon1._horizLine.postInit();
+ _icon1._horizLine.setup(160, 7, 1);
+ _icon1._horizLine.setPosition(Common::Point(106, 41));
_icon2.setup(160, 1, 1);
_icon2.setPosition(Common::Point(80, 32));
- _icon2._object2.postInit();
- _icon2._object2.setup(160, 7, 2);
- _icon2._object2.setPosition(Common::Point(106, 56));
+ _icon2._horizLine.postInit();
+ _icon2._horizLine.setup(160, 7, 2);
+ _icon2._horizLine.setPosition(Common::Point(106, 56));
_icon3.setup(160, 1, 1);
_icon3.setPosition(Common::Point(65, 47));
- _icon3._object2.postInit();
- _icon3._object2.setup(160, 7, 1);
- _icon3._object2.setPosition(Common::Point(106, 71));
+ _icon3._horizLine.postInit();
+ _icon3._horizLine.setup(160, 7, 1);
+ _icon3._horizLine.setPosition(Common::Point(106, 71));
_icon4.setup(160, 1, 1);
_icon4.setPosition(Common::Point(80, 62));
_icon4._sceneRegionId = 5;
- _icon4._object2.postInit();
- _icon4._object2.setup(160, 7, 2);
- _icon4._object2.setPosition(Common::Point(106, 86));
+ _icon4._horizLine.postInit();
+ _icon4._horizLine.setup(160, 7, 2);
+ _icon4._horizLine.setPosition(Common::Point(106, 86));
_icon5.postInit();
_icon5.setup(160, 1, 1);
@@ -3998,160 +4047,165 @@ void Scene325::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 9:
- switch (_field412) {
+ // Fade to black for console sub-section: database, or starchart
+ switch (_consoleAction) {
case 3:
+ // Starchart
_sceneMode = 129;
- _object1.postInit();
- _object2.postInit();
- _object3.postInit();
+ _starGrid1.postInit();
+ _starGrid2.postInit();
+ _starGrid3.postInit();
if (R2_GLOBALS.getFlag(13)) {
- _object4.postInit();
- setAction(&_sequenceManager1, this, 130, &R2_GLOBALS._player, &_object1,
- &_object2, &_object3, &_object4, NULL);
+ // Show starchart with Ringworld present
+ _starGrid4.postInit();
+ setAction(&_sequenceManager1, this, 130, &R2_GLOBALS._player, &_starGrid1,
+ &_starGrid2, &_starGrid3, &_starGrid4, NULL);
} else {
- setAction(&_sequenceManager1, this, 129, &R2_GLOBALS._player, &_object1,
- &_object2, &_object3, NULL);
+ // Show starchart without Ringworld
+ setAction(&_sequenceManager1, this, 129, &R2_GLOBALS._player, &_starGrid1,
+ &_starGrid2, &_starGrid3, NULL);
}
break;
case 17:
case 18:
case 19:
case 20: {
- int v = 10 - ((21 - _field412) * 2);
+ int v = 10 - ((21 - _consoleAction) * 2);
if (R2_GLOBALS.getFlag(50))
--v;
- if (_field418 == 5)
+ if (_priorConsoleAction == 5)
v += 8;
if (R2_GLOBALS.getFlag(51) && (v == 2))
R2_GLOBALS.setFlag(57);
if (R2_GLOBALS.getFlag(44) && !R2_GLOBALS.getFlag(51)) {
if (v != 13) {
- setMessage(328, 0);
+ setMessage(328, v);
} else {
- _field420 = 864;
-
- _object12.postInit();
- _object2.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);
-
- _object10.postInit();
- _object10.setup(326, 1, 1);
- _object10.setPosition(Common::Point(210, 20));
- _object10.fixPriority(10);
-
- _object1.postInit();
- _object1.setup(326, 1, 1);
- _object1.setPosition(Common::Point(210, 32));
- _object10.fixPriority(10);
-
- _object2.postInit();
- _object2.setup(326, 1, 1);
- _object2.setPosition(Common::Point(210, 44));
- _object2.fixPriority(10);
-
- _object3.postInit();
- _object3.setup(326, 1, 1);
- _object3.setPosition(Common::Point(210, 56));
- _object3.fixPriority(10);
-
- _object4.postInit();
- _object4.setup(326, 1, 1);
- _object4.setPosition(Common::Point(210, 68));
- _object4.fixPriority(10);
-
- _object5.postInit();
- _object5.setup(326, 1, 1);
- _object5.setPosition(Common::Point(210, 80));
- _object5.fixPriority(10);
-
- _object6.postInit();
- _object6.setup(326, 1, 1);
- _object6.setPosition(Common::Point(210, 92));
- _object6.fixPriority(10);
-
- _object7.postInit();
- _object7.setup(326, 1, 1);
- _object7.setPosition(Common::Point(210, 104));
- _object7.fixPriority(10);
-
- _object8.postInit();
- _object8.setup(326, 1, 1);
- _object8.setPosition(Common::Point(210, 116));
- _object8.fixPriority(10);
-
- _object9.postInit();
- _object9.setup(326, 1, 1);
- _object9.setPosition(Common::Point(210, 128));
- _object9.fixPriority(10);
-
- _object11.postInit();
- _object11.setup(326, 1, 1);
- _object11.setPosition(Common::Point(210, 150));
- _object11.fixPriority(10);
+ _scannerLocation = 864;
+
+ _starGrid12.postInit();
+ _starGrid12.setup(326, 4, 1);
+ _starGrid12.setPosition(Common::Point(149, 128));
+ _starGrid12.fixPriority(20);
+
+ _starGrid13.postInit();
+ _starGrid13.setup(326, 4, 2);
+ _starGrid13.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
+ _starGrid13.fixPriority(21);
+
+ _starGrid10.postInit();
+ _starGrid10.setup(326, 1, 1);
+ _starGrid10.setPosition(Common::Point(210, 20));
+ _starGrid10.fixPriority(10);
+
+ _starGrid1.postInit();
+ _starGrid1.setup(326, 1, 1);
+ _starGrid1.setPosition(Common::Point(210, 32));
+ _starGrid1.fixPriority(10);
+
+ _starGrid2.postInit();
+ _starGrid2.setup(326, 1, 1);
+ _starGrid2.setPosition(Common::Point(210, 44));
+ _starGrid2.fixPriority(10);
+
+ _starGrid3.postInit();
+ _starGrid3.setup(326, 1, 1);
+ _starGrid3.setPosition(Common::Point(210, 56));
+ _starGrid3.fixPriority(10);
+
+ _starGrid4.postInit();
+ _starGrid4.setup(326, 1, 1);
+ _starGrid4.setPosition(Common::Point(210, 68));
+ _starGrid4.fixPriority(10);
+
+ _starGrid5.postInit();
+ _starGrid5.setup(326, 1, 1);
+ _starGrid5.setPosition(Common::Point(210, 80));
+ _starGrid5.fixPriority(10);
+
+ _starGrid6.postInit();
+ _starGrid6.setup(326, 1, 1);
+ _starGrid6.setPosition(Common::Point(210, 92));
+ _starGrid6.fixPriority(10);
+
+ _starGrid7.postInit();
+ _starGrid7.setup(326, 1, 1);
+ _starGrid7.setPosition(Common::Point(210, 104));
+ _starGrid7.fixPriority(10);
+
+ _starGrid8.postInit();
+ _starGrid8.setup(326, 1, 1);
+ _starGrid8.setPosition(Common::Point(210, 116));
+ _starGrid8.fixPriority(10);
+
+ _starGrid9.postInit();
+ _starGrid9.setup(326, 1, 1);
+ _starGrid9.setPosition(Common::Point(210, 128));
+ _starGrid9.fixPriority(10);
+
+ _starGrid11.postInit();
+ _starGrid11.setup(326, 1, 1);
+ _starGrid11.setPosition(Common::Point(210, 150));
+ _starGrid11.fixPriority(10);
}
} else if (R2_GLOBALS.getFlag(51)) {
setMessage(329, (v == 12) ? 10 : v);
} else {
- setMessage(327, (v < 15) ? 1 : v);
+ setMessage(327, (v >= 15) ? 1 : v);
}
break;
}
case 21:
_sceneMode = 129;
- _object1.postInit();
- _object1.setup(327, 1, 1);
- _object1.setPosition(Common::Point(170, 80));
- _object1.fixPriority(10);
- _object1.animate(ANIM_MODE_5, NULL);
+ _starGrid1.postInit();
+ _starGrid1.setup(327, 1, 1);
+ _starGrid1.setPosition(Common::Point(170, 80));
+ _starGrid1.fixPriority(10);
+ _starGrid1.animate(ANIM_MODE_5, NULL);
break;
case 22:
_sceneMode = 129;
- _object1.postInit();
- _object1.setup(327, 2, 1);
- _object1.setPosition(Common::Point(160, 80));
- _object1.fixPriority(10);
- _object1.animate(ANIM_MODE_5, NULL);
+ _starGrid1.postInit();
+ _starGrid1.setup(327, 2, 1);
+ _starGrid1.setPosition(Common::Point(160, 80));
+ _starGrid1.fixPriority(10);
+ _starGrid1.animate(ANIM_MODE_5, NULL);
break;
case 24:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 37;
- setMessage(128, _field416);
+ _databasePage = 37;
+ setMessage(128, _databasePage);
break;
case 25:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 68;
- setMessage(128, _field416);
+ _databasePage = 68;
+ setMessage(128, _databasePage);
break;
case 26:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 105;
- setMessage(128, _field416);
+ _databasePage = 105;
+ setMessage(128, _databasePage);
break;
default:
- R2_GLOBALS._player.enableControl();
- R2_GLOBALS._player._canWalk = false;
- _field416 = 105;
- setMessage(128, _field416);
+ _databasePage = 0;
+ setMessage(128, _databasePage);
break;
}
+
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
break;
case 10:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- if ((_field412 >= 17) && (_field412 <= 20)) {
+ if ((_consoleAction >= 17) && (_consoleAction <= 20)) {
_icon5.setIcon(8);
consoleAction(4);
} else {
@@ -4202,7 +4256,7 @@ void Scene325::consoleAction(int id) {
if (id == 7)
_icon5.setIcon(9);
- else if ((_field412 != 3) && ((_field412 < 17) || (_field412 > 26)))
+ else if ((_consoleAction != 3) && ((_consoleAction < 17) || (_consoleAction > 26)))
_icon5.setIcon(8);
switch (id - 1) {
@@ -4211,10 +4265,12 @@ void Scene325::consoleAction(int id) {
_icon2.setIcon(11);
break;
case 1:
+ // Database screen
_icon1.setIcon(23);
_icon2.setIcon(24);
_icon3.setIcon(25);
_icon4.setIcon(26);
+ break;
case 2:
case 16:
case 17:
@@ -4227,8 +4283,88 @@ void Scene325::consoleAction(int id) {
_icon1.hideIcon();
_icon2.hideIcon();
_icon3.hideIcon();
- // TODO: Finish
+
+ if (id == 2 || (id == 19 && _priorConsoleAction == 5 && R2_GLOBALS.getFlag(50) &&
+ R2_GLOBALS.getFlag(44) && !R2_GLOBALS.getFlag(51))) {
+ _icon5.setIcon(13);
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(14);
+ _icon4._horizLine.hide();
+
+ } else {
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+ }
+
+ _icon6.setIcon(12);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ break;
+
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ // Database sub-sections: A-G, N-O, P-S, T-Z
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _consoleAction = 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._horizLine.hide();
+
+ _icon6.setIcon(12);
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ break;
+
+ case 11:
+ if (R2_GLOBALS.getFlag(57) && (R2_GLOBALS._player._characterIndex == R2_QUINN) && !R2_GLOBALS.getFlag(25)) {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _sceneMode = 13;
+ _stripManager.start(403, this);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ id = 8;
+ _text1.remove();
+
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ R2_GLOBALS._player.hide();
+ _starGrid1.remove();
+ _starGrid2.remove();
+ _starGrid3.remove();
+ _starGrid4.remove();
+ _starGrid5.remove();
+ _starGrid6.remove();
+ _starGrid7.remove();
+ _starGrid8.remove();
+ _starGrid9.remove();
+ _starGrid10.remove();
+ _starGrid11.remove();
+ _starGrid12.remove();
+ _starGrid13.remove();
+
+ _palette.loadPalette(160);
+ _sceneMode = 11;
+
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ }
break;
+
case 3:
_icon1.setIcon(5);
_icon2.setIcon(6);
@@ -4236,96 +4372,73 @@ void Scene325::consoleAction(int id) {
break;
case 4:
case 5:
- _field418 = id;
+ _priorConsoleAction = id;
_icon1.setIcon(17);
_icon2.setIcon(18);
_icon3.setIcon(19);
+ _icon4.setIcon(20);
break;
case 7:
- consoleAction(((_field412 == 5) || (_field412 == 6) || (_field412 == 15)) ? 4 : 7);
+ consoleAction(((_consoleAction == 5) || (_consoleAction == 6) || (_consoleAction == 15)) ? 4 : 7);
break;
case 8:
R2_GLOBALS._sceneManager.changeScene(300);
+ break;
case 9:
case 10:
+ // Set language: Interworld or Hero's Tongue
_iconFontNumber = (id - 1) == 9 ? 50 : 52;
_text1.remove();
_icon6.setIcon(7);
- break;
- case 11:
- if (R2_GLOBALS.getFlag(57) && (R2_GLOBALS._player._characterIndex == 1) && !R2_GLOBALS.getFlag(25)) {
- R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_ARROW);
- _sceneMode = 13;
- _stripManager.start(403, this);
- } else {
- R2_GLOBALS._player.disableControl();
- _text1.remove();
-
- _icon4.setPosition(Common::Point(80, 62));
- _icon4._sceneRegionId = 5;
- _icon4.hideIcon();
-
- _object12.remove();
- _object13.remove();
- _object10.remove();
- _object1.remove();
- _object2.remove();
- _object3.remove();
- _object4.remove();
- _object5.remove();
- _object6.remove();
- _object7.remove();
- _object8.remove();
- _object9.remove();
- _object11.remove();
-
- _palette.loadPalette(160);
- _sceneMode = 11;
-
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
- }
+ consoleAction(1);
break;
case 12:
+ // Page up button
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
- switch (_field412) {
+ switch (_consoleAction) {
case 17:
case 18:
case 19:
case 20:
- if (_field420) {
+ if (_scannerLocation) {
R2_GLOBALS._player.disableControl();
- _field41A = 1296;
- _field41E = 1;
+ _moveCounter = 1296;
+ _yDirection = 1;
}
break;
default:
- setMessage(128, --_field416);
+ setMessage(128, --_databasePage);
break;
}
return;
case 13:
+ // Page down button
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
- switch (_field412) {
+ switch (_consoleAction) {
case 17:
case 18:
case 19:
case 20:
- if (_field420 < 1620) {
+ if (_scannerLocation < 1620) {
R2_GLOBALS._player.disableControl();
- _field41A = 1296;
- _field41E = -1;
+ _moveCounter = 1296;
+ _yDirection = -1;
}
break;
+ default:
+ setMessage(128, ++_databasePage);
+ break;
}
return;
case 14:
if (R2_GLOBALS.getFlag(55)) {
- SceneItem::display2(329, 17);
+ consoleAction(4);
+ // Empty message crashing the game. It should be a warning message forbidding to switch to active scan
+ // SceneItem::display2(329, 17);
} else {
R2_GLOBALS.setFlag(50);
consoleAction(4);
@@ -4337,33 +4450,9 @@ 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:
+ // Initial starting screen
_icon1.setIcon(1);
_icon2.setIcon(2);
_icon3.setIcon(3);
@@ -4373,7 +4462,7 @@ void Scene325::consoleAction(int id) {
}
if (id != 8)
- _field412 = id;
+ _consoleAction = id;
}
void Scene325::process(Event &event) {
@@ -4390,107 +4479,107 @@ void Scene325::process(Event &event) {
}
void Scene325::dispatch() {
- if (_field41A) {
- switch (_field41A) {
+ if (_moveCounter) {
+ switch (_moveCounter) {
case 13:
- _field41C = 1;
+ _yChange = 1;
break;
case 1296:
R2_GLOBALS._sound3.play(87);
- _field41C = 1;
+ _yChange = 1;
break;
case 33:
case 1283:
- _field41C = 2;
+ _yChange = 2;
break;
case 63:
case 1263:
- _field41C = 3;
+ _yChange = 3;
break;
case 103:
case 1233:
- _field41C = 4;
+ _yChange = 4;
break;
case 153:
case 1193:
- _field41C = 5;
+ _yChange = 5;
break;
case 213:
case 1143:
- _field41C = 6;
+ _yChange = 6;
break;
case 283:
case 1083:
- _field41C = 7;
+ _yChange = 7;
break;
case 1013:
- _field41C = 8;
+ _yChange = 8;
break;
default:
break;
}
- _field41A -= _field41C;
- int yp = _field41E * _field41C + _object10._position.y;
+ _moveCounter -= _yChange;
+ int yp = _yDirection * _yChange + _starGrid10._position.y;
bool flag = false;
if (yp >= 30) {
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));
+ _starGrid13.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;
- _object10.setFrame((v++ <= 0) ? 1 : v);
- _object1.setFrame((v++ <= 0) ? 1 : v);
- _object2.setFrame((v++ <= 0) ? 1 : v);
- _object3.setFrame((v++ <= 0) ? 1 : v);
- _object4.setFrame((v++ <= 0) ? 1 : v);
- _object5.setFrame((v++ <= 0) ? 1 : v);
- _object6.setFrame((v++ <= 0) ? 1 : v);
- _object7.setFrame((v++ <= 0) ? 1 : v);
- _object8.setFrame((v++ <= 0) ? 1 : v);
- _object9.setFrame((v++ <= 0) ? 1 : v);
- _object11.setFrame((v++ <= 0) ? 1 : v);
- }
-
- _object10.setPosition(Common::Point(210, yp));
+ int v = _scannerLocation - 758;
+ _starGrid10.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid1.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid2.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid3.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid4.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid5.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid6.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid7.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid8.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid9.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid11.setFrame((v++ <= 0) ? 1 : v);
+ }
+
+ _starGrid10.setPosition(Common::Point(210, yp));
yp += 12;
- _object1.setPosition(Common::Point(210, yp));
+ _starGrid1.setPosition(Common::Point(210, yp));
yp += 12;
- _object2.setPosition(Common::Point(210, yp));
+ _starGrid2.setPosition(Common::Point(210, yp));
yp += 12;
- _object3.setPosition(Common::Point(210, yp));
+ _starGrid3.setPosition(Common::Point(210, yp));
yp += 12;
- _object4.setPosition(Common::Point(210, yp));
+ _starGrid4.setPosition(Common::Point(210, yp));
yp += 12;
- _object5.setPosition(Common::Point(210, yp));
+ _starGrid5.setPosition(Common::Point(210, yp));
yp += 12;
- _object6.setPosition(Common::Point(210, yp));
+ _starGrid6.setPosition(Common::Point(210, yp));
yp += 12;
- _object7.setPosition(Common::Point(210, yp));
+ _starGrid7.setPosition(Common::Point(210, yp));
yp += 12;
- _object8.setPosition(Common::Point(210, yp));
+ _starGrid8.setPosition(Common::Point(210, yp));
yp += 12;
- _object9.setPosition(Common::Point(210, yp));
+ _starGrid9.setPosition(Common::Point(210, yp));
yp += 12;
- _object11.setPosition(Common::Point(210, yp));
+ _starGrid11.setPosition(Common::Point(210, yp));
- if (!_field41A) {
+ if (!_moveCounter) {
R2_GLOBALS._sound3.stop();
- _field41C = 0;
+ _yChange = 0;
- if (_field420 == 756) {
+ if (_scannerLocation == 756) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_USE);
_sceneMode = 12;
@@ -4506,9 +4595,11 @@ void Scene325::dispatch() {
}
void Scene325::setMessage(int resNum, int lineNum) {
- Common::String msg = g_resourceManager->getMessage(resNum, lineNum);
+ removeText();
+ Common::String msg = g_resourceManager->getMessage(resNum, lineNum, true);
if (!msg.empty()) {
+ // Found valid database entry to display
Common::String msgText = parseMessage(msg);
_text1._fontNumber = _iconFontNumber;
@@ -4526,7 +4617,9 @@ void Scene325::setMessage(int resNum, int lineNum) {
R2_GLOBALS._playStream.play(_soundQueue[_soundIndex++], this);
}
} else {
- _field412 = 13;
+ // No message for given database index, so we must have passed beyond
+ // the start or end of the database
+ _consoleAction = 13;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.hide();
@@ -4536,7 +4629,7 @@ void Scene325::setMessage(int resNum, int lineNum) {
_palette.loadPalette(160);
_sceneMode = 11;
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
}
}
@@ -4558,15 +4651,16 @@ Common::String Scene325::parseMessage(const Common::String &msg) {
return Common::String(msgP);
}
+
/*--------------------------------------------------------------------------
* Scene 400 - Science Lab
*
*--------------------------------------------------------------------------*/
bool Scene400::Terminal::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 402;
scene->setAction(&scene->_sequenceManager1, scene, 402, &R2_GLOBALS._player, this, NULL);
@@ -4580,9 +4674,9 @@ bool Scene400::Terminal::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene400::Door::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 401;
scene->setAction(&scene->_sequenceManager1, scene, 401, &R2_GLOBALS._player, this, NULL);
@@ -4594,9 +4688,9 @@ bool Scene400::Door::startAction(CursorType action, Event &event) {
}
bool Scene400::Reader::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 405;
scene->setAction(&scene->_sequenceManager1, scene, 405, &R2_GLOBALS._player, this, NULL);
@@ -4608,9 +4702,9 @@ bool Scene400::Reader::startAction(CursorType action, Event &event) {
}
bool Scene400::SensorProbe::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 404;
scene->setAction(&scene->_sequenceManager1, scene, 404, &R2_GLOBALS._player, this, NULL);
@@ -4622,9 +4716,9 @@ bool Scene400::SensorProbe::startAction(CursorType action, Event &event) {
}
bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 406;
scene->setAction(&scene->_sequenceManager1, scene, 406, &R2_GLOBALS._player, this, NULL);
@@ -4638,8 +4732,9 @@ bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
void Scene400::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(400);
+ SceneExt::postInit();
+
_sound1.play(20);
_door.postInit();
@@ -4797,10 +4892,15 @@ void Scene400::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+Scene500::PanelDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(26)) {
@@ -4819,17 +4919,18 @@ bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
-bool Scene500::Object2::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene500::Seeker::startAction(CursorType action, Event &event) {
if (action == CURSOR_TALK) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
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 +4938,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 +4949,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 +4978,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,19 +4988,14 @@ 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);
}
}
bool Scene500::Doorway::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(26)) {
@@ -4908,7 +5004,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;
@@ -4918,8 +5014,6 @@ bool Scene500::Doorway::startAction(CursorType action, Event &event) {
}
bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_LOOK:
SceneItem::display2(500, R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) ? 50 : 49);
@@ -4931,6 +5025,8 @@ bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
return true;
} else if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 1) &&
(R2_GLOBALS._player._characterIndex != R2_SEEKER) && !R2_GLOBALS.getFlag(28)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (_position.y == 120) {
@@ -4954,23 +5050,56 @@ bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
}
bool Scene500::AirLock::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && R2_GLOBALS.getFlag(26)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
- &scene->_object2, &scene->_airLock, NULL);
+ &scene->_seeker, &scene->_airLock, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
}
}
-bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+void Scene500::TransparentDoor::draw() {
+ // Determine the area of the screen to be updated
+ Rect destRect = _bounds;
+ destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left,
+ -g_globals->_sceneManager._scene->_sceneBounds.top);
+
+ // Get the frame to be drawn
+ GfxSurface frame = getFrame();
+
+ Graphics::Surface s = frame.lockSurface();
+ Graphics::Surface screen = g_globals->gfxManager().getSurface().lockSurface();
+
+ for (int yp = 0; yp < s.h; ++yp) {
+ byte *frameSrcP = (byte *)s.getBasePtr(0, yp);
+ byte *screenP = (byte *)screen.getBasePtr(destRect.left, destRect.top + yp);
+
+ for (int xp = 0; xp < s.w; ++xp, ++frameSrcP, ++screenP) {
+ if (*frameSrcP != frame._transColor && *frameSrcP < 6) {
+ *frameSrcP = R2_GLOBALS._fadePaletteMap[*frameSrcP][*screenP];
+ }
+ }
+ }
+
+ // Finished updating the frame
+ frame.unlockSurface();
+ g_globals->gfxManager().getSurface().unlockSurface();
+
+ // Draw the processed frame
+ Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority);
+ g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+}
+
+bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 503;
scene->setAction(&scene->_sequenceManager1, scene, 503, &R2_GLOBALS._player, this, NULL);
@@ -4981,12 +5110,12 @@ bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
}
bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 520 : 502;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -4994,9 +5123,9 @@ bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
}
bool Scene500::Locker1::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(11))
@@ -5012,9 +5141,9 @@ bool Scene500::Locker1::startAction(CursorType action, Event &event) {
}
bool Scene500::Locker2::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(12))
@@ -5029,7 +5158,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 *)R2_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,13 +5195,127 @@ 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 *)R2_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() {
+ if (R2_GLOBALS.getFlag(28)) {
+ SceneItem::display2(500, 48);
+ } else {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = _buttonId;
+
+ switch (_buttonId) {
+ case 1:
+ // Rotate Left
+ if (--R2_GLOBALS._landerSuitNumber == 0)
+ R2_GLOBALS._landerSuitNumber = R2_MIRANDA;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 5;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_suits.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 2:
+ // Rotate Right
+ if (++R2_GLOBALS._landerSuitNumber == 4)
+ R2_GLOBALS._landerSuitNumber = R2_QUINN;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 6;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_suits.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 3:
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 509;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
+ } else {
+ scene->_suit.postInit();
+ scene->_suit.hide();
+ scene->_suit._effect = EFFECT_SHADED;
+ scene->_suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ scene->_suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 1);
+
+ scene->setAction(&scene->_sequenceManager1, scene, 508,
+ &R2_GLOBALS._player, &scene->_suits, &scene->_suit,
+ &scene->_transparentDoor, NULL);
+ R2_GLOBALS.setFlag(35);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
void Scene500::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(500);
+ SceneExt::postInit();
- Common::fill(&_buffer[0], &_buffer[2710], 0);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(50);
_stripManager.addSpeaker(&_seekerSpeaker);
@@ -5053,29 +5325,29 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterScene[R2_SEEKER] = 500;
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);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+
+ _seeker.postInit();
+ _seeker._effect = EFFECT_SHADED;
+ _seeker.setup(1505, 1, 1);
+ _seeker._moveDiff.x = 5;
+ _seeker.setPosition(Common::Point(42, 151));
+ _seeker.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
} else if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
- _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 = EFFECT_SHADED;
+ _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);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(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));
@@ -5137,30 +5409,30 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
_sonicStunner.setDetails(500, 21, 22, 23, 1, (SceneItem *)NULL);
}
- _object1.postInit();
- _object1._effect = 1;
- _object1.setup(502, 1, 1);
- _object1.setPosition(Common::Point(258, 99));
- _object1.fixPriority(50);
+ _suits.postInit();
+ _suits._effect = EFFECT_SHADED;
+ _suits.setup(502, 1, 1);
+ _suits.setPosition(Common::Point(258, 99));
+ _suits.fixPriority(50);
- _object8.postInit();
- _object8.setPosition(Common::Point(250, 111));
+ _transparentDoor.postInit();
+ _transparentDoor.setPosition(Common::Point(250, 111));
if (!R2_GLOBALS.getFlag(35)) {
- _object8.setup(501, 3, 1);
+ _transparentDoor.setup(501, 3, 1);
} else {
- _object8.setup(500, 8, 7);
+ _transparentDoor.setup(500, 8, 7);
- _object3.postInit();
- _object3._effect = 1;
- _object3.setPosition(Common::Point(247, 52));
- _object3.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ _suit.postInit();
+ _suit._effect = EFFECT_SHADED;
+ _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);
}
}
@@ -5171,7 +5443,7 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff.x = 5;
_controlPanel.setDetails(Rect(175, 62, 191, 80), 500, 31, 32, 33, 1, (SceneItem *)NULL);
- _item2.setDetails(Rect(13, 58, 70, 118), 500, 12, -1, -1, 1, (SceneItem *)NULL);
+ _airlockCorridor.setDetails(Rect(13, 58, 70, 118), 500, 12, -1, -1, 1, (SceneItem *)NULL);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 500, 0, -1, -1, 1, (SceneItem *)NULL);
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) && (R2_GLOBALS._sceneManager._previousScene == 700)) {
@@ -5203,34 +5475,34 @@ void Scene500::signal() {
case 5:
_sceneMode = 12;
_sound1.play(127);
- _object1.animate(ANIM_MODE_6, this);
+ _suits.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 6:
_sceneMode = 11;
_sound1.play(127);
- _object1.animate(ANIM_MODE_5, this);
+ _suits.animate(ANIM_MODE_5, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 7:
_sound1.play(126);
- _object8.animate(ANIM_MODE_6, this);
+ _transparentDoor.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 +5533,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 +5543,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:
@@ -5316,6 +5588,7 @@ void Scene500::signal() {
* Scene 525 - Cutscene - Walking in hall
*
*--------------------------------------------------------------------------*/
+
void Scene525::postInit(SceneObjectList *OwnerList) {
loadScene(525);
R2_GLOBALS._uiElements._active = false;
@@ -5324,7 +5597,7 @@ void Scene525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(105);
_actor1.postInit();
- _actor1._effect = 1;
+ _actor1._effect = EFFECT_SHADED;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -5338,42 +5611,32 @@ 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;
}
-bool Scene600::Item4::startAction(CursorType action, Event &event) {
+bool Scene600::EngineCompartment::startAction(CursorType action, Event &event) {
if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(1)))
return SceneHotspot::startAction(action, event);
if ((R2_GLOBALS.getFlag(5)) && (!R2_GLOBALS.getFlag(8))) {
- SceneItem::display(600, 32, 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;
}
@@ -5384,36 +5647,59 @@ 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->_stasisArea.setup(603, 3, 1, 239, 54, 10);
+ 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);
+
+ // WORKAROUND: For ScummVM, we use a SceneActor rather than BackgroundSceneObject
+ // for the stasis field since it doesn't work properly. We override the priority for
+ // the stasis field here so that the stasis field dissolve will show up
+ scene->_stasisField.fixPriority(12);
+
return true;
}
-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 +5709,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->_laserBeam, NULL);
return true;
}
@@ -5436,36 +5722,37 @@ 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;
}
if ((R2_GLOBALS.getFlag(9)) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600))
- SceneItem::display(600, 31, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(600, 31, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 601;
- 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);
+ SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
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 {
@@ -5474,32 +5761,33 @@ bool Scene600::Actor6::startAction(CursorType action, Event &event) {
break;
case R2_AEROSOL:
if (R2_GLOBALS.getFlag(5)) {
- SceneItem::display(600, 28, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(600, 28, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
} else {
R2_GLOBALS._player.disableControl();
- 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 = 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,45 +5797,62 @@ 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 {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 610;
- scene->setAction(&scene->_sequenceManager1, scene, 610, &scene->_actor1, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 610, &scene->_laserBeam, &R2_GLOBALS._player, NULL);
return true;
}
} else
return SceneActor::startAction(action, event);
}
-bool Scene600::Actor7::startAction(CursorType action, Event &event) {
- Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
-
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
- } else if (action == CURSOR_USE) {
+
+ if (action == CURSOR_USE) {
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 614;
- scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_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() {
+ _roomState = 0;
+ Common::fill(&_pixelMap[0], &_pixelMap[256], 0);
+}
+
+void Scene600::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_roomState);
+ 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);
}
@@ -5559,26 +5864,34 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
loadScene(600);
SceneExt::postInit();
R2_GLOBALS.setFlag(39);
- R2_GLOBALS._walkRegions.enableRegion(3);
- _field412 = 0;
-
- warning("FIXME: loop to initialize _fieldAD2[]");
-
- _actor5.postInit();
- _actor5.setVisage(600);
- _actor5.setPosition(Common::Point(29, 147));
- _actor5.fixPriority(10);
- _actor5.setDetails(300, 3, -1, -1, 1, (SceneItem *) NULL);
-
- _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) {
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ _roomState = 0;
+
+ // 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);
+
+ _pixelMap[i] = R2_GLOBALS._paletteMap[(av << 8) | (av << 4) | av];
+ }
+
+ _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,48 +5910,50 @@ 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);
- _actor1.setPosition(Common::Point(223, 51));
- _actor1.fixPriority(200);
+ _laserBeam.postInit();
+ _laserBeam.setup(600, 3, 5);
+ _laserBeam.setPosition(Common::Point(223, 51));
+ _laserBeam.fixPriority(200);
}
if (! R2_GLOBALS.getFlag(9))
- _object1.setup2(603, 1, 1, 244, 50, 10, 0);
+ _stasisArea.setup(603, 1, 1, 244, 50, 10);
if (R2_GLOBALS.getFlag(5)) {
- if (R2_INVENTORY.getObjectScene(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 = EFFECT_3;
+ _smoke.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
+ _smoke.signal();
}
}
@@ -5647,34 +5962,34 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _item2.setDetails(12, 600, 17, -1, 19);
- _item3.setDetails(11, 600, 14, -1, -1);
+ _quantumRegulator.setDetails(12, 600, 17, -1, 19);
+ _powerNode.setDetails(11, 600, 14, -1, -1);
if (R2_GLOBALS.getFlag(9)) {
- _item1.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
+ _quantumDrive.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
} else {
- _item4.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL);
- _item1.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
+ _engineCompartment.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL);
+ _quantumDrive.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
}
- _item5.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL);
_sceneMode = 600;
if (R2_GLOBALS._sceneManager._previousScene == 700) {
if (R2_GLOBALS.getFlag(6)) {
- setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_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, &_laserBeam, NULL);
} else {
- setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_actor5, &_actor6, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_doorway, &_laser, &_laserBeam, NULL);
}
} else if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.setPosition(Common::Point(50, 140));
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 +5997,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,55 +6012,63 @@ 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_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ R2_GLOBALS._walkRegions.disableRegion(10);
- R2_INVENTORY.setObjectScene(12, 600);
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 600);
R2_GLOBALS.setFlag(5);
- _actor4._effect = 3;
- _actor4.signal();
+ _smoke._effect = 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();
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(9);
- R2_GLOBALS._walkRegions.disableRegion(10);
+ _smoke.remove();
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(9);
+ R2_GLOBALS._walkRegions.enableRegion(10);
R2_GLOBALS._player.enableControl();
break;
case 612:
+ // Deactivate stasis field
R2_GLOBALS.setFlag(9);
- _actor3.remove();
- R2_GLOBALS._sceneItems.remove(&_item4);
- _actor2.setDetails(600, 21, -1, 23, 4, &_item4);
- _item1.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ _stasisField.remove();
+ R2_GLOBALS._sceneItems.remove(&_engineCompartment);
+ _computer.setDetails(600, 21, -1, 23, 4, &_engineCompartment);
+ _engineCompartment.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ _quantumDrive._lookLineNum = 7;
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
case 614:
+ // Pick up Aerosol
R2_GLOBALS._player.enableControl();
- _actor7.remove();
- R2_INVENTORY.setObjectScene(12, 1);
- R2_GLOBALS._walkRegions.disableRegion(7);
+ _aerosol.remove();
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 1);
+ R2_GLOBALS._walkRegions.enableRegion(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:
- _field412 = 0;
+ _roomState = 0;
_sceneMode = 0;
R2_GLOBALS._player.enableControl();
break;
@@ -5753,59 +6076,64 @@ 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;
+ _roomState += 10;
} else {
R2_GLOBALS._player.disableControl();
_sceneMode = 604;
- setAction(&_sequenceManager1, this, 604, &_actor1, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 604, &_laserBeam, &R2_GLOBALS._player, NULL);
event.handled = true;
}
} else {
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)){
- _field412 += 10;
+ } else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_roomState < 10)){
+ _roomState += 10;
}
Scene::process(event);
}
void Scene600::dispatch() {
- if ((_field412 != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
- if ( ((_actor6._strip == 4) && (_actor6._frame > 1))
+ if ((_roomState != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
+ if ( ((_laser._strip == 4) && (_laser._frame > 1))
|| (_sceneMode == 601)
- || ((_sceneMode == 616) && (_actor5._frame > 1)) )
- _field412 = 0;
+ || ((_sceneMode == 616) && (_doorway._frame > 1)) )
+ _roomState = 0;
else {
- _field412--;
- if (_field412 % 10 == 0) {
- _actor1.setAction(&_sequenceManager2, NULL, 611, &_actor1, NULL);
+ _roomState--;
+ if (_roomState % 10 == 0) {
+ _laserBeam.setAction(&_sequenceManager2, NULL, 611, &_laserBeam, NULL);
}
- if ((_field412 == 0) && (R2_GLOBALS._player._mover))
- _field412 = 10;
+ if ((_roomState == 0) && (R2_GLOBALS._player._mover))
+ _roomState = 10;
}
}
- if (_actor1._frame == 2)
- _aSound1.play(40);
+ if (_laserBeam._frame == 2)
+ _sound1.play(40);
Scene::dispatch();
- if ((_actor4._strip == 3) && (_actor4._frame == 3)) {
- _actor1.setStrip(4);
- _actor1.setFrame(1);
+ if ((_smoke._strip == 3) && (_smoke._frame == 3)) {
+ _laserBeam.setStrip(4);
+ _laserBeam.setFrame(1);
}
}
/*--------------------------------------------------------------------------
- * Scene 700 -
+ * Scene 700 - Lander Bay 2
*
*--------------------------------------------------------------------------*/
+
+#define CABLE700_X 26
+#define CABLE700_Y -5
+
Scene700::Scene700() {
_rotation = NULL;
}
@@ -5815,33 +6143,33 @@ void Scene700::synchronize(Serializer &s) {
SYNC_POINTER(_rotation);
}
-bool Scene700::Item11::startAction(CursorType action, Event &event) {
+bool Scene700::Loft::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_GLOBALS._player._position.x < 100))
return false;
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,19 +6177,19 @@ 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;
}
-bool Scene700::Actor2::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::LiftDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 701;
scene->setAction(&scene->_sequenceManager, scene, 701, &R2_GLOBALS._player, this, NULL);
@@ -5869,15 +6197,15 @@ bool Scene700::Actor2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor3::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::SuitRoomDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 702;
scene->setAction(&scene->_sequenceManager, scene, 702, &R2_GLOBALS._player, this, NULL);
@@ -5885,15 +6213,15 @@ bool Scene700::Actor3::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor4::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::ControlPanel::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 704;
scene->setAction(&scene->_sequenceManager, scene, 704, &R2_GLOBALS._player, this, NULL);
@@ -5901,7 +6229,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 +6238,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 +6263,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);
@@ -5953,12 +6281,12 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor6::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::LoftDoor::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (R2_GLOBALS._player._position.y >= 100))
return SceneActor::startAction(action, event);
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1;
Common::Point pt(_position.x, 69);
@@ -5969,70 +6297,68 @@ bool Scene700::Actor6::startAction(CursorType action, Event &event) {
}
void Scene700::postInit(SceneObjectList *OwnerList) {
- if (R2_GLOBALS._sceneManager._previousScene == 900)
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
-
loadScene(700);
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ if (R2_GLOBALS._sceneManager._previousScene == 900)
+ _sceneBounds = Rect(160, 0, 480, 200);
SceneExt::postInit();
_rotation = R2_GLOBALS._scenePalette.addRotation(237, 246, -1);
_rotation->setDelay(5);
_rotation->_countdown = 1;
- _actor2.postInit();
- _actor2.setVisage(700);
- _actor2.setPosition(Common::Point(21, 128));
- _actor2.fixPriority(10);
- _actor2.setDetails(700, 3, -1, -1, 1, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3.setup(700, 2, 1);
- _actor3.setPosition(Common::Point(217, 120));
- _actor3.fixPriority(10);
- _actor3.setDetails(700, 15, -1, -1, 1, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(700, 4, 1);
- _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._v565E3 * 8) / 5), ((R2_GLOBALS._v565E1 + 20 ) / 5) - 12));
- _actor1.fixPriority(10);
- _actor1.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL);
-
- _actor6.postInit();
- _actor6.setup(700, 8, 1);
- _actor6.setPosition(Common::Point(85, 53));
- _actor6.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor7.postInit();
- _actor7.setup(700, 8, 1);
- _actor7.setPosition(Common::Point(164, 53));
- _actor7.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor8.postInit();
- _actor8.setup(700, 8, 1);
- _actor8.setPosition(Common::Point(243, 53));
- _actor8.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor9.postInit();
- _actor9.setup(700, 8, 1);
- _actor9.setPosition(Common::Point(324, 53));
- _actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+ _liftDoor.postInit();
+ _liftDoor.setVisage(700);
+ _liftDoor.setPosition(Common::Point(21, 128));
+ _liftDoor.fixPriority(10);
+ _liftDoor.setDetails(700, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _suitRoomDoor.postInit();
+ _suitRoomDoor.setup(700, 2, 1);
+ _suitRoomDoor.setPosition(Common::Point(217, 120));
+ _suitRoomDoor.fixPriority(10);
+ _suitRoomDoor.setDetails(700, 15, -1, -1, 1, (SceneItem *) NULL);
+
+ _electromagnet.postInit();
+ _electromagnet.setup(700, 4, 1);
+ _electromagnet.setPosition(Common::Point(355 - ((R2_GLOBALS._electromagnetZoom * 8) / 5), ((R2_GLOBALS._electromagnetChangeAmount + 20 ) / 5) - 12));
+ _electromagnet.fixPriority(10);
+ _electromagnet.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL);
+
+ _loftDoor1.postInit();
+ _loftDoor1.setup(700, 8, 1);
+ _loftDoor1.setPosition(Common::Point(85, 53));
+ _loftDoor1.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor2.postInit();
+ _loftDoor2.setup(700, 8, 1);
+ _loftDoor2.setPosition(Common::Point(164, 53));
+ _loftDoor2.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor3.postInit();
+ _loftDoor3.setup(700, 8, 1);
+ _loftDoor3.setPosition(Common::Point(243, 53));
+ _loftDoor3.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor4.postInit();
+ _loftDoor4.setup(700, 8, 1);
+ _loftDoor4.setPosition(Common::Point(324, 53));
+ _loftDoor4.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _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 - (CABLE700_X * 8), 148 - (((CABLE700_Y + 10) / 5) * 4)));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6041,23 +6367,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._tractorField && (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);
- if (R2_GLOBALS._v565E7 == 0) {
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setup(701, 1, 8);
+ if (!R2_GLOBALS._cableAttached) {
+ _cable.setPosition(Common::Point(356 - (CABLE700_X * 8), 148 - (((CABLE700_Y + 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(_electromagnet._position.x + 1, _electromagnet._position.y + 120));
}
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6067,23 +6393,23 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
}
}
- _actor4.postInit();
- _actor4.setup(700, 3, 1);
- _actor4.setPosition(Common::Point(454, 117));
- _actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
-
- _item12.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
- _item6.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
- _item2.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
- _item3.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
- _item4.setDetails(Rect(247, 108, 275, 124), 700, 40, -1, 41, 1, NULL);
- _item5.setDetails(Rect(300, 105, 321, 124), 700, 40, -1, 41, 1, NULL);
- _item7.setDetails(Rect(255, 74, 368, 115), 700, 9, -1, 11, 1, NULL);
- _item8.setDetails(Rect(69, 74, 182, 115), 700, 9, -1, 11, 1, NULL);
- _item9.setDetails(Rect(370, 58, 475, 103), 700, 18, -1, -1, 1, NULL);
- _item10.setDetails(Rect(17, 11, 393, 31), 700, 24, -1, -1, 1, NULL);
- _item11.setDetails(Rect(42, 32, 368, 66), 700, 30, -1, 32, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 700, 0, -1, -1, 1, NULL);
+ _controlPanel.postInit();
+ _controlPanel.setup(700, 3, 1);
+ _controlPanel.setPosition(Common::Point(454, 117));
+ _controlPanel.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
+
+ _handGrip.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
+ _restraintCollar.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
+ _debris1.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
+ _debris2.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
+ _debris3.setDetails(Rect(247, 108, 275, 124), 700, 40, -1, 41, 1, NULL);
+ _debris4.setDetails(Rect(300, 105, 321, 124), 700, 40, -1, 41, 1, NULL);
+ _storage2.setDetails(Rect(255, 74, 368, 115), 700, 9, -1, 11, 1, NULL);
+ _storage1.setDetails(Rect(69, 74, 182, 115), 700, 9, -1, 11, 1, NULL);
+ _stars.setDetails(Rect(370, 58, 475, 103), 700, 18, -1, -1, 1, NULL);
+ _light.setDetails(Rect(17, 11, 393, 31), 700, 24, -1, -1, 1, NULL);
+ _loft.setDetails(Rect(42, 32, 368, 66), 700, 30, -1, 32, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 700, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(11);
@@ -6097,14 +6423,14 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 250:
- setAction(&_sequenceManager, this, 700, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 700, &R2_GLOBALS._player, &_liftDoor, NULL);
break;
case 500:
- setAction(&_sequenceManager, this, 703, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 703, &R2_GLOBALS._player, &_suitRoomDoor, NULL);
break;
case 600: {
_sceneMode = 4;
- _actor7.setFrame(5);
+ _loftDoor2.setFrame(5);
R2_GLOBALS._player.setPosition(Common::Point(164, 74));
R2_GLOBALS._player.setStrip2(3);
Common::Point pt(164, 69);
@@ -6113,7 +6439,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
}
break;
case 900:
- setAction(&_sequenceManager, this, 705, &R2_GLOBALS._player, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 705, &R2_GLOBALS._player, &_controlPanel, NULL);
break;
default:
if (R2_GLOBALS.getFlag(41))
@@ -6128,11 +6454,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
void Scene700::remove() {
R2_GLOBALS._sound1.play(10);
-// CHECKME: Present in the original... But it crashes badly.
-// The instruction was removed as it's not used in other scene coded the same way
-// and reversed by dreammaster. A double check is required in order to verify it doesn't hide
-// a memory leak
-// _rotation->remove();
+
SceneExt::remove();
}
@@ -6142,11 +6464,11 @@ void Scene700::signal() {
_sceneMode = 2;
R2_GLOBALS._player.setStrip(4);
if (R2_GLOBALS._player._position.x != 164) {
- SceneItem::display(700, 36, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(700, 36, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
R2_GLOBALS._player.enableControl();
} else {
R2_GLOBALS._sound2.play(19);
- _actor7.animate(ANIM_MODE_5, this);
+ _loftDoor2.animate(ANIM_MODE_5, this);
}
break;
case 2: {
@@ -6158,16 +6480,14 @@ 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;
R2_GLOBALS._player.setStrip2(-1);
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
R2_GLOBALS._sound2.play(19);
- _actor7.animate(ANIM_MODE_6, this);
+ _loftDoor2.animate(ANIM_MODE_6, this);
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS.setFlag(41);
break;
@@ -6179,7 +6499,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,14 +6524,14 @@ 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._tractorField && (_cable._position.x == _electromagnet._position.x + 1) && (_cable._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
+ _cable.animate(ANIM_MODE_6, NULL);
+ Common::Point pt(_cable._position.x, _electromagnet._position.y + 120);
NpcMover *mover = new NpcMover();
- _actor5.addMover(mover, &pt, NULL);
- R2_GLOBALS._v565E7 = 1;
+ _cable.addMover(mover, &pt, NULL);
+ R2_GLOBALS._cableAttached = true;
}
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
@@ -6230,9 +6550,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._tractorField && (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 +6567,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._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
@@ -6277,11 +6597,11 @@ void Scene700::signal() {
*--------------------------------------------------------------------------*/
bool Scene800::Button::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE) {
return NamedHotspot::startAction(action, event);
} else {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 802;
scene->setAction(&scene->_sequenceManager1, scene, 802, &R2_GLOBALS._player, &scene->_autodocCover, NULL);
@@ -6290,11 +6610,11 @@ bool Scene800::Button::startAction(CursorType action, Event &event) {
}
bool Scene800::CableJunction::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
if (action != R2_OPTICAL_FIBRE) {
return NamedHotspot::startAction(action, event);
} else {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_opticalFibre.postInit();
scene->_sceneMode = 803;
@@ -6317,12 +6637,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;
@@ -6334,24 +6668,25 @@ bool Scene800::DeviceSlot::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene800::Door::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 801;
scene->setAction(&scene->_sequenceManager1, scene, 801, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene800::Tray::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
if (!R2_GLOBALS.getFlag(10)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 806;
@@ -6366,16 +6701,17 @@ bool Scene800::Tray::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager1, scene, 807, &R2_GLOBALS._player, &scene->_tray, NULL);
}
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
if (scene->_cabinet._frame == 1)
return false;
@@ -6383,6 +6719,7 @@ bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
scene->_sceneMode = 811;
scene->setAction(&scene->_sequenceManager1, scene, 811, &R2_GLOBALS._player, &scene->_comScanner, NULL);
return true;
+ }
case CURSOR_TALK:
SceneItem::display2(800, 35);
return true;
@@ -6392,10 +6729,10 @@ bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
}
bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (scene->_cabinet._frame == 1) {
@@ -6408,6 +6745,7 @@ bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
R2_GLOBALS.clearFlag(56);
}
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
@@ -6416,8 +6754,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);
@@ -6561,21 +6899,19 @@ void Scene800::signal() {
Scene825::Button::Button(): SceneObject() {
_buttonId = 0;
- _v2 = 0;
_buttonDown = false;
}
void Scene825::Button::synchronize(Serializer &s) {
SceneObject::synchronize(s);
s.syncAsSint16LE(_buttonId);
- s.syncAsSint16LE(_v2);
s.syncAsSint16LE(_buttonDown);
}
void Scene825::Button::process(Event &event) {
- Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
-
if (!event.handled) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
+
if ((event.eventType == EVENT_BUTTON_DOWN) && _bounds.contains(event.mousePos) && !_buttonDown) {
scene->_sound1.play(14);
setFrame(2);
@@ -6602,7 +6938,6 @@ bool Scene825::Button::startAction(CursorType action, Event &event) {
void Scene825::Button::setButton(int buttonId) {
SceneObject::postInit();
- _v2 = buttonId;
_buttonDown = 0;
_sceneText._color1 = 92;
_sceneText._color2 = 0;
@@ -6640,14 +6975,14 @@ void Scene825::Button::setButton(int buttonId) {
}
void Scene825::Button::setText(int textId) {
- Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
-
_buttonId = textId;
_lookLineNum = textId;
_sceneText.remove();
- if (_buttonId != 0)
+ if (_buttonId != 0) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
_sceneText.setup(scene->_autodocItems[textId - 1]);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -6670,18 +7005,19 @@ Scene825::Scene825(): SceneExt() {
}
void Scene825::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(825);
- R2_GLOBALS._player._uiEnabled = false;
- BF_GLOBALS._interfaceY = 200;
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
R2_GLOBALS._player.setVisage(10);
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _item2.setDetails(1, 825, 3, 4, 5);
+
+ _console.setDetails(1, 825, 3, 4, 5);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 825, 0, -1, -1, 1, NULL);
_sceneMode = 10;
@@ -6728,7 +7064,7 @@ void Scene825::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 825:
- _object5.remove();
+ _vertLine5.remove();
_sceneText._color1 = 92;
_sceneText._color2 = 0;
_sceneText._width = 200;
@@ -6746,7 +7082,7 @@ void Scene825::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 827:
- _object5.remove();
+ _vertLine5.remove();
R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 825);
_sceneText.setPosition(Common::Point(108, 75));
_sceneText.setup(FOREIGN_OBJECT_EXTRACTED);
@@ -6774,19 +7110,19 @@ void Scene825::process(Event &event) {
}
void Scene825::dispatch() {
- if (R2_GLOBALS._sceneObjects->contains(&_object4) &&
- ((_object4._frame == 1) || (_object4._frame == 3)) &&
- (_object4._frame != _frame1)) {
+ if (R2_GLOBALS._sceneObjects->contains(&_vertLine4) &&
+ ((_vertLine4._frame == 1) || (_vertLine4._frame == 3)) &&
+ (_vertLine4._frame != _frame1)) {
_sound2.play(25);
}
- if (R2_GLOBALS._sceneObjects->contains(&_object1) &&
- (_object1._frame == 3) && (_object1._frame != _frame2)) {
+ if (R2_GLOBALS._sceneObjects->contains(&_vertLine1) &&
+ (_vertLine1._frame == 3) && (_vertLine1._frame != _frame2)) {
_sound3.play(26);
}
- _frame1 = _object4._frame;
- _frame2 = _object1._frame;
+ _frame1 = _vertLine4._frame;
+ _frame2 = _vertLine1._frame;
Scene::dispatch();
}
@@ -6803,9 +7139,9 @@ void Scene825::doButtonPress(int buttonId) {
switch (buttonId) {
case 2:
R2_GLOBALS._player.disableControl();
- _object5.postInit();
+ _vertLine5.postInit();
_sceneMode = 825;
- setAction(&_sequenceManager1, this, 825, &R2_GLOBALS._player, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 825, &R2_GLOBALS._player, &_vertLine5, NULL);
break;
case 3:
R2_GLOBALS._player.disableControl();
@@ -6826,9 +7162,10 @@ void Scene825::doButtonPress(int buttonId) {
_sceneText.setup(NO_TREATMENT_REQUIRED);
} else {
_button6._buttonId = 5;
+ _sceneMode = 827;
+ _vertLine5.postInit();
- _object5.postInit();
- setAction(&_sequenceManager1, this, 827, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 827, &_vertLine5, NULL);
}
} else {
R2_GLOBALS.setFlag(2);
@@ -6852,44 +7189,44 @@ void Scene825::doButtonPress(int buttonId) {
_sound4.play(27);
_button6._buttonId = 5;
- _object1.postInit();
- _object1.setup(826, 7, 1);
- _object1.setPosition(Common::Point(112, 67));
- _object1._numFrames = 1;
- _object1.animate(ANIM_MODE_2);
-
- _object2.postInit();
- _object2.setup(826, 5, 1);
- _object2.setPosition(Common::Point(158, 67));
- _object2._numFrames = 5;
- _object2.animate(ANIM_MODE_2);
-
- _object3.postInit();
- _object3.setup(826, 6, 1);
- _object3.setPosition(Common::Point(206, 67));
- _object3._numFrames = 1;
- _object3.animate(ANIM_MODE_2);
-
- _object4.postInit();
- _object4.setup(826, 8, 1);
- _object4.setPosition(Common::Point(158, 84));
- _object4._numFrames = 1;
- _object4.animate(ANIM_MODE_2);
-
- _object5.postInit();
- _object5.setup(826, 4, 1);
- _object5.setPosition(Common::Point(161, 110));
+ _vertLine1.postInit();
+ _vertLine1.setup(826, 7, 1);
+ _vertLine1.setPosition(Common::Point(112, 67));
+ _vertLine1._numFrames = 1;
+ _vertLine1.animate(ANIM_MODE_2);
+
+ _vertLine2.postInit();
+ _vertLine2.setup(826, 5, 1);
+ _vertLine2.setPosition(Common::Point(158, 67));
+ _vertLine2._numFrames = 5;
+ _vertLine2.animate(ANIM_MODE_2);
+
+ _vertLine3.postInit();
+ _vertLine3.setup(826, 6, 1);
+ _vertLine3.setPosition(Common::Point(206, 67));
+ _vertLine3._numFrames = 1;
+ _vertLine3.animate(ANIM_MODE_2);
+
+ _vertLine4.postInit();
+ _vertLine4.setup(826, 8, 1);
+ _vertLine4.setPosition(Common::Point(158, 84));
+ _vertLine4._numFrames = 1;
+ _vertLine4.animate(ANIM_MODE_2);
+
+ _vertLine5.postInit();
+ _vertLine5.setup(826, 4, 1);
+ _vertLine5.setPosition(Common::Point(161, 110));
break;
case 5:
R2_GLOBALS._player.disableControl();
if (_menuId == 4) {
_menuId = 0;
- _object1.remove();
- _object2.remove();
- _object3.remove();
- _object4.remove();
- _object5.remove();
+ _vertLine1.remove();
+ _vertLine2.remove();
+ _vertLine3.remove();
+ _vertLine4.remove();
+ _vertLine5.remove();
_sound2.stop();
_sound3.stop();
@@ -6934,11 +7271,11 @@ void Scene825::doButtonPress(int buttonId) {
*--------------------------------------------------------------------------*/
bool Scene850::Indicator::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 850))
return NamedHotspot::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 851;
scene->setAction(&scene->_sequenceManager1, scene, 851, &R2_GLOBALS._player, &scene->_fibre, NULL);
@@ -6949,11 +7286,11 @@ bool Scene850::Indicator::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene850::LiftDoor::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 202;
scene->setAction(&scene->_sequenceManager1, scene, 202, &R2_GLOBALS._player, this, NULL);
@@ -6962,11 +7299,11 @@ bool Scene850::LiftDoor::startAction(CursorType action, Event &event) {
}
bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 204;
scene->setAction(&scene->_sequenceManager1, scene, 204, &R2_GLOBALS._player, this, NULL);
@@ -6975,30 +7312,32 @@ bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) {
}
bool Scene850::Clamp::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (!R2_GLOBALS.getFlag(7))
return false;
else if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- scene->_object1.postInit();
+ scene->_spark.postInit();
scene->_sceneMode = 850;
- scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this,
+ &scene->_spark, NULL);
return true;
}
}
bool Scene850::Panel::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || R2_GLOBALS.getFlag(7))
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 852;
- scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player,
+ this, &scene->_spark, NULL);
return true;
}
}
@@ -7006,8 +7345,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);
@@ -7084,7 +7423,7 @@ void Scene850::signal() {
case 850:
R2_INVENTORY.setObjectScene(R2_CLAMP, 1);
_clamp.remove();
- _object1.remove();
+ _spark.remove();
R2_GLOBALS._player.enableControl();
break;
case 851:
@@ -7103,85 +7442,88 @@ 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;
+ _controlsScreenNumber = 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(_controlsScreenNumber);
+ 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) {
+ if (scene->_controlsScreenNumber == 1) {
scene->_sceneMode = 2;
scene->signal();
- } else if (scene->_field412 == 2) {
- if (R2_GLOBALS._v565E5 == 0) {
+ } else if (scene->_controlsScreenNumber == 2) {
+ if (!R2_GLOBALS._tractorField) {
scene->_aSound1.play(30);
setup(900, 3, 11);
- R2_GLOBALS._v565E5 = 1;
- if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) {
- scene->_actor2.animate(ANIM_MODE_6, NULL);
+ R2_GLOBALS._tractorField = true;
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70) && (scene->_cable._animateMode != ANIM_MODE_6)) {
+ scene->_cable.animate(ANIM_MODE_6, NULL);
} else {
- if (((scene->_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->_cable._position.x) {
+ if (scene->_cable._position.x == 166 - (R2_GLOBALS._electromagnetZoom / 15)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 4;
- scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_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->_cable._moveDiff.y = (scene->_cable._position.y - (scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2)) / 9;
+ Common::Point pt(scene->_electromagnet._position.x + ((scene->_electromagnet._percent * 49) / 100), scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2);
NpcMover *mover = new NpcMover();
- scene->_actor2.addMover(mover, &pt, this);
- scene->_actor2.animate(ANIM_MODE_6, NULL);
+ scene->_cable.addMover(mover, &pt, this);
+ scene->_cable.animate(ANIM_MODE_6, NULL);
}
}
}
} else {
scene->_aSound1.play(53);
setup(900, 3, 9);
- R2_GLOBALS._v565E5 = 0;
+ R2_GLOBALS._tractorField = false;
- if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8) && (scene->_actor2._animateMode != ANIM_MODE_5)) {
- scene->_actor2.animate(ANIM_MODE_5, NULL);
- } else if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8)) {
- R2_GLOBALS._v565E7 = 0;
- if (scene->_actor2._animateMode != 5) {
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_cable._frame < 8) && (scene->_cable._animateMode != ANIM_MODE_5)) {
+ scene->_cable.animate(ANIM_MODE_5, NULL);
+ } else if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_cable._frame < 8)) {
+ R2_GLOBALS._cableAttached = false;
+ if (scene->_cable._animateMode != 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 5;
- scene->_actor2.animate(ANIM_MODE_5, NULL);
- scene->_actor2._moveDiff.y = (166 - scene->_actor2._position.y) / 9;
- Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._v565E3 / 15));
+ scene->_cable.animate(ANIM_MODE_5, NULL);
+ scene->_cable._moveDiff.y = (166 - scene->_cable._position.y) / 9;
+ Common::Point pt(scene->_cable._position.x, 166 - (R2_GLOBALS._electromagnetZoom / 15));
NpcMover *mover = new NpcMover();
- scene->_actor2.addMover(mover, &pt, this);
+ scene->_cable.addMover(mover, &pt, this);
}
}
}
@@ -7189,61 +7531,61 @@ bool Scene900::Actor4::startAction(CursorType action, Event &event) {
return true;
break;
case 3:
- if (scene->_field412 == 1) {
+ if (scene->_controlsScreenNumber == 1) {
scene->_sceneMode = 3;
scene->signal();
}
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;
case 8:
- SceneItem::display(5, 11, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(5, 11, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case 9:
- SceneItem::display(5, 12, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(5, 12, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
- if (scene->_field412 == 1) {
+ if (scene->_controlsScreenNumber == 1) {
R2_GLOBALS._player.disableControl();
- scene->_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);
- } else if ((scene->_field412 == 2) || (scene->_field412 == 3)) {
+ scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_controls, this ,NULL);
+ } else if ((scene->_controlsScreenNumber == 2) || (scene->_controlsScreenNumber == 3)) {
scene->_sceneMode = 1;
scene->signal();
}
@@ -7252,10 +7594,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->_controlsScreenNumber == 2)) ? 21 : _buttonId + 11,
+ SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1, SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -7272,48 +7612,48 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor1.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
+ _controls.postInit();
+ _controls.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
- _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 = EFFECT_SHADED;
+ _electromagnet.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _actor2.postInit();
- _actor2.setPosition(Common::Point(0, 0));
- _actor2.fixPriority(1);
+ _cable.postInit();
+ _cable.setPosition(Common::Point(0, 0));
+ _cable.fixPriority(1);
if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) {
if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 700) {
- _actor2.setup(901, 3, 2);
- } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._v565E1 == 20) && (R2_GLOBALS._v565E3 == 70)) {
- _actor2.setup(901, 2, 1);
+ _cable.setup(901, 3, 2);
+ } else if (R2_GLOBALS._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
+ _cable.setup(901, 2, 1);
} else {
- _actor2.setup(901, 2, 8);
+ _cable.setup(901, 2, 8);
}
- _actor2.setPosition(Common::Point(171, 145));
- _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setPosition(Common::Point(171, 145));
+ _cable.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
- if (R2_GLOBALS._v565E7 == 0) {
- _actor2.setup(901, 1, 8);
+ _cable.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ if (!R2_GLOBALS._cableAttached) {
+ _cable.setup(901, 1, 8);
// Original set two times the same values: skipped
- _actor2.setPosition(Common::Point((((100 - ((R2_GLOBALS._v565EB * 350) / 100)) * 49) / 100) + ((R2_GLOBALS._v565E9 * _actor3._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3)));
- _actor2.changeZoom(((100 - ((R2_GLOBALS._v565EB * 350) / 100) + 52) / 10) * 10);
+ _cable.setPosition(Common::Point((((100 - ((CABLE700_X * 350) / 100)) * 49) / 100) + ((CABLE700_Y * _electromagnet._percent * 6) / 100) + 89, 166 - (CABLE700_X / 3)));
+ _cable.changeZoom(((100 - ((CABLE700_X * 350) / 100) + 52) / 10) * 10);
}
}
}
- _item1.setDetails(Rect(0, 0, 320, 200), 900, 0, -1, -1, 1, NULL);
+
+ _background.setDetails(Rect(0, 0, 320, 200), 900, 0, -1, -1, 1, NULL);
_sceneMode = 900;
- setAction(&_sequenceManager1, this, 900, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 900, &_controls, NULL);
}
void Scene900::remove() {
@@ -7326,87 +7666,87 @@ void Scene900::remove() {
void Scene900::signal() {
switch (_sceneMode) {
case 1:
- _field412 = 1;
+ _controlsScreenNumber = 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;
+ _controlsScreenNumber = 2;
- _actor5.remove();
- _actor6.remove();
+ _button2.remove();
+ _button3.remove();
- _actor5.sub96135(2);
- if (R2_GLOBALS._v565E5 == 0)
- _actor5.setup(900, 3, 9);
+ _button2.initButton(2);
+ if (!R2_GLOBALS._tractorField)
+ _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;
+ _controlsScreenNumber = 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;
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- R2_GLOBALS._v565E7 = 1;
+ R2_GLOBALS._cableAttached = true;
break;
case 900:
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _actor1.setup(900, 1, 1);
+ _controls.setup(900, 1, 1);
- _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,45 +7765,47 @@ 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 ((_actor2._frame > 1) && (_actor2._animateMode != ANIM_MODE_6))
- _actor2.animate(ANIM_MODE_6, NULL);
+ if (R2_GLOBALS._sceneObjects->contains(&_cable)) {
+ if (R2_GLOBALS._tractorField && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
+ if ((_cable._frame > 1) && (_cable._animateMode != ANIM_MODE_6))
+ _cable.animate(ANIM_MODE_6, NULL);
} else {
- if ((_actor2._frame < 8) && (_actor2._animateMode != ANIM_MODE_5) && (R2_GLOBALS._v565E7 == 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (_sceneMode != 4))
- _actor2.animate(ANIM_MODE_5, NULL);
+ if ((_cable._frame < 8) && (_cable._animateMode != ANIM_MODE_5) && !R2_GLOBALS._cableAttached && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (_sceneMode != 4))
+ _cable.animate(ANIM_MODE_5, NULL);
}
}
- _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.setup(901, 1, 1);
- _actor2.changeZoom(((_actor3._percent + 52) / 10) * 10);
+ if ((R2_GLOBALS._sceneObjects->contains(&_cable)) && R2_GLOBALS._cableAttached && (!_cable._mover) && (_cable._animateMode == ANIM_MODE_NONE)) {
+ _cable.setPosition(Common::Point(_electromagnet._position.x + ((_electromagnet._percent * 49) / 100), _electromagnet._position.y + ((_electromagnet._percent * 3) / 10)));
+ if (R2_GLOBALS._electromagnetZoom >= 75) {
+ _cable.setup(901, 1, 1);
+ _cable.changeZoom(((_electromagnet._percent + 52) / 10) * 10);
} else {
- _actor2.setup(901, 5, 1);
- _actor2.changeZoom(((_actor3._percent / 10) * 10) + 30);
+ _cable.setup(901, 5, 1);
+ _cable.changeZoom(((_electromagnet._percent / 10) * 10) + 30);
}
}
Scene::dispatch();
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index 2f52f9578f..0e68b67ee7 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -85,7 +85,7 @@ class Scene100: public SceneExt {
public:
NamedHotspot _background, _duct, _bed, _desk;
Terminal _terminal;
- SceneActor _bedLights1, _bedLights2, _object3, _object4, _object5;
+ SceneActor _bedLights1, _bedLights2, _tableLocker, _wardrobeTopAnim, _wardrobeColorAnim;
SceneActor _wardrobe;
Door _door;
Table _table;
@@ -102,16 +102,16 @@ public:
class Scene125: public SceneExt {
/* Objects */
- class Object5: public SceneActor {
+ class Food: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
class Icon: public SceneActor {
public:
- int _lookLineNum, _field98;
+ int _lookLineNum, _iconId;
bool _pressed;
- SceneObject _object1, _object2;
+ SceneObject _glyph, _horizLine;
SceneText _sceneText1, _sceneText2;
Icon();
@@ -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,9 @@ public:
ScenePalette _palette;
ASoundExt _sound1;
NamedHotspot _background, _item2, _item3;
- Item4 _item4;
- SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _object7;
+ DiskSlot _diskSlot;
+ SceneActor _starchart1, _starchart2, _starchart3, _starchart4;
+ SceneActor _food, _foodDispenser, _infoDisk;
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
SequenceManager _sequenceManager;
SceneText _sceneText;
@@ -175,7 +176,6 @@ public:
ASound _sound1;
Action1 _action1;
int _frameNumber, _yChange;
- SceneObject _object1, _object2, _object3;
int _lineNum;
SynchronizedList<SceneText *> _creditsList;
public:
@@ -197,11 +197,11 @@ class Scene180: public SceneExt {
private:
void setSceneDelay(int v);
public:
- SpeakerWebbster _webbsterSpeaker;
- SpeakerDutyOfficer _dutyOfficerSpeaker;
- SpeakerTeal _tealSpeaker;
+ SpeakerWebbster180 _webbsterSpeaker;
+ SpeakerDutyOfficer180 _dutyOfficerSpeaker;
+ SpeakerTeal180 _tealSpeaker;
SpeakerGameText _gameTextSpeaker;
- SceneActor _object1, _object2, _object3, _object4, _object5;
+ SceneActor _dutyOfficer, _teal, _webbster, _door, _shipDisplay;
ScenePalette _palette;
SceneText _textList[20];
AnimationPlayerExt _animationPlayer;
@@ -210,10 +210,9 @@ public:
ASoundExt _sound1;
int _frameNumber;
- int _field412, _field480;
- int _field482, _frameInc;
+ bool _helpEnabled;
+ int _frameInc;
int _fontNumber, _fontHeight;
- int _scene180Mode;
public:
Scene180();
@@ -263,6 +262,13 @@ public:
virtual void signal();
};
+class Star: public SceneObject {
+public:
+ int _x100, _y100;
+public:
+ virtual Common::String getClassName() { return "Scene205_Star"; }
+};
+
class Scene205: public SceneExt {
/* Actions */
class Action1: public Action {
@@ -271,28 +277,18 @@ class Scene205: public SceneExt {
public:
virtual void signal();
};
-
- /* Objects */
- class Object: public SceneObject {
- public:
- int _x100, _y100;
- public:
- Object();
-
- virtual void synchronize(Serializer &s);
- };
private:
void setup();
- void processList(Object **ObjList, int count, const Common::Rect &bounds,
+ void processList(Star **ObjList, int count, const Common::Rect &bounds,
int xMultiply, int yMultiply, int xCenter, int yCenter);
void handleText();
public:
AnimationPlayer _animationPlayer;
int _fontHeight;
SceneText _textList[15];
- Object *_objList1[3];
- Object *_objList2[3];
- Object *_objList3[4];
+ Star *_starList1[3];
+ Star *_starList2[3];
+ Star *_starList3[4];
ASound _sound1;
Action1 _action1;
int _yp;
@@ -308,11 +304,10 @@ public:
virtual void dispatch();
};
-
class Scene250: public SceneExt {
class Button: public SceneActor {
public:
- int _floorNumber, _v2;
+ int _floorNumber;
Button();
void setFloor(int floorNumber);
@@ -320,9 +315,10 @@ class Scene250: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412, _field414, _field416, _field418, _field41A;
- NamedHotspot _background, _item2, _item3, _item4;
- Button _button1, _currentFloor;
+ int _currButtonY, _destButtonY, _elevatorSpeed;
+ bool _skippingFl, _skippableFl;
+ NamedHotspot _background, _door, _directionIndicator;
+ Button _destinationFloor, _currentFloor;
Button _floor1, _floor2, _floor3, _floor4, _floor5;
Button _floor6, _floor7, _floor8, _floor9;
ASoundExt _sound1;
@@ -404,8 +400,8 @@ public:
QuinnWorkstation _quinnWorkstation1, _quinnWorkstation2;
SeekerWorkstation _seekerWorkstation;
MirandaWorkstation _mirandaWorkstation1, _mirandaWorkstation2;
- SceneActor _object1, _object2, _object3, _object4, _protocolDisplay;
- SceneActor _object6, _object7, _object8, _object9;
+ SceneActor _atmosphereLeftWindow, _atmosphereRightWindow, _leftVerticalBarsAnim, _rightVerticalBarsAnim, _protocolDisplay;
+ SceneActor _rightTextDisplay, _mirandaScreen, _leftTextDisplay, _quinnScreen;
SceneActor _teal, _soldier, _object12;
Doorway _doorway;
Miranda _miranda;
@@ -430,9 +426,9 @@ public:
class Scene325: public SceneExt {
class Icon: public SceneActor {
public:
- int _lookLineNum, _field98;
+ int _lookLineNum, _iconId;
bool _pressed;
- SceneObject _object1, _object2;
+ SceneObject _glyph, _horizLine;
SceneText _sceneText1, _sceneText2;
Icon();
@@ -452,16 +448,17 @@ private:
void setMessage(int resNum, int lineNum);
Common::String parseMessage(const Common::String &msg);
public:
- int _field412, _iconFontNumber, _field416, _field418;
- int _field41A, _field41C, _field41E, _field420;
+ int _consoleAction, _iconFontNumber, _databasePage, _priorConsoleAction;
+ int _moveCounter, _yChange, _yDirection, _scannerLocation;
int _soundCount, _soundIndex;
int _soundQueue[10];
SpeakerQuinn _quinnSpeaker;
ScenePalette _palette;
- SceneHotspot _background, _item2;
- SceneObject _object1, _object2, _object3, _object4, _object5;
- SceneObject _object6, _object7, _object8, _object9, _object10;
- SceneObject _object11, _object12, _object13;
+ SceneHotspot _background, _terminal;
+ SceneObject _starGrid1, _starGrid2, _starGrid3; // Both starchart & scan grid objects
+ SceneObject _starGrid4, _starGrid5, _starGrid6, _starGrid7;
+ SceneObject _starGrid8, _starGrid9, _starGrid10, _starGrid11;
+ SceneObject _starGrid12, _starGrid13;
SceneObject _objList[4];
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
ASoundExt _sound1;
@@ -478,7 +475,6 @@ public:
virtual void dispatch();
};
-
class Scene400: public SceneExt {
/* Items */
class Terminal: public NamedHotspot {
@@ -526,6 +522,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 +554,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);
};
@@ -553,8 +574,9 @@ class Scene500: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object8: public SceneActor {
- // This classes uses a custom draw method
+ class TransparentDoor: public SceneActor {
+ public:
+ virtual void draw();
};
class Aerosol: public SceneActor {
public:
@@ -572,30 +594,24 @@ 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;
- SceneHotspot _background, _item2;
+ SpeakerSeeker500 _seekerSpeaker;
+ SpeakerQuinn500 _quinnSpeaker;
+ SceneHotspot _background, _airlockCorridor;
ControlPanel _controlPanel;
- SceneActor _object1;
- Object2 _object2;
- Object3 _object3;
+ SceneActor _suits;
+ Seeker _seeker;
+ Suit _suit;
Doorway _doorway;
OxygenTanks _tanks1, _tanks2;
AirLock _airLock;
- Object8 _object8;
+ TransparentDoor _transparentDoor;
Aerosol _aerosol;
SonicStunner _sonicStunner;
Locker1 _locker1;
Locker2 _locker2;
- SceneAreaObject _area1;
- Object _obj1, _obj2, _obj3;
+ PanelDialog _panelDialog;
ASoundExt _sound1;
SequenceManager _sequenceManager1, _sequenceManager2;
public:
@@ -611,61 +627,60 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
-
};
class Scene600 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class CompartmentHotspot : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item4 : public NamedHotspot {
+ class EngineCompartment : public NamedHotspot {
public:
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;
- Item4 _item4;
- Item1 _item5;
- BackgroundSceneObject _object1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- ASoundExt _aSound1;
+ int _roomState;
+ CompartmentHotspot _quantumDrive;
+ CompartmentHotspot _quantumRegulator;
+ CompartmentHotspot _powerNode;
+ EngineCompartment _engineCompartment;
+ CompartmentHotspot _background;
+ SceneActor _stasisArea;
+ SceneActor _laserBeam;
+ SceneActor _computer;
+ SceneActor _stasisField;
+ Smoke _smoke;
+ Doorway _doorway;
+ Laser _laser;
+ Aerosol _aerosol;
+ Scanner _scanner;
+ ASoundExt _sound1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
- byte _fieldAD2[256];
+ byte _pixelMap[256];
Scene600();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -677,60 +692,59 @@ public:
};
class Scene700: public SceneExt {
- class Item11 : public NamedHotspot {
+ class Loft : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item12 : public NamedHotspot {
+ class HandGrip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class LiftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class SuitRoomDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class ControlPanel : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Cable : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class LoftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- NamedHotspot _item8;
- NamedHotspot _item9;
- NamedHotspot _item10;
- Item11 _item11;
- Item12 _item12;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor6 _actor7;
- Actor6 _actor8;
- Actor6 _actor9;
+ NamedHotspot _background;
+ NamedHotspot _debris1;
+ NamedHotspot _debris2;
+ NamedHotspot _debris3;
+ NamedHotspot _debris4;
+ NamedHotspot _restraintCollar;
+ NamedHotspot _storage2;
+ NamedHotspot _storage1;
+ NamedHotspot _stars;
+ NamedHotspot _light;
+ Loft _loft;
+ HandGrip _handGrip;
+ SceneActor _electromagnet;
+ LiftDoor _liftDoor;
+ SuitRoomDoor _suitRoomDoor;
+ ControlPanel _controlPanel;
+ Cable _cable;
+ LoftDoor _loftDoor1;
+ LoftDoor _loftDoor2;
+ LoftDoor _loftDoor3;
+ LoftDoor _loftDoor4;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
- int _field100E;
Scene700();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -792,7 +806,7 @@ class Scene825: public SceneExt {
/* Objects */
class Button: public SceneObject {
public:
- int _buttonId, _v2;
+ int _buttonId;
bool _buttonDown;
SceneText _sceneText;
public:
@@ -805,8 +819,8 @@ class Scene825: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _background, _item2;
- SceneActor _object1, _object2, _object3, _object4, _object5;
+ NamedHotspot _background, _console;
+ SceneActor _vertLine1, _vertLine2, _vertLine3, _vertLine4, _vertLine5;
Button _button1, _button2, _button3, _button4, _button5, _button6;
ASoundExt _sound1, _sound2, _sound3, _sound4;
SequenceManager _sequenceManager1;
@@ -853,7 +867,7 @@ public:
NamedHotspot _background, _eastDoor, _compartment, _sickBayIndicator;
NamedHotspot _liftControls;
Indicator _indicator;
- SceneActor _object1, _fibre;
+ SceneActor _spark, _fibre;
LiftDoor _liftDoor;
SickBayDoor _sickBayDoor;
Clamp _clamp;
@@ -865,30 +879,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;
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor4 _actor5;
- Actor4 _actor6;
- Actor4 _actor7;
- Actor4 _actor8;
- Actor4 _actor9;
- Actor4 _actor10;
+ int _controlsScreenNumber;
+ Common::Point _magnetChangeAmount;
+ NamedHotspot _background;
+ SceneActor _controls;
+ SceneActor _cable;
+ 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 af62ab6916..5ed45efbbe 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.
@@ -20,6 +20,8 @@
*
*/
+#include "graphics/cursorman.h"
+
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
@@ -30,14 +32,458 @@ 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 = 70;
+ 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: Determine correct colors
+ 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: Determine correct colors
+ 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: Determine correct colors
+ 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: Determine correct colors
+ 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)
+ _animationPlayer._endAction = this;
+ } else
+ _animationPlayer.dispatch();
+ }
+
+ Scene::dispatch();
+}
+
+
+/*--------------------------------------------------------------------------
* Scene 1010 - Cutscene: A pixel lost in space!
*
*--------------------------------------------------------------------------*/
+
void Scene1010::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(1010);
-
R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
setZoomPercents(100, 1, 160, 100);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setObjectWrapper(NULL);
@@ -89,18 +535,19 @@ void Scene1010::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1020 -
+ * Scene 1020 - Cutscene - trip in space 2
*
*--------------------------------------------------------------------------*/
+
void Scene1020::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(1020);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == 1010)
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ _sceneBounds = Rect(160, 0, SCREEN_WIDTH + 160, 200);
- R2_GLOBALS._v558B6.set(160, 0, 160, 161);
- R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._sceneManager._previousScene == 1010) {
@@ -214,47 +661,50 @@ void Scene1020::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 1100 -
+ * Scene 1100 - Canyon
*
*--------------------------------------------------------------------------*/
+
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) {
- Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
if (R2_GLOBALS.getFlag(52)) {
+ // The trouper is dead
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 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 {
+ // The trouper is not dead
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 55;
- if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._stripModifier >= 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(329, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(330, scene, R2_GLOBALS._stripManager_lookupList);
} else {
- ++R2_GLOBALS._v565AE;
+ ++R2_GLOBALS._stripModifier;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 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,45 +713,45 @@ 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) {
case R2_NEGATOR_GUN:
if (_visage == 1105) {
+ // Trooper wears the stasis shield
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1114;
- scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL);
return true;
- } else {
+ } else
return SceneActor::startAction(action, event);
- }
break;
case R2_SONIC_STUNNER:
// No break on purpose
case R2_PHOTON_STUNNER:
if (_visage == 1105) {
+ // If trooper wears the stasis shield
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 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) {
+ // Trooper wears his black uniform
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);
- } else {
- scene->setAction(&scene->_sequenceManager1, scene, 1118, &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->_trooper, NULL);
return true;
- } else {
+ } else
return SceneActor::startAction(action, event);
- }
break;
default:
return SceneActor::startAction(action, event);
@@ -309,11 +759,13 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
}
}
-bool Scene1100::Actor18::startAction(CursorType action, Event &event) {
- Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1100::Chief::startAction(CursorType action, Event &event) {
+ // CHECKME: Flag 54 is never set. Guess: the flag means "Chief is dead"
if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
- scene->_field412 = 0;
+ // Talk to chief after the trooper dies
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_nextStripNum = 0;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
@@ -329,20 +781,14 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
else
loadScene(1100);
- if ((R2_GLOBALS._sceneManager._previousScene == 1000) && (!R2_GLOBALS.getFlag(44))) {
+ if ((R2_GLOBALS._sceneManager._previousScene == 1000) && (!R2_GLOBALS.getFlag(44)))
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.left = 0;
- R2_GLOBALS._v5589E.right = 200;
- }
- if (R2_GLOBALS._player._characterScene[1] == 1100)
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 1100)
R2_GLOBALS._sceneManager._previousScene = 1100;
- if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.left = 0;
- R2_GLOBALS._v5589E.right = 200;
- }
SceneExt::postInit();
@@ -357,71 +803,72 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
scalePalette(65, 65, 65);
- _actor2.postInit();
- _actor2.setup(1100, 1, 1);
- _actor2.fixPriority(10);
+ _cloud.postInit();
+ _cloud.setup(1100, 1, 1);
+ _cloud.fixPriority(10);
R2_GLOBALS._scrollFollower = NULL;
- _item3.setDetails(Rect(56, 47, 68, 83), 1100, 7, -1, -1, 1, NULL);
- _item4.setDetails(Rect(167, 132, 183, 167), 1100, 7, -1, -1, 1, NULL);
- _item5.setDetails(Rect(26, 112, 87, 145), 1100, 13, -1, -1, 1, NULL);
- _item7.setDetails(Rect(4, 70, 79, 167), 1100, 16, -1, -1, 1, NULL);
+ _fuana1.setDetails(Rect(56, 47, 68, 83), 1100, 7, -1, -1, 1, NULL);
+ _fauna2.setDetails(Rect(167, 132, 183, 167), 1100, 7, -1, -1, 1, NULL);
+ _bouldersBlockingCave.setDetails(Rect(26, 112, 87, 145), 1100, 13, -1, -1, 1, NULL);
+ _trail.setDetails(Rect(4, 70, 79, 167), 1100, 16, -1, -1, 1, NULL);
R2_GLOBALS._sound1.stop();
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;
- _actor2.setPosition(Common::Point(150, 30));
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1100;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1100;
+ _cloud.setPosition(Common::Point(150, 30));
R2_GLOBALS._sound1.play(93);
R2_GLOBALS._player.postInit();
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);
-
- _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);
-
- _actor1.postInit();
- _actor1.setup(1512, 1, 1);
- _actor1.setPosition(Common::Point(187, -25));
- _actor1.fixPriority(48);
- _actor1._moveDiff.y = 1;
- _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+
+ _trooper.postInit();
+ // Trooper wears his stasis shield
+ _trooper.setup(1105, 3, 1);
+ _trooper.setPosition(Common::Point(312, 165));
+ _trooper._numFrames = 5;
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+
+ _ship.postInit();
+ _ship.setup(1512, 1, 1);
+ _ship.setPosition(Common::Point(187, -25));
+ _ship.fixPriority(48);
+ _ship._moveDiff.y = 1;
+ _ship.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
_sceneMode = 20;
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- _actor2.setPosition(Common::Point(50, 30));
- _field414 = 0;
+ _cloud.setPosition(Common::Point(50, 30));
+ _paletteRefreshStatus = 0;
_palette1.loadPalette(1101);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player._effect = 5;
- R2_GLOBALS._player._field9C = _field312;
+ R2_GLOBALS._player._effect = EFFECT_SHADOW_MAP;
+ R2_GLOBALS._player._shadowMap = _shadowPaletteMap;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player.setPosition(Common::Point(111,-20));
@@ -429,25 +876,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);
- _object2.setup2(1102, 5, 1, 216, 167, 1, 0);
+ _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, 1);
+ _purplePlant.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 = EFFECT_SHADOW_MAP;
+ _shipFormationShadow._shadowMap = _shadowPaletteMap;
R2_GLOBALS._sound1.play(86);
@@ -455,86 +902,95 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else {
- _actor2.setPosition(Common::Point(180, 30));
+ _cloud.setPosition(Common::Point(180, 30));
if (R2_GLOBALS.getFlag(52))
+ // Trooper is dead
R2_GLOBALS._sound1.play(98);
else
+ // Trooper is alive
R2_GLOBALS._sound1.play(95);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- _actor16.postInit();
+ _seeker.postInit();
if (R2_GLOBALS.getFlag(52)) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ // Trooper is dead
+ 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) {
+ // Trooper is alive
+ 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();
+ // If trooper is alive, initialize him
+ _trooper.postInit();
if (R2_GLOBALS.getFlag(53))
- _actor17.setup(1106, 2, 4);
+ // Trooper wears his black uniform
+ _trooper.setup(1106, 2, 4);
else
- _actor17.setup(1105, 4, 4);
+ // Trooper wears a stasis shield
+ _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 isn't wearing the stasis shield
+ _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);
- _actor1.setPosition(Common::Point(187, 45));
- _actor1.fixPriority(48);
- _actor1._moveDiff.y = 1;
- _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+ _ship.postInit();
+ _ship.setup(1512, 1, 1);
+ _ship.setPosition(Common::Point(187, 45));
+ _ship.fixPriority(48);
+ _ship._moveDiff.y = 1;
+ _ship.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
}
- _item6.setDetails(Rect(123, 69, 222, 105), 1100, 13, -1, -1, 1, NULL);
- _item2.setDetails(Rect(0, 0, 480, 46), 1100, 0, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 1100, 40, 41, 42, 1, NULL);
+
+ _boulders.setDetails(Rect(123, 69, 222, 105), 1100, 13, -1, -1, 1, NULL);
+ _sky.setDetails(Rect(0, 0, 480, 46), 1100, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 1100, 40, 41, 42, 1, NULL);
}
void Scene1100::remove() {
@@ -549,30 +1005,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 +1039,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 = EFFECT_SHADED2;
+ _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 = EFFECT_SHADED2;
+ _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,30 +1067,31 @@ 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);
+ R2_GLOBALS._player._effect = EFFECT_NONE;
+ _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);
- R2_GLOBALS._player._effect = 5;
+ setAction(&_sequenceManager1, this, 1106, &_animation, &_laserShot, &_leftImpacts, NULL);
+
+ R2_GLOBALS._player._effect = EFFECT_SHADOW_MAP;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setPosition(Common::Point(-50, 131));
R2_GLOBALS._sound2.play(84);
@@ -647,19 +1104,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);
@@ -667,19 +1124,19 @@ void Scene1100::signal() {
case 20: {
Common::Point pt(187, -13);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _ship.addMover(mover, &pt, this);
}
break;
case 21: {
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);
+ _ship.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 +1150,79 @@ 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_WALK);
_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_WALK);
_stripManager.start(303, this);
break;
+ case 29:
+ case 50:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
case 51:
+ // Trooper no longer wears a statis shield
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:
+ // Trooper is shot to death
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);
- }
+ } else
+ _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;
@@ -769,8 +1231,8 @@ void Scene1100::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 99:
- R2_GLOBALS._player._characterScene[1] = 300;
- R2_GLOBALS._player._characterScene[2] = 300;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 300;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 300;
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._sceneManager.changeScene(300);
break;
@@ -800,10 +1262,10 @@ void Scene1100::signal() {
_stripManager.start3(314, this, _stripManager._lookupList);
break;
case 1116:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
break;
case 1125: {
_sceneMode = 99;
@@ -811,7 +1273,7 @@ void Scene1100::signal() {
R2_GLOBALS._sound1.play(101);
Common::Point pt(187, -13);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _ship.addMover(mover, &pt, this);
}
break;
default:
@@ -822,76 +1284,79 @@ 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;
+ // WORKAROUND: This fixes a problem with an overhang that gets blasted re-appearing
+ if (_animation._frame > 5 && _sceneMode == 13) {
+ _animation._endFrame = 9;
+ if (_animation._frame == 9)
+ // Use one of the scene's background scene objects to copy the scene to the background.
+ // This fixes the problem with the cliff overhang still appearing during the cutscene
+ _rightLandslide.copySceneToBackground();
+ }
+
+ if ((g_globals->_sceneObjects->contains(&_laserShot)) && (_laserShot._visage == 1102) && (_laserShot._strip == 4) && (_laserShot._frame == 1) && (_laserShot._flags & OBJFLAG_HIDING)) {
+ if (_paletteRefreshStatus == 1) {
+ _paletteRefreshStatus = 2;
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);
}
/*--------------------------------------------------------------------------
- * Scene 1200 -
+ * Scene 1200 - Air Ducts Maze
*
*--------------------------------------------------------------------------*/
+
Scene1200::Scene1200() {
- _field412 = 0;
+ _nextCrawlDirection = 0;
_field414 = 0;
_field416 = 0;
_field418 = 0;
_field41A = 0;
- _field41C = 1; //CHECKME: Only if fixup_flag == 6??
+ _fixupMaze = false;
}
void Scene1200::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_nextCrawlDirection);
s.syncAsSint16LE(_field414);
s.syncAsSint16LE(_field416);
s.syncAsSint16LE(_field418);
s.syncAsSint16LE(_field41A);
- s.syncAsSint16LE(_field41C);
-}
-
-Scene1200::Area1::Area1() {
- _field20 = 0;
+ s.syncAsSint16LE(_fixupMaze);
}
-void Scene1200::Area1::synchronize(Serializer &s) {
- SceneArea::synchronize(s);
-
- s.syncAsByte(_field20);
+Scene1200::LaserPanel::LaserPanel() {
}
-void Scene1200::Area1::Actor3::init(int state) {
+void Scene1200::LaserPanel::Jumper::init(int state) {
_state = state;
SceneActor::postInit();
@@ -900,7 +1365,7 @@ void Scene1200::Area1::Actor3::init(int state) {
switch (_state) {
case 1:
- switch (R2_GLOBALS._v56AA6) {
+ switch (R2_GLOBALS._ductMazePanel1State) {
case 1:
setFrame2(2);
setPosition(Common::Point(129, 101));
@@ -912,8 +1377,9 @@ void Scene1200::Area1::Actor3::init(int state) {
default:
break;
}
+ break;
case 2:
- switch (R2_GLOBALS._v56AA7) {
+ switch (R2_GLOBALS._ductMazePanel2State) {
case 1:
setFrame2(2);
setPosition(Common::Point(152, 101));
@@ -929,8 +1395,9 @@ void Scene1200::Area1::Actor3::init(int state) {
default:
break;
}
+ break;
case 3:
- switch (R2_GLOBALS._v56AA8) {
+ switch (R2_GLOBALS._ductMazePanel3State) {
case 1:
setFrame2(3);
setPosition(Common::Point(158, 95));
@@ -942,6 +1409,7 @@ void Scene1200::Area1::Actor3::init(int state) {
default:
break;
}
+ break;
default:
break;
}
@@ -949,31 +1417,31 @@ void Scene1200::Area1::Actor3::init(int state) {
setDetails(1200, 12, -1, -1, 2, (SceneItem *) NULL);
}
-bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) {
+bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
R2_GLOBALS._sound2.play(260);
switch (_state) {
case 1:
- if (R2_GLOBALS._v56AA6 == 1) {
- R2_GLOBALS._v56AA6 = 2;
+ if (R2_GLOBALS._ductMazePanel1State == 1) {
+ R2_GLOBALS._ductMazePanel1State = 2;
setFrame2(3);
setPosition(Common::Point(135, 95));
} else {
- R2_GLOBALS._v56AA6 = 1;
+ R2_GLOBALS._ductMazePanel1State = 1;
setFrame2(2);
setPosition(Common::Point(129, 101));
}
break;
case 2:
- ++R2_GLOBALS._v56AA7;
- if (R2_GLOBALS._v56AA7 == 4)
- R2_GLOBALS._v56AA7 = 1;
+ ++R2_GLOBALS._ductMazePanel2State;
+ if (R2_GLOBALS._ductMazePanel2State == 4)
+ R2_GLOBALS._ductMazePanel2State = 1;
- switch (R2_GLOBALS._v56AA7) {
+ switch (R2_GLOBALS._ductMazePanel2State) {
case 1:
- setFrame2(1);
+ setFrame2(2);
setPosition(Common::Point(152, 101));
break;
case 2:
@@ -989,12 +1457,12 @@ bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) {
}
break;
case 3:
- if (R2_GLOBALS._v56AA8 == 1) {
- R2_GLOBALS._v56AA8 = 2;
+ if (R2_GLOBALS._ductMazePanel3State == 1) {
+ R2_GLOBALS._ductMazePanel3State = 2;
setFrame2(2);
setPosition(Common::Point(175, 101));
} else {
- R2_GLOBALS._v56AA8 = 1;
+ R2_GLOBALS._ductMazePanel3State = 1;
setFrame2(3);
setPosition(Common::Point(158, 95));
}
@@ -1006,121 +1474,68 @@ bool Scene1200::Area1::Actor3::startAction(CursorType action, Event &event) {
Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
scene->_field418 = 0;
- if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 1;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 2;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
scene->_field418 = 3;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 4;
return true;
}
-void Scene1200::Area1::postInit(SceneObjectList *OwnerList) {
+void Scene1200::LaserPanel::postInit(SceneObjectList *OwnerList) {
Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
scene->_field41A = 1;
R2_GLOBALS._events.setCursor(CURSOR_USE);
- proc12(1003, 1, 1, 100, 40);
- proc13(1200, 11, -1, -1);
+ setup2(1003, 1, 1, 100, 40);
+ setup3(1200, 11, -1, -1);
R2_GLOBALS._sound2.play(259);
- _actor3.init(1);
- _actor4.init(2);
- _actor5.init(3);
+ _jumper1.init(1);
+ _jumper2.init(2);
+ _jumper3.init(3);
R2_GLOBALS._player._canWalk = false;
}
-void Scene1200::Area1::remove() {
+void Scene1200::LaserPanel::remove() {
Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
scene->_field41A = 0;
- warning("Unexpected _sceneAreas.remove() call");
-// scene->_sceneAreas.remove(&_actor3);
-// scene->_sceneAreas.remove(&_actor4);
-// scene->_sceneAreas.remove(&_actor5);
- _actor3.remove();
- _actor4.remove();
- _actor5.remove();
-
- // sub201EA
- R2_GLOBALS._sceneItems.remove((SceneItem *)this);
- _actor2.remove();
- SceneArea::remove();
- R2_GLOBALS._insetUp--;
- //
-
+ scene->_sceneAreas.remove(&_jumper1);
+ scene->_sceneAreas.remove(&_jumper2);
+ scene->_sceneAreas.remove(&_jumper3);
+ _jumper1.remove();
+ _jumper2.remove();
+ _jumper3.remove();
+
+ ModalWindow::remove();
R2_GLOBALS._player._canWalk = true;
}
-void Scene1200::Area1::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) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
- }
- } 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);
- remove();
- }
- }
-}
-
-void Scene1200::Area1::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::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- _actor2.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
-}
-
void Scene1200::postInit(SceneObjectList *OwnerList) {
- Rect tmpRect;
-
loadScene(1200);
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene < 3200)
R2_GLOBALS._sound1.play(257);
- _field412 = 1;
+ _nextCrawlDirection = CRAWL_EAST;
_field414 = 0;
_field416 = 0;
_field418 = 0;
_field41A = 0;
- _field41C = 0;
- if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 1;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 2;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
_field418 = 3;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 4;
R2_GLOBALS._player.postInit();
@@ -1128,19 +1543,16 @@ void Scene1200::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setup(3156, 1, 6);
R2_GLOBALS._player.setPosition(Common::Point(160, 70));
R2_GLOBALS._player._numFrames = 10;
- R2_GLOBALS._player._oldCharacterScene[3] = 1200;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1200;
_actor1.postInit();
_actor1.hide();
- tmpRect.set(110, 20, 210, 120);
- _object1.sub9EDE8(tmpRect);
+ _mazeUI.setDisplayBounds(Rect(110, 20, 210, 120));
- _object1.sub51AE9(1);
- _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
- warning("int unk = set_pane_p(_paneNumber);");
- _object1.sub51B02();
- warning("set_pane_p(unk);");
+ _mazeUI.postInit();
+ _mazeUI.load(1);
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
R2_GLOBALS._player.enableControl();
_item1.setDetails(Rect(0, 0, 320, 200), 1200, 0, 1, 2, 1, NULL);
@@ -1158,7 +1570,7 @@ void Scene1200::signal() {
// No break on purpose
case 1203:
R2_GLOBALS._player.enableControl();
- warning("_eventManager.waitEvent()");
+ // CHECKME: The original is calling _eventManager.waitEvent();
_sceneMode = 2;
break;
case 10:
@@ -1337,7 +1749,7 @@ void Scene1200::signal() {
case 111:
// No break on purpose
case 116:
- R2_GLOBALS._player.setup(3157, 3, 1);
+ R2_GLOBALS._player.setup(3157, 4, 1);
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
case 78:
@@ -1380,7 +1792,7 @@ void Scene1200::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
default:
- warning("_eventManager.waitEvent()");
+ // CHECKME: The original is walling _eventManager.waitEvent();
_sceneMode = 2;
break;
}
@@ -1396,61 +1808,63 @@ void Scene1200::process(Event &event) {
return;
if (event.eventType == EVENT_BUTTON_DOWN) {
- _object1.sub9EE22(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4);
- int unk = _object1.sub51AF8(event.mousePos);
+ Common::Point cellPos = R2_GLOBALS._ventCellPos;
+ _mazeUI.pixelToCellXY(cellPos);
+
+ int cellId = _mazeUI.getCellFromPixelXY(event.mousePos);
switch (R2_GLOBALS._events.getCursor()) {
- case CURSOR_ARROW:
+ case CURSOR_WALK:
event.handled = true;
if ((event.mousePos.x > 179) && (event.mousePos.x < 210) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
- sub9DAD6(1);
+ startCrawling(CRAWL_EAST);
if ((event.mousePos.x > 109) && (event.mousePos.x < 140) && (event.mousePos.y > 50) && (event.mousePos.y < 89))
- sub9DAD6(2);
+ startCrawling(CRAWL_WEST);
if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 89) && (event.mousePos.y < 120))
- sub9DAD6(3);
+ startCrawling(CRAWL_SOUTH);
if ((event.mousePos.x > 140) && (event.mousePos.x < 179) && (event.mousePos.y > 19) && (event.mousePos.y < 50))
- sub9DAD6(4);
+ startCrawling(CRAWL_NORTH);
break;
case CURSOR_USE:
- if (unk > 36) {
- if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 33))
- || ((R2_GLOBALS._v56AA2 == 7) && (R2_GLOBALS._v56AA4 == 33))
- || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 41))
- || ((R2_GLOBALS._v56AA2 == 5) && (R2_GLOBALS._v56AA4 == 5))
- || ((R2_GLOBALS._v56AA2 == 13) && (R2_GLOBALS._v56AA4 == 21))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 21))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 5))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 9))
- || ((R2_GLOBALS._v56AA2 == 29) && (R2_GLOBALS._v56AA4 == 17))
- || ((R2_GLOBALS._v56AA2 == 33) && (R2_GLOBALS._v56AA4 == 17))
- || ((R2_GLOBALS._v56AA2 == 35) && (R2_GLOBALS._v56AA4 == 17))
- || ((R2_GLOBALS._v56AA2 == 41) && (R2_GLOBALS._v56AA4 == 21)) ) {
- _area1.postInit();
+ if (cellId > 36) {
+ if ( ((cellPos.x == 3) && (cellPos.y == 33))
+ || ((cellPos.x == 7) && (cellPos.y == 33))
+ || ((cellPos.x == 33) && (cellPos.y == 41))
+ || ((cellPos.x == 5) && (cellPos.y == 5))
+ || ((cellPos.x == 13) && (cellPos.y == 21))
+ || ((cellPos.x == 17) && (cellPos.y == 21))
+ || ((cellPos.x == 17) && (cellPos.y == 5))
+ || ((cellPos.x == 17) && (cellPos.y == 9))
+ || ((cellPos.x == 29) && (cellPos.y == 17))
+ || ((cellPos.x == 33) && (cellPos.y == 17))
+ || ((cellPos.x == 35) && (cellPos.y == 17))
+ || ((cellPos.x == 41) && (cellPos.y == 21)) ) {
+ _laserPanel.postInit();
event.handled = true;
}
}
- if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
- if ( ((R2_GLOBALS._v56AA2 == 3) && (R2_GLOBALS._v56AA4 == 9))
- || ((R2_GLOBALS._v56AA2 == 11) && (R2_GLOBALS._v56AA4 == 27))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 7))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 27))
- || ((R2_GLOBALS._v56AA2 == 17) && (R2_GLOBALS._v56AA4 == 33))
- || (R2_GLOBALS._v56AA2 == 33) ) {
- switch (R2_GLOBALS._v56AA2) {
+ if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
+ if ( ((cellPos.x == 3) && (cellPos.y == 9))
+ || ((cellPos.x == 11) && (cellPos.y == 27))
+ || ((cellPos.x == 17) && (cellPos.y == 7))
+ || ((cellPos.x == 17) && (cellPos.y == 27))
+ || ((cellPos.x == 17) && (cellPos.y == 33))
+ || (cellPos.x == 33) ) {
+ switch (cellPos.x) {
case 3:
R2_GLOBALS._sceneManager.changeScene(3150);
break;
case 33:
- if (R2_GLOBALS._v56AA1 >= 4)
+ if (R2_GLOBALS._scientistConvIndex >= 4)
R2_GLOBALS._sceneManager.changeScene(3250);
else
- SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(1200, 6, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
default:
- SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
}
event.handled = true;
@@ -1458,23 +1872,25 @@ void Scene1200::process(Event &event) {
}
break;
case CURSOR_LOOK:
- if ((unk == 1) || (unk == 4) || (unk == 11) || (unk == 14)) {
+ if ((cellId == 1) || (cellId == 4) || (cellId == 11) || (cellId == 14)) {
event.handled = true;
- switch (R2_GLOBALS._v56AA2) {
+ switch (cellPos.x) {
case 3:
- SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- break;
+ // It was your cell.
+ SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ break;
case 9:
R2_GLOBALS._sceneManager.changeScene(3240);
break;
case 11:
- if (R2_GLOBALS._v56AA4 == 27)
+ if (cellPos.y == 27)
R2_GLOBALS._sceneManager.changeScene(3210);
else
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ // A vent grill
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 17:
- switch (R2_GLOBALS._v56AA4) {
+ switch (cellPos.y) {
case 5:
R2_GLOBALS._sceneManager.changeScene(3230);
break;
@@ -1485,20 +1901,23 @@ void Scene1200::process(Event &event) {
R2_GLOBALS._sceneManager.changeScene(3200);
break;
default:
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ // A vent grill
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
}
+ break;
case 33:
R2_GLOBALS._sceneManager.changeScene(3245);
break;
default:
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
}
}
- if (unk > 36) {
+ if (cellId > 36) {
+ // "An anti-pest laser"
event.handled = true;
- SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
break;
case CURSOR_TALK:
@@ -1514,81 +1933,77 @@ void Scene1200::process(Event &event) {
}
switch (event.kbd.keycode) {
- case Common::KEYCODE_1:
- warning("FIXME: keycode = 0x4800");
- sub9DAD6(4);
+ case Common::KEYCODE_KP8:
+ case Common::KEYCODE_UP:
+ startCrawling(CRAWL_NORTH);
break;
- case Common::KEYCODE_2:
- warning("FIXME: keycode = 0x4B00");
- sub9DAD6(2);
+ case Common::KEYCODE_KP4:
+ case Common::KEYCODE_LEFT:
+ startCrawling(CRAWL_WEST);
break;
- case Common::KEYCODE_3:
- warning("FIXME: keycode = 0x4D00");
- sub9DAD6(1);
+ case Common::KEYCODE_KP6:
+ case Common::KEYCODE_RIGHT:
+ startCrawling(CRAWL_EAST);
break;
- case Common::KEYCODE_4:
- warning("FIXME: keycode = 0x5000");
- sub9DAD6(3);
+ case Common::KEYCODE_KP2:
+ case Common::KEYCODE_DOWN:
+ startCrawling(CRAWL_SOUTH);
break;
default:
event.handled = false;
return;
break;
}
- } else {
+ } else
return;
- }
}
void Scene1200::dispatch() {
Rect tmpRect;
Scene::dispatch();
- if (_field41C != 0) {
- _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
- warning("int unk = set_pane_p(_paneNumber);");
- _object1.sub51B02();
- warning("_gfxManager.sub294AC(unk);");
- warning("tmpRect.sub14DF3();");
- _field41C = 0;
+
+ if (_fixupMaze) {
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
+ //_mazeUI.draw();
+ _fixupMaze = false;
}
if (_field414 != 0) {
tmpRect.set(110, 20, 210, 120);
_field414--;
- switch (_field412 - 1) {
- case 0:
- R2_GLOBALS._v56AA2 += 2;
+
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ R2_GLOBALS._ventCellPos.x += 2;
break;
- case 1:
- R2_GLOBALS._v56AA2 -= 2;
+ case CRAWL_WEST:
+ R2_GLOBALS._ventCellPos.x -= 2;
break;
- case 2:
- R2_GLOBALS._v56AA4 += 2;
+ case CRAWL_SOUTH:
+ R2_GLOBALS._ventCellPos.y += 2;
break;
- case 3:
- R2_GLOBALS._v56AA4 -= 2;
+ case CRAWL_NORTH:
+ R2_GLOBALS._ventCellPos.y -= 2;
break;
default:
break;
}
- _object1.sub51AFD(Common::Point(R2_GLOBALS._v56AA2, R2_GLOBALS._v56AA4));
- warning("int unk = set_pane_p(_paneNumber);");
- _object1.sub51B02();
- warning("_gfxManager.sub294AC(unk);");
- warning("tmpRect.sub14DF3();");
+
+ _mazeUI.setMazePosition(R2_GLOBALS._ventCellPos);
+ //_mazeUI.draw();
if (_field416 != 0) {
- switch(_field412 - 1) {
- case 0:
+ switch(_nextCrawlDirection) {
+ case CRAWL_EAST:
R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x - 2, R2_GLOBALS._player._position.y));
break;
- case 1:
+ case CRAWL_WEST:
R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x + 2, R2_GLOBALS._player._position.y));
break;
- case 2:
+ case CRAWL_SOUTH:
R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y - 2));
break;
- case 3:
+ case CRAWL_NORTH:
R2_GLOBALS._player.setPosition(Common::Point(R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 2));
break;
default:
@@ -1608,14 +2023,198 @@ void Scene1200::saveCharacter(int characterIndex) {
SceneExt::saveCharacter(characterIndex);
}
+void Scene1200::startCrawling(CrawlDirection dir) {
+ Common::Point cellPos = R2_GLOBALS._ventCellPos;
+ _mazeUI.pixelToCellXY(cellPos);
+
+ switch (dir) {
+ case CRAWL_EAST:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(200, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(200, 88)) > 36))
+ && ( ((cellPos.x == 3) && (cellPos.y == 33) && (_field418 != 4))
+ || ((cellPos.x == 13) && (cellPos.y == 21) && (_field418 != 2))
+ || ((cellPos.x == 29) && (cellPos.y == 17) && (_field418 != 1))
+ || ((cellPos.x == 33) && (cellPos.y == 41)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1200;
+ setAction(&_sequenceManager, this, 1200, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(200, 69)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 15;
+ else
+ _sceneMode = 10;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 76;
+ else
+ _sceneMode = 75;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 101;
+ else
+ _sceneMode = 100;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 111;
+ else
+ _sceneMode = 110;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 1;
+ signal();
+ }
+ break;
+ case CRAWL_WEST:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(120, 50)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(120, 88)) > 36))
+ && ( ((cellPos.x == 7) && (cellPos.y == 33) && (_field418 != 4))
+ || ((cellPos.x == 17) && (cellPos.y == 21) && (_field418 != 2))
+ || ((cellPos.x == 33) && (cellPos.y == 17) && (_field418 != 1))
+ || ((cellPos.x == 5) && (cellPos.y == 5)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1201;
+ setAction(&_sequenceManager, this, 1201, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(120, 69)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 56;
+ else
+ _sceneMode = 55;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 25;
+ else
+ _sceneMode = 20;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 91;
+ else
+ _sceneMode = 90;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 121;
+ else
+ _sceneMode = 120;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 2;
+ signal();
+ }
+ break;
+ case CRAWL_SOUTH:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 110)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 110)) > 36))
+ && ( ((cellPos.x == 17) && (cellPos.y == 5) && (_field418 != 3))
+ || ((cellPos.x == 41) && (cellPos.y == 21)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1203;
+ setAction(&_sequenceManager, this, 1203, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 110)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 51;
+ else
+ _sceneMode = 50;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 81;
+ else
+ _sceneMode = 80;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 35;
+ else
+ _sceneMode = 30;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 116;
+ else
+ _sceneMode = 115;
+ break;
+ default:
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 3;
+ signal();
+ }
+ break;
+ case CRAWL_NORTH:
+ if ( ((_mazeUI.getCellFromPixelXY(Common::Point(140, 30)) > 36) || (_mazeUI.getCellFromPixelXY(Common::Point(178, 30)) > 36))
+ && ( ((cellPos.x == 17) && (cellPos.y == 9) && (_field418 != 3))
+ || ((cellPos.x == 35) && (cellPos.y == 17)) )
+ ) {
+ R2_GLOBALS._player.disableControl();
+ _sceneMode = 1202;
+ setAction(&_sequenceManager, this, 1202, &_actor1, NULL);
+ } else if (_mazeUI.getCellFromPixelXY(Common::Point(160, 30)) == 36) {
+ switch (_nextCrawlDirection) {
+ case CRAWL_EAST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 61;
+ else
+ _sceneMode = 60;
+ break;
+ case CRAWL_WEST:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 71;
+ else
+ _sceneMode = 70;
+ break;
+ case CRAWL_SOUTH:
+ if (R2_GLOBALS._player._visage == 3156)
+ _sceneMode = 96;
+ else
+ _sceneMode = 95;
+ break;
+ case CRAWL_NORTH:
+ if (R2_GLOBALS._player._visage == 3155)
+ _sceneMode = 45;
+ else
+ _sceneMode = 40;
+ break;
+ default:
+ _sceneMode = 1;
+ R2_GLOBALS._player.setup(3156, 4, 6);
+ break;
+ }
+ R2_GLOBALS._player.disableControl();
+ _nextCrawlDirection = 4;
+ signal();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
/*--------------------------------------------------------------------------
* Scene 1337 - Card game
*
*--------------------------------------------------------------------------*/
Scene1337::unkObj1337sub1::unkObj1337sub1() {
- _field34 = 0;
- _field36 = Common::Point(0, 0);
+ _cardId = 0;
+ _stationPos = Common::Point(0, 0);
}
void Scene1337::unkObj1337sub1::synchronize(Serializer &s) {
@@ -1636,42 +2235,50 @@ void Scene1337::unkObj1337_1::synchronize(Serializer &s) {
Scene1337::Scene1337() {
_autoplay = false;
- _field3E24 = 0;
+ _cardsAvailableNumb = 0;
_field3E26 = 0;
for (int i = 0; i < 100; i++)
- _field3E28[i] = 0;
+ _availableCardsPile[i] = 0;
- _field423C = 0;
- _field423E = 0;
+ _shuffleEndedFl = false;
+ _currentPlayerNumb = 0;
_field4240 = 0;
_field4242 = 0;
- _field4244 = 0;
- _field4246 = 0;
+ _field4244 = false;
+ _field4246 = false;
_field4248 = 0;
_field424A = 0;
- _field424C = 0;
- _field424E = 0;
+ _instructionsDisplayedFl = 0;
+ _instructionsWaitCount = 0;
+
+ _unkFctPtr412 = nullptr;
+ _field3EF0 = nullptr;
+ _field3EF4 = nullptr;
+ _field3EF8 = nullptr;
}
void Scene1337::synchronize(Serializer &s) {
warning("STUBBED: Scene1337::synchronize()");
}
-void Scene1337::Action1337::subD18B5(int resNum, int stripNum, int frameNum) {
- warning("STUBBED: Action1337::subD18B5()");
-}
-
-void Scene1337::Action1337::skipFrames(int32 skipCount) {
+void Scene1337::Action1337::waitFrames(int32 frameCount) {
uint32 firstFrameNumber = g_globals->_events.getFrameNumber();
- uint32 tmpFrameNumber = firstFrameNumber;
-
- while (tmpFrameNumber < firstFrameNumber + skipCount)
- tmpFrameNumber = g_globals->_events.getFrameNumber();
+ uint32 curFrame = firstFrameNumber;
+ uint32 destFrame = firstFrameNumber + frameCount;
- warning("_eventManager.waitEvent(-1)");
+ while ((curFrame < destFrame) && !g_vm->shouldQuit()) {
+ TsAGE::Event event;
+ g_globals->_events.getEvent(event);
+ curFrame = g_globals->_events.getFrameNumber();
+ }
+
+ // CHECKME: The original is calling _eventManager.waitEvent();
}
+/**
+ * Display instructions
+ */
void Scene1337::Action1::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
@@ -1682,393 +2289,392 @@ void Scene1337::Action1::signal() {
scene->actionDisplay(1331, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 8, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[1]._arr2[0]._field34 = 2;
- scene->_arrunkObj1337[1]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[0]._field34);
- scene->_arrunkObj1337[1]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[0]);
-
- scene->_arrunkObj1337[1]._arr2[1]._field34 = 3;
- scene->_arrunkObj1337[1]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[1]._field34);
- scene->_arrunkObj1337[1]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[1]);
-
- scene->_arrunkObj1337[2]._arr2[0]._field34 = 4;
- scene->_arrunkObj1337[2]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[0]._field34);
- scene->_arrunkObj1337[2]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[0]);
-
- scene->_arrunkObj1337[3]._arr2[0]._field34 = 5;
- scene->_arrunkObj1337[3]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[0]._field34);
- scene->_arrunkObj1337[3]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[0]);
-
- scene->_arrunkObj1337[3]._arr2[1]._field34 = 6;
- scene->_arrunkObj1337[3]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[1]._field34);
- scene->_arrunkObj1337[3]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[1]);
-
- scene->_arrunkObj1337[3]._arr2[2]._field34 = 7;
- scene->_arrunkObj1337[3]._arr2[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[2]._field34);
- scene->_arrunkObj1337[3]._arr2[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[2]);
-
- scene->_arrunkObj1337[0]._arr2[0]._field34 = 8;
- scene->_arrunkObj1337[0]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[0]._field34);
- scene->_arrunkObj1337[0]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[0]);
-
- scene->_arrunkObj1337[0]._arr2[1]._field34 = 9;
- scene->_arrunkObj1337[0]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[1]._field34);
- scene->_arrunkObj1337[0]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[1]);
+ scene->_gameBoardSide[1]._outpostStation[0]._cardId = 2;
+ scene->_gameBoardSide[1]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[1]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[1]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[1]._outpostStation[0]);
+
+ scene->_gameBoardSide[1]._outpostStation[1]._cardId = 3;
+ scene->_gameBoardSide[1]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[1]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[1]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[1]._outpostStation[1]);
+
+ scene->_gameBoardSide[2]._outpostStation[0]._cardId = 4;
+ scene->_gameBoardSide[2]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[0]._cardId);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[0]);
+
+ scene->_gameBoardSide[3]._outpostStation[0]._cardId = 5;
+ scene->_gameBoardSide[3]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[0]);
+
+ scene->_gameBoardSide[3]._outpostStation[1]._cardId = 6;
+ scene->_gameBoardSide[3]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[1]);
+
+ scene->_gameBoardSide[3]._outpostStation[2]._cardId = 7;
+ scene->_gameBoardSide[3]._outpostStation[2]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[2]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[2]);
+
+ scene->_gameBoardSide[0]._outpostStation[0]._cardId = 8;
+ scene->_gameBoardSide[0]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[0]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[0]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[0]._outpostStation[0]);
+
+ scene->_gameBoardSide[0]._outpostStation[1]._cardId = 9;
+ scene->_gameBoardSide[0]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[0]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[0]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[0]._outpostStation[1]);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = 2;
- scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[1]._field34);
- scene->_arrunkObj1337[2]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
-
- scene->_arrunkObj1337[2]._arr2[2]._field34 = 3;
- scene->_arrunkObj1337[2]._arr2[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[2]._field34);
- scene->_arrunkObj1337[2]._arr2[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[2]);
-
- scene->_arrunkObj1337[2]._arr2[3]._field34 = 5;
- scene->_arrunkObj1337[2]._arr2[3]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[3]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[3]._field34);
- scene->_arrunkObj1337[2]._arr2[3]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[3]);
-
- scene->_arrunkObj1337[2]._arr2[4]._field34 = 6;
- scene->_arrunkObj1337[2]._arr2[4]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[4]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[4]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[4]._field34);
- scene->_arrunkObj1337[2]._arr2[4]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[4]);
-
- scene->_arrunkObj1337[2]._arr2[5]._field34 = 7;
- scene->_arrunkObj1337[2]._arr2[5]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[5]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[5]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[5]._field34);
- scene->_arrunkObj1337[2]._arr2[5]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[5]);
-
- scene->_arrunkObj1337[2]._arr2[6]._field34 = 8;
- scene->_arrunkObj1337[2]._arr2[6]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[6]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[6]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[6]._field34);
- scene->_arrunkObj1337[2]._arr2[6]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[6]);
-
- scene->_arrunkObj1337[2]._arr2[7]._field34 = 9;
- scene->_arrunkObj1337[2]._arr2[7]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[7]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[7]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[7]._field34);
- scene->_arrunkObj1337[2]._arr2[7]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[7]);
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = 2;
+ scene->_gameBoardSide[2]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
+
+ scene->_gameBoardSide[2]._outpostStation[2]._cardId = 3;
+ scene->_gameBoardSide[2]._outpostStation[2]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[2]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[2]);
+
+ scene->_gameBoardSide[2]._outpostStation[3]._cardId = 5;
+ scene->_gameBoardSide[2]._outpostStation[3]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[3]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[3]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[3]);
+
+ scene->_gameBoardSide[2]._outpostStation[4]._cardId = 6;
+ scene->_gameBoardSide[2]._outpostStation[4]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[4]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[4]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[4]);
+
+ scene->_gameBoardSide[2]._outpostStation[5]._cardId = 7;
+ scene->_gameBoardSide[2]._outpostStation[5]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[5]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[5]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[5]);
+
+ scene->_gameBoardSide[2]._outpostStation[6]._cardId = 8;
+ scene->_gameBoardSide[2]._outpostStation[6]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[6]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[6]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[6]);
+
+ scene->_gameBoardSide[2]._outpostStation[7]._cardId = 9;
+ scene->_gameBoardSide[2]._outpostStation[7]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[7]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[7]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[7]);
scene->_aSound1.play(62);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(120);
- scene->_arrunkObj1337[2]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[1]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[2]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[3]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[4]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[5]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[6]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[7]._object1.remove();
+ waitFrames(120);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[2]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[3]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[4]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[5]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[6]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[7]._card.remove();
- scene->_arrunkObj1337[1]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[1]._arr2[1]._object1.remove();
+ scene->_gameBoardSide[1]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[1]._outpostStation[1]._card.remove();
- scene->_arrunkObj1337[3]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[3]._arr2[1]._object1.remove();
- scene->_arrunkObj1337[3]._arr2[2]._object1.remove();
+ scene->_gameBoardSide[3]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[3]._outpostStation[1]._card.remove();
+ scene->_gameBoardSide[3]._outpostStation[2]._card.remove();
- scene->_arrunkObj1337[0]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[0]._arr2[1]._object1.remove();
+ scene->_gameBoardSide[0]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[0]._outpostStation[1]._card.remove();
scene->_background2.setup2(1332, 5, 1, 165, 95, 110, 1);
- scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[2]._arr1[0]._field34 = 30;
- scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[0]);
-
- scene->_arrunkObj1337[2]._arr1[1]._field34 = 16;
- scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[1]);
-
- scene->_arrunkObj1337[2]._arr1[2]._field34 = 1;
- scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[2]);
-
- scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[0]._card.setPosition(scene->_gameBoardSide[1]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[0]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[1]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[1]._card.setPosition(scene->_gameBoardSide[1]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[1]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[1]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[2]._card.setPosition(scene->_gameBoardSide[1]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[2]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[2]._card.fixPriority(170);
+
+ scene->_gameBoardSide[2]._handCard[0]._cardId = 30;
+ scene->_gameBoardSide[2]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[0]._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[0]);
+
+ scene->_gameBoardSide[2]._handCard[1]._cardId = 16;
+ scene->_gameBoardSide[2]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[1]._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[1]);
+
+ scene->_gameBoardSide[2]._handCard[2]._cardId = 1;
+ scene->_gameBoardSide[2]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[2]._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[2]);
+
+ scene->_gameBoardSide[3]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[0]._card.setPosition(scene->_gameBoardSide[3]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[0]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[3]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[1]._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[1]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[3]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[2]._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[2]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[2]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[0]._card.setPosition(scene->_gameBoardSide[0]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[0]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[1]._card.setPosition(scene->_gameBoardSide[0]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[1]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[2]._card.setPosition(scene->_gameBoardSide[0]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[2]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[2]._card.fixPriority(170);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
Common::Point pt(91, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
}
break;
case 2: {
- scene->_arrunkObj1337[2]._arr1[3]._field34 = 2;
- scene->_arrunkObj1337[2]._arr1[3]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[3]._object1.fixPriority(170);
+ scene->_gameBoardSide[2]._handCard[3]._cardId = 2;
+ scene->_gameBoardSide[2]._handCard[3]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[3]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[3]._card.setPosition(scene->_gameBoardSide[2]._handCard[3]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[3]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[3]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[3]._card.fixPriority(170);
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[3]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[3]);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 12, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = 1;
- scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[1]._object1.hide();
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = 1;
+ scene->_gameBoardSide[2]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.hide();
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[2]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[2]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[2]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[2]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[2]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[2]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._outpostStation[1]._stationPos, this);
}
break;
case 3: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
scene->_aSound1.play(59);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = scene->_arrunkObj1337[2]._arr1[3]._field34;
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = scene->_gameBoardSide[2]._handCard[3]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[3]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[3]._object1._frame);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[3]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[3]._card._frame);
- scene->_arrunkObj1337[2]._arr1[3]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[3]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[3]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[3]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[3]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._outpostStation[1]._stationPos, this);
}
break;
case 4: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
scene->_aSound1.play(59);
- scene->_item7._field34 = 1;
- scene->_item7._object1.hide();
+ scene->_discardPile._cardId = 1;
+ scene->_discardPile._card.hide();
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 5: {
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
- scene->_item7._object1.postInit();
- scene->_item7._object1.setVisage(1332);
- scene->_item7._object1.setPosition(scene->_item7._field36, 0);
- scene->setAnimationInfo(&scene->_item7);
+ scene->_discardPile._card.postInit();
+ scene->_discardPile._card.setVisage(1332);
+ scene->_discardPile._card.setPosition(scene->_discardPile._stationPos, 0);
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 14, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+ scene->_gameBoardSide[2]._delayPile[0]._card.postInit();
+ scene->_gameBoardSide[2]._delayPile[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._delayPile[0]._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._delayPile[0]._card.hide();
- scene->_arrunkObj1337[3]._arr1[2]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[2].remove();
+ scene->_gameBoardSide[3]._handCard[2]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[2].remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this);
}
break;
case 6: {
- scene->_item2._object1.hide();
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 21;
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_animatedCard._card.hide();
+ scene->_gameBoardSide[2]._delayPile[0]._cardId = 21;
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayPile[0]);
scene->_aSound1.play(57);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
int tmpVal = 15;
@@ -2077,89 +2683,89 @@ void Scene1337::Action1::signal() {
for (i = 0; i <= 7; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 90), 0);
- scene->_arrObject1[i].setStrip(3);
- scene->_arrObject1[i].fixPriority(190);
-
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 90), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
- }
-
- scene->_arrObject1[0].setFrame(1);
- scene->_arrObject1[1].setFrame(3);
- scene->_arrObject1[2].setFrame(6);
- scene->_arrObject1[3].setFrame(8);
- scene->_arrObject1[4].setFrame(9);
- scene->_arrObject1[5].setFrame(10);
- scene->_arrObject1[6].setFrame(11);
- scene->_arrObject1[7].setFrame(12);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_upperDisplayCard[i].setStrip(3);
+ scene->_upperDisplayCard[i].fixPriority(190);
+
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
+ }
+
+ scene->_upperDisplayCard[0].setFrame(1);
+ scene->_upperDisplayCard[1].setFrame(3);
+ scene->_upperDisplayCard[2].setFrame(6);
+ scene->_upperDisplayCard[3].setFrame(8);
+ scene->_upperDisplayCard[4].setFrame(9);
+ scene->_upperDisplayCard[5].setFrame(10);
+ scene->_upperDisplayCard[6].setFrame(11);
+ scene->_upperDisplayCard[7].setFrame(12);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
- scene->_arrObject1[4].remove();
- scene->_arrObject1[5].remove();
- scene->_arrObject1[6].remove();
- scene->_arrObject1[7].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
+ scene->_upperDisplayCard[4].remove();
+ scene->_upperDisplayCard[5].remove();
+ scene->_upperDisplayCard[6].remove();
+ scene->_upperDisplayCard[7].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
- scene->_arrObject2[4].remove();
- scene->_arrObject2[5].remove();
- scene->_arrObject2[6].remove();
- scene->_arrObject2[7].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
+ scene->_lowerDisplayCard[4].remove();
+ scene->_lowerDisplayCard[5].remove();
+ scene->_lowerDisplayCard[6].remove();
+ scene->_lowerDisplayCard[7].remove();
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr3[0]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._delayPile[0]._cardId;
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+ scene->_gameBoardSide[2]._delayPile[0]._cardId = 0;
+ scene->_gameBoardSide[2]._delayPile[0]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 7: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
- scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+ scene->_gameBoardSide[2]._delayPile[0]._card.postInit();
+ scene->_gameBoardSide[2]._delayPile[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._delayPile[0]._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._delayPile[0]._card.hide();
- scene->_arrunkObj1337[3]._arr1[1]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[1].remove();
+ scene->_gameBoardSide[3]._handCard[1]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[1].remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this);
}
break;
case 8: {
- scene->_item2._object1.hide();
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 14;
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_animatedCard._card.hide();
+ scene->_gameBoardSide[2]._delayPile[0]._cardId = 14;
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayPile[0]);
scene->_aSound1.play(57);
R2_GLOBALS._sceneObjects->draw();
@@ -2170,219 +2776,219 @@ void Scene1337::Action1::signal() {
for (i = 0; i <= 3; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 71), 0);
- scene->_arrObject1[i].setStrip(3);
- scene->_arrObject1[i].fixPriority(190);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_upperDisplayCard[i].setStrip(3);
+ scene->_upperDisplayCard[i].fixPriority(190);
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 71), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
}
- scene->_arrObject1[0].setFrame(2);
- scene->_arrObject1[1].setFrame(5);
- scene->_arrObject1[2].setFrame(7);
- scene->_arrObject1[3].setFrame(15);
+ scene->_upperDisplayCard[0].setFrame(2);
+ scene->_upperDisplayCard[1].setFrame(5);
+ scene->_upperDisplayCard[2].setFrame(7);
+ scene->_upperDisplayCard[3].setFrame(15);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
scene->actionDisplay(1331, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
tmpVal = 72;
for (i = 4; i <= 7; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 100), 0);
- scene->_arrObject1[i].setStrip(4);
- scene->_arrObject1[i].fixPriority(190);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_upperDisplayCard[i].setStrip(4);
+ scene->_upperDisplayCard[i].fixPriority(190);
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 100), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
}
- scene->_arrObject1[4].setFrame(1);
- scene->_arrObject1[5].setFrame(5);
- scene->_arrObject1[6].setFrame(7);
- scene->_arrObject1[7].setFrame(3);
+ scene->_upperDisplayCard[4].setFrame(1);
+ scene->_upperDisplayCard[5].setFrame(5);
+ scene->_upperDisplayCard[6].setFrame(7);
+ scene->_upperDisplayCard[7].setFrame(3);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
- scene->_arrObject1[4].remove();
- scene->_arrObject1[5].remove();
- scene->_arrObject1[6].remove();
- scene->_arrObject1[7].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
+ scene->_upperDisplayCard[4].remove();
+ scene->_upperDisplayCard[5].remove();
+ scene->_upperDisplayCard[6].remove();
+ scene->_upperDisplayCard[7].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
- scene->_arrObject2[4].remove();
- scene->_arrObject2[5].remove();
- scene->_arrObject2[6].remove();
- scene->_arrObject2[7].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
+ scene->_lowerDisplayCard[4].remove();
+ scene->_lowerDisplayCard[5].remove();
+ scene->_lowerDisplayCard[6].remove();
+ scene->_lowerDisplayCard[7].remove();
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[0]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._handCard[0]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[0]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[0]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[0]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[0]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[0]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this);
}
break;
case 9: {
scene->_aSound1.play(58);
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0].remove();
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_gameBoardSide[2]._delayPile[0]._cardId = 0;
+ scene->_gameBoardSide[2]._delayPile[0].remove();
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 10: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrObject1[0].postInit();
- scene->_arrObject1[0].setVisage(1332);
- scene->_arrObject1[0].setPosition(Common::Point(131, 71), 0);
- scene->_arrObject1[0].fixPriority(190);
- scene->_arrObject1[0].setStrip(3);
- scene->_arrObject1[0].setFrame(4);
-
- scene->_arrObject2[0].postInit();
- scene->_arrObject2[0].setVisage(1332);
- scene->_arrObject2[0].setPosition(Common::Point(131, 71), 0);
- scene->_arrObject2[0].setStrip(7);
- scene->_arrObject2[0].setFrame(1);
- scene->_arrObject2[0].fixPriority(180);
-
- scene->_arrObject1[1].postInit();
- scene->_arrObject1[1].setVisage(1332);
- scene->_arrObject1[1].setPosition(Common::Point(160, 71), 0);
- scene->_arrObject1[1].fixPriority(190);
- scene->_arrObject1[1].setStrip(3);
- scene->_arrObject1[1].setFrame(16);
-
- scene->_arrObject2[1].postInit();
- scene->_arrObject2[1].setVisage(1332);
- scene->_arrObject2[1].setPosition(Common::Point(160, 71), 0);
- scene->_arrObject2[1].setStrip(7);
- scene->_arrObject2[1].setFrame(1);
- scene->_arrObject2[1].fixPriority(180);
-
- scene->_arrObject1[2].postInit();
- scene->_arrObject1[2].setVisage(1332);
- scene->_arrObject1[2].setPosition(Common::Point(131, 100), 0);
- scene->_arrObject1[2].fixPriority(190);
- scene->_arrObject1[2].setStrip(4);
- scene->_arrObject1[2].setFrame(4);
-
- scene->_arrObject2[2].postInit();
- scene->_arrObject2[2].setVisage(1332);
- scene->_arrObject2[2].setPosition(Common::Point(131, 100), 0);
- scene->_arrObject2[2].setStrip(7);
- scene->_arrObject2[2].setFrame(1);
- scene->_arrObject2[2].fixPriority(180);
-
- scene->_arrObject1[3].postInit();
- scene->_arrObject1[3].setVisage(1332);
- scene->_arrObject1[3].setPosition(Common::Point(160, 100), 0);
- scene->_arrObject1[3].fixPriority(190);
- scene->_arrObject1[3].setStrip(4);
- scene->_arrObject1[3].setFrame(2);
-
- scene->_arrObject2[3].postInit();
- scene->_arrObject2[3].setVisage(1332);
- scene->_arrObject2[3].setPosition(Common::Point(160, 100), 0);
- scene->_arrObject2[3].setStrip(7);
- scene->_arrObject2[3].setFrame(1);
- scene->_arrObject2[3].fixPriority(180);
+ scene->_upperDisplayCard[0].postInit();
+ scene->_upperDisplayCard[0].setVisage(1332);
+ scene->_upperDisplayCard[0].setPosition(Common::Point(131, 71), 0);
+ scene->_upperDisplayCard[0].fixPriority(190);
+ scene->_upperDisplayCard[0].setStrip(3);
+ scene->_upperDisplayCard[0].setFrame(4);
+
+ scene->_lowerDisplayCard[0].postInit();
+ scene->_lowerDisplayCard[0].setVisage(1332);
+ scene->_lowerDisplayCard[0].setPosition(Common::Point(131, 71), 0);
+ scene->_lowerDisplayCard[0].setStrip(7);
+ scene->_lowerDisplayCard[0].setFrame(1);
+ scene->_lowerDisplayCard[0].fixPriority(180);
+
+ scene->_upperDisplayCard[1].postInit();
+ scene->_upperDisplayCard[1].setVisage(1332);
+ scene->_upperDisplayCard[1].setPosition(Common::Point(160, 71), 0);
+ scene->_upperDisplayCard[1].fixPriority(190);
+ scene->_upperDisplayCard[1].setStrip(3);
+ scene->_upperDisplayCard[1].setFrame(16);
+
+ scene->_lowerDisplayCard[1].postInit();
+ scene->_lowerDisplayCard[1].setVisage(1332);
+ scene->_lowerDisplayCard[1].setPosition(Common::Point(160, 71), 0);
+ scene->_lowerDisplayCard[1].setStrip(7);
+ scene->_lowerDisplayCard[1].setFrame(1);
+ scene->_lowerDisplayCard[1].fixPriority(180);
+
+ scene->_upperDisplayCard[2].postInit();
+ scene->_upperDisplayCard[2].setVisage(1332);
+ scene->_upperDisplayCard[2].setPosition(Common::Point(131, 100), 0);
+ scene->_upperDisplayCard[2].fixPriority(190);
+ scene->_upperDisplayCard[2].setStrip(4);
+ scene->_upperDisplayCard[2].setFrame(4);
+
+ scene->_lowerDisplayCard[2].postInit();
+ scene->_lowerDisplayCard[2].setVisage(1332);
+ scene->_lowerDisplayCard[2].setPosition(Common::Point(131, 100), 0);
+ scene->_lowerDisplayCard[2].setStrip(7);
+ scene->_lowerDisplayCard[2].setFrame(1);
+ scene->_lowerDisplayCard[2].fixPriority(180);
+
+ scene->_upperDisplayCard[3].postInit();
+ scene->_upperDisplayCard[3].setVisage(1332);
+ scene->_upperDisplayCard[3].setPosition(Common::Point(160, 100), 0);
+ scene->_upperDisplayCard[3].fixPriority(190);
+ scene->_upperDisplayCard[3].setStrip(4);
+ scene->_upperDisplayCard[3].setFrame(2);
+
+ scene->_lowerDisplayCard[3].postInit();
+ scene->_lowerDisplayCard[3].setVisage(1332);
+ scene->_lowerDisplayCard[3].setPosition(Common::Point(160, 100), 0);
+ scene->_lowerDisplayCard[3].setStrip(7);
+ scene->_lowerDisplayCard[3].setFrame(1);
+ scene->_lowerDisplayCard[3].fixPriority(180);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
- scene->_object1.setFrame(1);
- scene->_object1.show();
- scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_currentPlayerArrow.setFrame(1);
+ scene->_currentPlayerArrow.show();
+ scene->_currentPlayerArrow.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 19, 159, 10, 1, 220, 0, 7, 0, 154, 154);
- scene->_object1.hide();
+ scene->_currentPlayerArrow.hide();
scene->actionDisplay(1331, 20, 159, 10, 1, 220, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 21, 159, 10, 1, 220, 0, 7, 0, 154, 154);
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[1]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._handCard[1]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[1]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[1]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[1]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[1]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[1]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[1]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 11: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._sceneObjects->draw();
@@ -2390,38 +2996,38 @@ void Scene1337::Action1::signal() {
int i = -1;
for (i = 0; i <= 3; i ++) {
- scene->_arrunkObj1337[3]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[3]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[i]._card.remove();
- scene->_arrunkObj1337[2]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[i]._card.remove();
- scene->_arrunkObj1337[0]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[0]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[0]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[0]._handCard[i]._card.remove();
- scene->_arrunkObj1337[1]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[1]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[1]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[1]._handCard[i]._card.remove();
}
for (i = 0; i <= 7; i++) {
- scene->_arrunkObj1337[3]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[3]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[3]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[3]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[2]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[2]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[2]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[2]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[0]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[0]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[0]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[0]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[1]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[1]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[1]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[1]._outpostStation[i]._card.remove();
}
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+ scene->_gameBoardSide[2]._delayPile[0]._cardId = 0;
+ scene->_gameBoardSide[2]._delayPile[0]._card.remove();
- scene->_item7._field34 = 0;
- scene->_item7._object1.remove();
+ scene->_discardPile._cardId = 0;
+ scene->_discardPile._card.remove();
scene->_background2.remove();
}
@@ -2439,40 +3045,43 @@ void Scene1337::Action1::signal() {
}
}
+/**
+ * Shuffle cards animation
+ */
void Scene1337::Action2::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0:
- scene->_item3._object1.postInit();
- scene->_item3._object1.setVisage(1332);
- scene->_item3._object1.setStrip(8);
- scene->_item3._object1.setFrame(1);
- scene->_item3._object1.fixPriority(300);
- scene->_item3._object1.setPosition(Common::Point(156, 108));
+ scene->_shuffleAnimation._card.postInit();
+ scene->_shuffleAnimation._card.setVisage(1332);
+ scene->_shuffleAnimation._card.setStrip(8);
+ scene->_shuffleAnimation._card.setFrame(1);
+ scene->_shuffleAnimation._card.fixPriority(300);
+ scene->_shuffleAnimation._card.setPosition(Common::Point(156, 108));
- scene->_item7._object1.remove();
- scene->_item7._field34 = 0;
+ scene->_discardPile._card.remove();
+ scene->_discardPile._cardId = 0;
scene->_aSound1.play(60);
- scene->_item3._object1.animate(ANIM_MODE_5, this);
+ scene->_shuffleAnimation._card.animate(ANIM_MODE_5, this);
break;
case 1:
- scene->_item3._object1.setFrame(1);
+ scene->_shuffleAnimation._card.setFrame(1);
scene->_aSound1.play(60);
- scene->_item3._object1.animate(ANIM_MODE_5, this);
+ scene->_shuffleAnimation._card.animate(ANIM_MODE_5, this);
break;
case 2: {
Common::Point pt(156, 108);
NpcMover *mover = new NpcMover();
- scene->_item3._object1.addMover(mover, &pt, this);
+ scene->_shuffleAnimation._card.addMover(mover, &pt, this);
}
break;
case 3:
- scene->_item3._object1.remove();
+ scene->_shuffleAnimation._card.remove();
scene->_background2.setup2(1332, 5, 1, 162, 95, 110, 1);
- scene->_field423C = 1;
+ scene->_shuffleEndedFl = true;
break;
default:
break;
@@ -2482,268 +3091,268 @@ void Scene1337::Action2::signal() {
void Scene1337::Action3::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
switch (_actionIndex++) {
case 0: {
- scene->_item2._object1._moveDiff = Common::Point(30, 30);
- scene->_item2._object1.setVisage(1332);
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.fixPriority(400);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card._moveDiff = Common::Point(30, 30);
+ scene->_animatedCard._card.setVisage(1332);
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.fixPriority(400);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
scene->_aSound2.play(61);
Common::Point pt(283, 146);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_item2._object1.show();
- scene->_arrunkObj1337[1]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_animatedCard._card.show();
+ scene->_gameBoardSide[1]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 1: {
- scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[0]._card.setPosition(scene->_gameBoardSide[1]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[0]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(10, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 2: {
- scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
- if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 25);
+ scene->_gameBoardSide[2]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[0]._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[0]._card.fixPriority(170);
+ if (scene->_gameBoardSide[2]._handCard[0]._cardId > 9) {
+ if (scene->_gameBoardSide[2]._handCard[0]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId - 25);
} else {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 9);
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId - 9);
}
} else {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34);
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 14);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 3: {
- scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[0]._card.setPosition(scene->_gameBoardSide[3]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[0]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(280, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 4: {
- scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[0]._object1._moveDiff = Common::Point(30,30);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[0]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[0]._card._moveDiff = Common::Point(30,30);
+ scene->_gameBoardSide[0]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[0]._card.setPosition(scene->_gameBoardSide[0]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[0]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[0]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(283, 124);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[1]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[1]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 5: {
- scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[1]._card.setPosition(scene->_gameBoardSide[1]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[1]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(37, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 6: {
- scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
-
- if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 25);
+ scene->_gameBoardSide[2]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[1]._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[1]._card.fixPriority(170);
+
+ if (scene->_gameBoardSide[2]._handCard[1]._cardId > 9) {
+ if (scene->_gameBoardSide[2]._handCard[1]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId - 25);
} else {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 9);
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId - 9);
}
} else {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34);
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 36);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 7: {
- scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[1]._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos);
+ scene->_gameBoardSide[3]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[1]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(253, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 8: {
- scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[0]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[0]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[1]._card.setPosition(scene->_gameBoardSide[0]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[1]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[1]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(283, 102);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[1]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[1]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 9: {
- scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[2]._card.setPosition(scene->_gameBoardSide[1]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[2]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[2]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(64, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 10: {
- scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
-
- if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 25);
+ scene->_gameBoardSide[2]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[2]._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[2]._card.fixPriority(170);
+
+ if (scene->_gameBoardSide[2]._handCard[2]._cardId > 9) {
+ if (scene->_gameBoardSide[2]._handCard[2]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId - 25);
} else {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 9);
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId - 9);
}
} else {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34);
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 58);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 11: {
- scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[2]._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[2]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[2]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(226, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 12:
- scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
- scene->_arrunkObj1337[0]._arr1[2]._object1.hide();
+ scene->_gameBoardSide[0]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[0]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[2]._card.setPosition(scene->_gameBoardSide[0]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[2]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[2]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[2]._card.fixPriority(170);
+ scene->_gameBoardSide[0]._handCard[2]._card.hide();
default:
break;
}
if (_actionIndex > 12) {
- scene->_field423E = 0;
+ scene->_currentPlayerNumb = 0;
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1330, 0, 159, 10, 1, 200, 0, 7, 0, 154, 154);
scene->subC20F9();
} else if (_actionIndex >= 1) {
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
}
}
@@ -2752,21 +3361,21 @@ void Scene1337::Action4::signal() {
switch (_actionIndex++) {
case 0:
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34))) {
- if (scene->_field3E24 < 0)
- scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34);
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
- scene->_item2._object1.show();
+ if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId))) {
+ if (scene->_cardsAvailableNumb < 0)
+ scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId);
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB94, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
- if (scene->_field3E24 < 0)
+ if (scene->_cardsAvailableNumb < 0)
scene->_background2.remove();
} else {
// Self call, forcing next actionIndex
@@ -2774,127 +3383,127 @@ void Scene1337::Action4::signal() {
}
break;
case 1:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB94.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB94.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[0]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94.x)
+ && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]);
+
+ scene->_animatedCard._card.hide();
+ if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB98, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
scene->_background2.remove();
} else
signal();
break;
case 2:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB98.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB98.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[1]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98.x)
+ && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]);
+
+ scene->_animatedCard._card.hide();
+ if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB9C, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
scene->_background2.remove();
} else
signal();
break;
case 3:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[2]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C.x)
+ && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]);
+
+ scene->_animatedCard._card.hide();
+ if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldBA0, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
scene->_background2.remove();
} else
signal();
break;
case 4:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[3]);
-
- scene->_item2._object1.hide();
- switch (scene->_field423E) {
+ if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0.x)
+ && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.fixPriority(170);
+ }
+
+ if ((scene->_field4248 == 1) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]);
+
+ scene->_animatedCard._card.hide();
+ switch (scene->_currentPlayerNumb) {
case 0:
scene->subCF979();
break;
@@ -2921,34 +3530,34 @@ void Scene1337::Action5::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF0->_field34;
+ scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF0->_cardId;
scene->_field3E26--;
- if (!g_globals->_sceneObjects->contains(&scene->_item7._object1)) {
- scene->_item7._object1.postInit();
- scene->_item7._object1.hide();
- scene->_item7._object1.setVisage(1332);
- scene->_item7._object1.setPosition(scene->_item7._field36, 0);
- scene->_item7._object1.fixPriority(170);
+ if (!g_globals->_sceneObjects->contains(&scene->_discardPile._card)) {
+ scene->_discardPile._card.postInit();
+ scene->_discardPile._card.hide();
+ scene->_discardPile._card.setVisage(1332);
+ scene->_discardPile._card.setPosition(scene->_discardPile._stationPos, 0);
+ scene->_discardPile._card.fixPriority(170);
}
- scene->_item7._field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_discardPile._cardId = scene->_field3EF0->_cardId;
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
Common::Point pt(128, 95);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
}
break;
case 1:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
scene->subC20F9();
break;
@@ -2962,29 +3571,29 @@ void Scene1337::Action6::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = 1;
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36);
- scene->_field3EF4->_object1.fixPriority(170);
+ scene->_field3EF4->_cardId = 1;
+ scene->_field3EF4->_card.postInit();
+ scene->_field3EF4->_card.hide();
+ scene->_field3EF4->_card.setVisage(1332);
+ scene->_field3EF4->_card.setPosition(scene->_field3EF4->_stationPos);
+ scene->_field3EF4->_card.fixPriority(170);
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(59);
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
scene->subC20F9();
@@ -2999,30 +3608,30 @@ void Scene1337::Action7::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF4->_cardId = scene->_field3EF0->_cardId;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1:
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(59);
- scene->_item5._field34 = 1;
- scene->_item5._field36.x = scene->_field3EF4->_field36.x;
- scene->_item5._field36.y = scene->_field3EF4->_field36.y;
- scene->_item5._object1.postInit();
- scene->_item5._object1.hide();
- scene->_item5._object1._flags = 0x200;
+ scene->_item5._cardId = 1;
+ scene->_item5._stationPos.x = scene->_field3EF4->_stationPos.x;
+ scene->_item5._stationPos.y = scene->_field3EF4->_stationPos.y;
+ scene->_item5._card.postInit();
+ scene->_item5._card.hide();
+ scene->_item5._card._flags = 0x200;
scene->subC4A39(&scene->_item5);
break;
@@ -3036,24 +3645,24 @@ void Scene1337::Action8::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId;
scene->_field3E26--;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF4->_cardId = scene->_field3EF0->_cardId;
+ scene->_field3EF0->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
scene->setAnimationInfo(scene->_field3EF4);
@@ -3070,30 +3679,30 @@ void Scene1337::Action9::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_field3EF4->_object1.fixPriority(170);
+ scene->_field3EF4->_cardId = scene->_field3EF0->_cardId;
+ scene->_field3EF4->_card.postInit();
+ scene->_field3EF4->_card.hide();
+ scene->_field3EF4->_card.setVisage(1332);
+ scene->_field3EF4->_card.setPosition(scene->_field3EF4->_stationPos, 0);
+ scene->_field3EF4->_card.fixPriority(170);
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(57);
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
@@ -3109,29 +3718,29 @@ void Scene1337::Action10::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF8->_object1.postInit();
- scene->_field3EF8->_object1.hide();
- scene->_field3EF8->_object1.setVisage(1332);
- scene->_field3EF8->_object1.setPosition(scene->_field3EF8->_field36, 0);
- scene->_field3EF8->_object1.fixPriority(170);
- scene->_field3EF8->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF8->_card.postInit();
+ scene->_field3EF8->_card.hide();
+ scene->_field3EF8->_card.setVisage(1332);
+ scene->_field3EF8->_card.setPosition(scene->_field3EF8->_stationPos, 0);
+ scene->_field3EF8->_card.fixPriority(170);
+ scene->_field3EF8->_cardId = scene->_field3EF0->_cardId;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF8->_stationPos, this);
}
break;
case 1: {
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF8);
scene->_aSound1.play(57);
@@ -3141,7 +3750,7 @@ void Scene1337::Action10::signal() {
switch (scene->_field4240) {
case 0:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[0]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[0]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3149,7 +3758,7 @@ void Scene1337::Action10::signal() {
break;
case 1:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[1]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[1]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3157,7 +3766,7 @@ void Scene1337::Action10::signal() {
break;
case 2:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[2]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[2]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3165,7 +3774,7 @@ void Scene1337::Action10::signal() {
break;
case 3:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[3]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[3]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3180,11 +3789,11 @@ void Scene1337::Action10::signal() {
if (found) {
switch (scene->_field4240) {
case 0:
- scene->subC51A0(&scene->_arrunkObj1337[0]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[0]._handCard[indexFound], scene->_field3EF8);
found2 = true;
break;
case 1:
- scene->subC51A0(&scene->_arrunkObj1337[1]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[1]._handCard[indexFound], scene->_field3EF8);
found2 = true;
break;
case 2:
@@ -3192,12 +3801,12 @@ void Scene1337::Action10::signal() {
if (MessageDialog::show(USE_INTERCEPTOR, NO_MSG, YES_MSG) == 0)
scene->subC4CEC();
else {
- scene->subC51A0(&scene->_arrunkObj1337[2]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[2]._handCard[indexFound], scene->_field3EF8);
found2 = true;
}
break;
case 3:
- scene->subC51A0(&scene->_arrunkObj1337[3]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[3]._handCard[indexFound], scene->_field3EF8);
found2 = true;
break;
default:
@@ -3211,14 +3820,14 @@ void Scene1337::Action10::signal() {
if (scene->_field4240 == 2) {
int j = 0;
for (int i = 0; i <= 7; i++) {
- if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)
+ if (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)
++j;
}
if (j <= 1) {
for (int i = 0; i <= 7; i++) {
- if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0) {
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[i];
+ if (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0) {
+ scene->_field3EF4 = &scene->_gameBoardSide[2]._outpostStation[i];
break;
}
}
@@ -3237,11 +3846,11 @@ void Scene1337::Action10::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_item6._stationPos = event.mousePos;
for (int i = 0; i <= 7; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[2]._arr2[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)) {
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[0];
+ if ((scene->subC2BF8(&scene->_gameBoardSide[2]._outpostStation[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)) {
+ scene->_field3EF4 = &scene->_gameBoardSide[2]._outpostStation[0];
found2 = true;
break;
}
@@ -3251,20 +3860,20 @@ void Scene1337::Action10::signal() {
}
}
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId;
scene->_field3E26--;
- scene->_field3EF4->_field34 = 0;
- scene->_field3EF4->_object1.remove();
+ scene->_field3EF4->_cardId = 0;
+ scene->_field3EF4->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF4->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF8->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->subC4A39(scene->_field3EF8);
break;
default:
@@ -3279,29 +3888,29 @@ void Scene1337::Action11::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_field3EF4->_object1.fixPriority(170);
- scene->_field3EF4->_field34 = 25;
+ scene->_field3EF4->_card.postInit();
+ scene->_field3EF4->_card.hide();
+ scene->_field3EF4->_card.setVisage(1332);
+ scene->_field3EF4->_card.setPosition(scene->_field3EF4->_stationPos, 0);
+ scene->_field3EF4->_card.fixPriority(170);
+ scene->_field3EF4->_cardId = 25;
if (scene->_field4240 == 2) {
- scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
- subD18B5(5, 1, 4);
+ scene->_animatedCard._card.setPosition(scene->_field3EF4->_stationPos, 0);
+ scene->setCursorData(5, 1, 4);
} else {
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
}
- scene->_item2._object1.show();
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1: {
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(57);
@@ -3311,18 +3920,18 @@ void Scene1337::Action11::signal() {
switch (scene->_field4242) {
case 0:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[0]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[0]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[0]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[0]._arr4[0];
+ scene->_field3EF0 = &scene->_gameBoardSide[0]._handCard[i];
+ scene->_field3EF4 = &scene->_gameBoardSide[0]._arr4[0];
if (scene->_field4240 != 0) {
int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal];
}
scene->_item1.setAction(&scene->_action12);
noAction = false;
@@ -3330,18 +3939,18 @@ void Scene1337::Action11::signal() {
break;
case 1:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[1]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[1]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[1]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[1]._arr4[0];
+ scene->_field3EF0 = &scene->_gameBoardSide[1]._handCard[i];
+ scene->_field3EF4 = &scene->_gameBoardSide[1]._arr4[0];
if (scene->_field4240 != 1) {
int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal];
}
scene->_item1.setAction(&scene->_action12);
noAction = false;
@@ -3349,7 +3958,7 @@ void Scene1337::Action11::signal() {
break;
case 2:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[2]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[2]._handCard[i]._cardId == 27) {
found = true;
break;
}
@@ -3361,11 +3970,11 @@ void Scene1337::Action11::signal() {
scene->subC4CEC();
else {
scene->subC4CEC();
- scene->_field3EF0 = &scene->_arrunkObj1337[2]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr4[0];
+ scene->_field3EF0 = &scene->_gameBoardSide[2]._handCard[i];
+ scene->_field3EF4 = &scene->_gameBoardSide[2]._arr4[0];
if (scene->_field4240 != 2) {
int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal];
}
scene->_item1.setAction(&scene->_action12);
noAction = false;
@@ -3374,18 +3983,18 @@ void Scene1337::Action11::signal() {
break;
case 3:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[3]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[3]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[3]._arr4[0];
+ scene->_field3EF0 = &scene->_gameBoardSide[3]._handCard[i];
+ scene->_field3EF4 = &scene->_gameBoardSide[3]._arr4[0];
if (scene->_field4240 != 3) {
int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal];
}
scene->_item1.setAction(&scene->_action12);
noAction = false;
@@ -3402,7 +4011,7 @@ void Scene1337::Action11::signal() {
int count = 0;
if (scene->_field4242 != 2) {
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 == 0)
+ if (scene->_gameBoardSide[scene->_field4242]._handCard[i]._cardId == 0)
++count;
}
}
@@ -3433,74 +4042,70 @@ void Scene1337::Action11::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_item6._stationPos = event.mousePos;
found = false;
if (scene->_field4242 != 2) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[scene->_field4242]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 != 0)) {
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[i];
+ if ((scene->subC2BF8(&scene->_gameBoardSide[scene->_field4242]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[scene->_field4242]._handCard[i]._cardId != 0)) {
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4242]._handCard[i];
found = true;
break;
}
}
}
} // while
- scene->_field4246 = 1;
+ scene->_field4246 = true;
scene->subC4CEC();
} else {
if (scene->_field4242 != 2) {
int tmpVal = scene->subC3E92(scene->_field4242);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[tmpVal];
+ scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4242]._handCard[tmpVal];
}
}
}
- scene->_field3EF0->_object1.postInit();
- scene->_field3EF0->_object1.hide();
- scene->_field3EF0->_object1.setVisage(1332);
- scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_field3EF0->_object1.fixPriority(170);
- scene->_field3EF0->_object1.setStrip2(1);
- scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+ scene->_field3EF0->_card.postInit();
+ scene->_field3EF0->_card.hide();
+ scene->_field3EF0->_card.setVisage(1332);
+ scene->_field3EF0->_card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_field3EF0->_card.fixPriority(170);
+ scene->_field3EF0->_card.setStrip2(1);
+ scene->_field3EF0->_cardId = scene->_field3EF8->_cardId;
- scene->_field3EF8->_field34 = 0;
- scene->_field3EF8->_object1.remove();
+ scene->_field3EF8->_cardId = 0;
+ scene->_field3EF8->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF8->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF8->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF0->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
switch (scene->_field4240) {
case 0:
- scene->_field3EF0->_object1.setFrame(2);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_field3EF0->_card.setFrame(2);
+ scene->_field3EF0->_card.show();
break;
case 1:
- scene->_field3EF0->_object1.setFrame(4);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_field3EF0->_card.setFrame(4);
+ scene->_field3EF0->_card.show();
break;
case 3:
- scene->_field3EF0->_object1.setFrame(3);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_field3EF0->_card.setFrame(3);
+ scene->_field3EF0->_card.show();
break;
default:
scene->setAnimationInfo(scene->_field3EF0);
break;
}
+ scene->_currentPlayerNumb--;
+ scene->_field4244 = false;
scene->subC4A39(scene->_field3EF4);
break;
default:
@@ -3516,19 +4121,19 @@ void Scene1337::Action12::signal() {
signal();
break;
case 1: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId;
+ scene->_field3EF4->_cardId = scene->_field3EF0->_cardId;
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(58);
if (scene->_field4242 == 2) {
@@ -3537,19 +4142,19 @@ void Scene1337::Action12::signal() {
switch (scene->_field4240) {
case 0:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)
+ if (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)
++count;
}
break;
case 1:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ if (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)
++count;
}
break;
case 3:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ if (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)
++count;
}
break;
@@ -3584,13 +4189,13 @@ void Scene1337::Action12::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_item6._stationPos = event.mousePos;
if (scene->_field4240 == 0) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[0]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)) {
+ if ((scene->subC2BF8(&scene->_gameBoardSide[0]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[i];
+ scene->_field3EF8 = &scene->_gameBoardSide[0]._handCard[i];
break;
}
}
@@ -3598,9 +4203,9 @@ void Scene1337::Action12::signal() {
if (scene->_field4240 == 3) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[3]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)) {
+ if ((scene->subC2BF8(&scene->_gameBoardSide[3]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[i];
+ scene->_field3EF8 = &scene->_gameBoardSide[3]._handCard[i];
break;
}
}
@@ -3608,9 +4213,9 @@ void Scene1337::Action12::signal() {
if (scene->_field4240 == 1) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[1]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[1]._arr1[i]._field34 != 0)) {
+ if ((scene->subC2BF8(&scene->_gameBoardSide[1]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[1]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[i];
+ scene->_field3EF8 = &scene->_gameBoardSide[1]._handCard[i];
break;
}
}
@@ -3621,52 +4226,52 @@ void Scene1337::Action12::signal() {
if (scene->_field4240 != 1) {
switch (scene->_field4240) {
case 0:
- scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[scene->subC3E92(0)];
+ scene->_field3EF8 = &scene->_gameBoardSide[0]._handCard[scene->subC3E92(0)];
break;
case 3:
- scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[scene->subC3E92(3)];
+ scene->_field3EF8 = &scene->_gameBoardSide[3]._handCard[scene->subC3E92(3)];
break;
default:
break;
}
} else {
- scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[scene->subC3E92(1)];
+ scene->_field3EF8 = &scene->_gameBoardSide[1]._handCard[scene->subC3E92(1)];
}
}
- scene->_field3EF0->_object1.postInit();
- scene->_field3EF0->_object1.hide();
- scene->_field3EF0->_object1.setVisage(1332);
- scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36);
- scene->_field3EF0->_object1.fixPriority(170);
- scene->_field3EF0->_object1.setStrip2(1);
- scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+ scene->_field3EF0->_card.postInit();
+ scene->_field3EF0->_card.hide();
+ scene->_field3EF0->_card.setVisage(1332);
+ scene->_field3EF0->_card.setPosition(scene->_field3EF0->_stationPos);
+ scene->_field3EF0->_card.fixPriority(170);
+ scene->_field3EF0->_card.setStrip2(1);
+ scene->_field3EF0->_cardId = scene->_field3EF8->_cardId;
- scene->_field3EF8->_field34 = 0;
- scene->_field3EF8->_object1.remove();
+ scene->_field3EF8->_cardId = 0;
+ scene->_field3EF8->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF8->_field36);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF8->_stationPos);
+ scene->_animatedCard._card.show();
scene->_aSound1.play(57);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF0->_stationPos, this);
}
break;
case 3:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
switch (scene->_field4242) {
case 0:
- scene->_field3EF0->_object1.setFrame2(2);
- scene->_field3EF0->_object1.show();
+ scene->_field3EF0->_card.setFrame2(2);
+ scene->_field3EF0->_card.show();
break;
case 1:
- scene->_field3EF0->_object1.setFrame2(4);
- scene->_field3EF0->_object1.show();
+ scene->_field3EF0->_card.setFrame2(4);
+ scene->_field3EF0->_card.show();
break;
case 3:
- scene->_field3EF0->_object1.setFrame2(3);
- scene->_field3EF0->_object1.show();
+ scene->_field3EF0->_card.setFrame2(3);
+ scene->_field3EF0->_card.show();
break;
default:
scene->setAnimationInfo(scene->_field3EF0);
@@ -3684,23 +4289,23 @@ void Scene1337::Action13::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
+ scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId;
scene->_field3E26--;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_field3EF4->_cardId = scene->_field3EF0->_cardId;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_field3EF0->_cardId = 0;
+ scene->_field3EF0->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
scene->setAnimationInfo(scene->_field3EF4);
scene->_aSound1.play(58);
signal();
@@ -3717,12 +4322,12 @@ void Scene1337::postInit(SceneObjectList *OwnerList) {
// In the original, may be found in subPostInit.
// Without it, enableControl asserts
loadScene(1330);
+ R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
//
// Hide the user interface
- R2_GLOBALS._uiElements._active = false;
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
@@ -3733,101 +4338,101 @@ void Scene1337::postInit(SceneObjectList *OwnerList) {
_field3EF4 = NULL;
_field3EF8 = NULL;
- _arrunkObj1337[2]._arr1[0]._field36 = Common::Point(10, 174);
- _arrunkObj1337[2]._arr1[1]._field36 = Common::Point(37, 174);
- _arrunkObj1337[2]._arr1[2]._field36 = Common::Point(64, 174);
- _arrunkObj1337[2]._arr1[3]._field36 = Common::Point(91, 174);
-
- _arrunkObj1337[2]._arr2[0]._field36 = Common::Point(119, 174);
- _arrunkObj1337[2]._arr2[1]._field36 = Common::Point(119, 148);
- _arrunkObj1337[2]._arr2[2]._field36 = Common::Point(119, 122);
- _arrunkObj1337[2]._arr2[3]._field36 = Common::Point(145, 122);
- _arrunkObj1337[2]._arr2[4]._field36 = Common::Point(171, 122);
- _arrunkObj1337[2]._arr2[5]._field36 = Common::Point(171, 148);
- _arrunkObj1337[2]._arr2[6]._field36 = Common::Point(171, 174);
- _arrunkObj1337[2]._arr2[7]._field36 = Common::Point(145, 174);
-
- _arrunkObj1337[2]._arr3[0]._field36 = Common::Point(199, 174);
-
- _arrunkObj1337[2]._arr4[0]._field36 = Common::Point(145, 148);
-
- _arrunkObj1337[2]._fieldB94 = Common::Point(10, 174);
- _arrunkObj1337[2]._fieldB98 = Common::Point(37, 174);
- _arrunkObj1337[2]._fieldB9C = Common::Point(64, 174);
- _arrunkObj1337[2]._fieldBA0 = Common::Point(91, 174);
- _arrunkObj1337[2]._fieldBA4 = 2;
-
- _arrunkObj1337[3]._arr1[0]._field36 = Common::Point(14, 14);
- _arrunkObj1337[3]._arr1[1]._field36 = Common::Point(14, 36);
- _arrunkObj1337[3]._arr1[2]._field36 = Common::Point(14, 58);
- _arrunkObj1337[3]._arr1[3]._field36 = Common::Point(14, 80);
-
- _arrunkObj1337[3]._arr2[0]._field36 = Common::Point(37, 66);
- _arrunkObj1337[3]._arr2[1]._field36 = Common::Point(63, 66);
- _arrunkObj1337[3]._arr2[2]._field36 = Common::Point(89, 66);
- _arrunkObj1337[3]._arr2[3]._field36 = Common::Point(89, 92);
- _arrunkObj1337[3]._arr2[4]._field36 = Common::Point(89, 118);
- _arrunkObj1337[3]._arr2[5]._field36 = Common::Point(63, 118);
- _arrunkObj1337[3]._arr2[6]._field36 = Common::Point(37, 118);
- _arrunkObj1337[3]._arr2[7]._field36 = Common::Point(37, 92);
-
- _arrunkObj1337[3]._arr3[0]._field36 = Common::Point(37, 145);
-
- _arrunkObj1337[3]._arr4[0]._field36 = Common::Point(63, 92);
-
- _arrunkObj1337[3]._fieldB94 = Common::Point(14, 14);
- _arrunkObj1337[3]._fieldB98 = Common::Point(14, 36);
- _arrunkObj1337[3]._fieldB9C = Common::Point(14, 58);
- _arrunkObj1337[3]._fieldBA0 = Common::Point(14, 80);
- _arrunkObj1337[3]._fieldBA4 = 3;
-
- _arrunkObj1337[0]._arr1[0]._field36 = Common::Point(280, 5);
- _arrunkObj1337[0]._arr1[1]._field36 = Common::Point(253, 5);
- _arrunkObj1337[0]._arr1[2]._field36 = Common::Point(226, 5);
- _arrunkObj1337[0]._arr1[3]._field36 = Common::Point(199, 5);
-
- _arrunkObj1337[0]._arr2[0]._field36 = Common::Point(171, 16);
- _arrunkObj1337[0]._arr2[1]._field36 = Common::Point(171, 42);
- _arrunkObj1337[0]._arr2[2]._field36 = Common::Point(171, 68);
- _arrunkObj1337[0]._arr2[3]._field36 = Common::Point(145, 68);
- _arrunkObj1337[0]._arr2[4]._field36 = Common::Point(119, 68);
- _arrunkObj1337[0]._arr2[5]._field36 = Common::Point(119, 42);
- _arrunkObj1337[0]._arr2[6]._field36 = Common::Point(119, 16);
- _arrunkObj1337[0]._arr2[7]._field36 = Common::Point(145, 16);
-
- _arrunkObj1337[0]._arr3[0]._field36 = Common::Point(91, 16);
-
- _arrunkObj1337[0]._arr4[0]._field36 = Common::Point(145, 42);
-
- _arrunkObj1337[0]._fieldB94 = Common::Point(280, 5);
- _arrunkObj1337[0]._fieldB98 = Common::Point(253, 5);
- _arrunkObj1337[0]._fieldB9C = Common::Point(226, 5);
- _arrunkObj1337[0]._fieldBA0 = Common::Point(199, 5);
- _arrunkObj1337[0]._fieldBA4 = 2;
-
- _arrunkObj1337[1]._arr1[0]._field36 = Common::Point(283, 146);
- _arrunkObj1337[1]._arr1[1]._field36 = Common::Point(283, 124);
- _arrunkObj1337[1]._arr1[2]._field36 = Common::Point(283, 102);
- _arrunkObj1337[1]._arr1[3]._field36 = Common::Point(283, 80);
-
- _arrunkObj1337[1]._arr2[0]._field36 = Common::Point(253, 122);
- _arrunkObj1337[1]._arr2[1]._field36 = Common::Point(227, 122);
- _arrunkObj1337[1]._arr2[2]._field36 = Common::Point(201, 122);
- _arrunkObj1337[1]._arr2[3]._field36 = Common::Point(201, 96);
- _arrunkObj1337[1]._arr2[4]._field36 = Common::Point(201, 70);
- _arrunkObj1337[1]._arr2[5]._field36 = Common::Point(227, 70);
- _arrunkObj1337[1]._arr2[6]._field36 = Common::Point(253, 70);
- _arrunkObj1337[1]._arr2[7]._field36 = Common::Point(253, 96);
-
- _arrunkObj1337[1]._arr3[0]._field36 = Common::Point(253, 43);
-
- _arrunkObj1337[1]._arr4[0]._field36 = Common::Point(227, 96);
-
- _arrunkObj1337[1]._fieldB94 = Common::Point(283, 146);
- _arrunkObj1337[1]._fieldB98 = Common::Point(283, 124);
- _arrunkObj1337[1]._fieldB9C = Common::Point(283, 102);
- _arrunkObj1337[1]._fieldBA0 = Common::Point(283, 80);
- _arrunkObj1337[1]._fieldBA4 = 4;
+ _gameBoardSide[2]._handCard[0]._stationPos = Common::Point(10, 174);
+ _gameBoardSide[2]._handCard[1]._stationPos = Common::Point(37, 174);
+ _gameBoardSide[2]._handCard[2]._stationPos = Common::Point(64, 174);
+ _gameBoardSide[2]._handCard[3]._stationPos = Common::Point(91, 174);
+
+ _gameBoardSide[2]._outpostStation[0]._stationPos = Common::Point(119, 174);
+ _gameBoardSide[2]._outpostStation[1]._stationPos = Common::Point(119, 148);
+ _gameBoardSide[2]._outpostStation[2]._stationPos = Common::Point(119, 122);
+ _gameBoardSide[2]._outpostStation[3]._stationPos = Common::Point(145, 122);
+ _gameBoardSide[2]._outpostStation[4]._stationPos = Common::Point(171, 122);
+ _gameBoardSide[2]._outpostStation[5]._stationPos = Common::Point(171, 148);
+ _gameBoardSide[2]._outpostStation[6]._stationPos = Common::Point(171, 174);
+ _gameBoardSide[2]._outpostStation[7]._stationPos = Common::Point(145, 174);
+
+ _gameBoardSide[2]._delayPile[0]._stationPos = Common::Point(199, 174);
+
+ _gameBoardSide[2]._arr4[0]._stationPos = Common::Point(145, 148);
+
+ _gameBoardSide[2]._fieldB94 = Common::Point(10, 174);
+ _gameBoardSide[2]._fieldB98 = Common::Point(37, 174);
+ _gameBoardSide[2]._fieldB9C = Common::Point(64, 174);
+ _gameBoardSide[2]._fieldBA0 = Common::Point(91, 174);
+ _gameBoardSide[2]._fieldBA4 = 2;
+
+ _gameBoardSide[3]._handCard[0]._stationPos = Common::Point(14, 14);
+ _gameBoardSide[3]._handCard[1]._stationPos = Common::Point(14, 36);
+ _gameBoardSide[3]._handCard[2]._stationPos = Common::Point(14, 58);
+ _gameBoardSide[3]._handCard[3]._stationPos = Common::Point(14, 80);
+
+ _gameBoardSide[3]._outpostStation[0]._stationPos = Common::Point(37, 66);
+ _gameBoardSide[3]._outpostStation[1]._stationPos = Common::Point(63, 66);
+ _gameBoardSide[3]._outpostStation[2]._stationPos = Common::Point(89, 66);
+ _gameBoardSide[3]._outpostStation[3]._stationPos = Common::Point(89, 92);
+ _gameBoardSide[3]._outpostStation[4]._stationPos = Common::Point(89, 118);
+ _gameBoardSide[3]._outpostStation[5]._stationPos = Common::Point(63, 118);
+ _gameBoardSide[3]._outpostStation[6]._stationPos = Common::Point(37, 118);
+ _gameBoardSide[3]._outpostStation[7]._stationPos = Common::Point(37, 92);
+
+ _gameBoardSide[3]._delayPile[0]._stationPos = Common::Point(37, 145);
+
+ _gameBoardSide[3]._arr4[0]._stationPos = Common::Point(63, 92);
+
+ _gameBoardSide[3]._fieldB94 = Common::Point(14, 14);
+ _gameBoardSide[3]._fieldB98 = Common::Point(14, 36);
+ _gameBoardSide[3]._fieldB9C = Common::Point(14, 58);
+ _gameBoardSide[3]._fieldBA0 = Common::Point(14, 80);
+ _gameBoardSide[3]._fieldBA4 = 3;
+
+ _gameBoardSide[0]._handCard[0]._stationPos = Common::Point(280, 5);
+ _gameBoardSide[0]._handCard[1]._stationPos = Common::Point(253, 5);
+ _gameBoardSide[0]._handCard[2]._stationPos = Common::Point(226, 5);
+ _gameBoardSide[0]._handCard[3]._stationPos = Common::Point(199, 5);
+
+ _gameBoardSide[0]._outpostStation[0]._stationPos = Common::Point(171, 16);
+ _gameBoardSide[0]._outpostStation[1]._stationPos = Common::Point(171, 42);
+ _gameBoardSide[0]._outpostStation[2]._stationPos = Common::Point(171, 68);
+ _gameBoardSide[0]._outpostStation[3]._stationPos = Common::Point(145, 68);
+ _gameBoardSide[0]._outpostStation[4]._stationPos = Common::Point(119, 68);
+ _gameBoardSide[0]._outpostStation[5]._stationPos = Common::Point(119, 42);
+ _gameBoardSide[0]._outpostStation[6]._stationPos = Common::Point(119, 16);
+ _gameBoardSide[0]._outpostStation[7]._stationPos = Common::Point(145, 16);
+
+ _gameBoardSide[0]._delayPile[0]._stationPos = Common::Point(91, 16);
+
+ _gameBoardSide[0]._arr4[0]._stationPos = Common::Point(145, 42);
+
+ _gameBoardSide[0]._fieldB94 = Common::Point(280, 5);
+ _gameBoardSide[0]._fieldB98 = Common::Point(253, 5);
+ _gameBoardSide[0]._fieldB9C = Common::Point(226, 5);
+ _gameBoardSide[0]._fieldBA0 = Common::Point(199, 5);
+ _gameBoardSide[0]._fieldBA4 = 2;
+
+ _gameBoardSide[1]._handCard[0]._stationPos = Common::Point(283, 146);
+ _gameBoardSide[1]._handCard[1]._stationPos = Common::Point(283, 124);
+ _gameBoardSide[1]._handCard[2]._stationPos = Common::Point(283, 102);
+ _gameBoardSide[1]._handCard[3]._stationPos = Common::Point(283, 80);
+
+ _gameBoardSide[1]._outpostStation[0]._stationPos = Common::Point(253, 122);
+ _gameBoardSide[1]._outpostStation[1]._stationPos = Common::Point(227, 122);
+ _gameBoardSide[1]._outpostStation[2]._stationPos = Common::Point(201, 122);
+ _gameBoardSide[1]._outpostStation[3]._stationPos = Common::Point(201, 96);
+ _gameBoardSide[1]._outpostStation[4]._stationPos = Common::Point(201, 70);
+ _gameBoardSide[1]._outpostStation[5]._stationPos = Common::Point(227, 70);
+ _gameBoardSide[1]._outpostStation[6]._stationPos = Common::Point(253, 70);
+ _gameBoardSide[1]._outpostStation[7]._stationPos = Common::Point(253, 96);
+
+ _gameBoardSide[1]._delayPile[0]._stationPos = Common::Point(253, 43);
+
+ _gameBoardSide[1]._arr4[0]._stationPos = Common::Point(227, 96);
+
+ _gameBoardSide[1]._fieldB94 = Common::Point(283, 146);
+ _gameBoardSide[1]._fieldB98 = Common::Point(283, 124);
+ _gameBoardSide[1]._fieldB9C = Common::Point(283, 102);
+ _gameBoardSide[1]._fieldBA0 = Common::Point(283, 80);
+ _gameBoardSide[1]._fieldBA4 = 4;
subPostInit();
}
@@ -3870,10 +4475,10 @@ void Scene1337::process(Event &event) {
}
void Scene1337::dispatch() {
- if (_field424C == 0) {
- ++_field424E;
- if (_field424E == 4) {
- _field424C = 1;
+ if (_instructionsDisplayedFl == 0) {
+ ++_instructionsWaitCount;
+ if (_instructionsWaitCount == 4) {
+ _instructionsDisplayedFl = 1;
suggestInstructions();
}
}
@@ -3891,20 +4496,20 @@ void Scene1337::setAnimationInfo(unkObj1337sub1 *subObj) {
if (!subObj)
return;
- if (subObj->_field34 > 9) {
- if (subObj->_field34 > 25) {
- subObj->_object1.setStrip2(4);
- subObj->_object1.setFrame(subObj->_field34 - 25);
+ if (subObj->_cardId > 9) {
+ if (subObj->_cardId > 25) {
+ subObj->_card.setStrip2(4);
+ subObj->_card.setFrame(subObj->_cardId - 25);
} else {
- subObj->_object1.setStrip2(3);
- subObj->_object1.setFrame(subObj->_field34 - 9);
+ subObj->_card.setStrip2(3);
+ subObj->_card.setFrame(subObj->_cardId - 9);
}
} else {
- subObj->_object1.setStrip2(2);
- subObj->_object1.setFrame(subObj->_field34);
+ subObj->_card.setStrip2(2);
+ subObj->_card.setFrame(subObj->_cardId);
}
- subObj->_object1.show();
+ subObj->_card.show();
R2_GLOBALS._sceneObjects->draw();
}
@@ -3915,26 +4520,26 @@ void Scene1337::subC20E5() {
void Scene1337::subC20F9() {
switch (_field424A) {
case -1:
- ++_field423E;
- if (_field423E == 3)
- _field423E = 0;
+ ++_currentPlayerNumb;
+ if (_currentPlayerNumb == 3)
+ _currentPlayerNumb = 0;
- if (_field4244 == 1) {
- _object1.show();
- switch (_field423E) {
+ if (_field4244) {
+ _currentPlayerArrow.show();
+ switch (_currentPlayerNumb) {
case 0:
- _object1.setStrip(3);
+ _currentPlayerArrow.setStrip(3);
break;
case 1:
- _object1.setStrip(4);
+ _currentPlayerArrow.setStrip(4);
break;
case 2:
subD1975(174, 107);
- _object1.setStrip(1);
+ _currentPlayerArrow.setStrip(1);
break;
case 3:
subC4CEC();
- _object1.setStrip(2);
+ _currentPlayerArrow.setStrip(2);
break;
default:
break;
@@ -3990,15 +4595,15 @@ void Scene1337::subC20F9() {
}
void Scene1337::subC2586() {
- if (_field4244 != 0)
- _object1.hide();
+ if (_field4244)
+ _currentPlayerArrow.hide();
- switch (_field423E) {
+ switch (_currentPlayerNumb) {
case 2:
subC4CD2();
- if (_field4246 == 1)
+ if (_field4246)
actionDisplay(1330, 114, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- _field4246 = 0;
+ _field4246 = false;
// No break on purpose
case 0:
// No break on purpose
@@ -4010,7 +4615,7 @@ void Scene1337::subC2586() {
break;
}
- _field4244 = 1;
+ _field4244 = true;
}
@@ -4053,7 +4658,7 @@ bool Scene1337::subC2687(int arg1) {
}
int Scene1337::subC26CB(int arg1, int arg2) {
- if ((_arrunkObj1337[arg1]._arr1[arg2]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[arg2]._field34 <= 9)) {
+ if ((_gameBoardSide[arg1]._handCard[arg2]._cardId > 1) && (_gameBoardSide[arg1]._handCard[arg2]._cardId <= 9)) {
return arg2;
}
@@ -4062,7 +4667,7 @@ int Scene1337::subC26CB(int arg1, int arg2) {
int Scene1337::subC2719(int arg1) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1)
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 1)
return i;
}
@@ -4071,7 +4676,7 @@ int Scene1337::subC2719(int arg1) {
int Scene1337::subC274D(int arg1) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13)
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 13)
return i;
}
@@ -4080,7 +4685,7 @@ int Scene1337::subC274D(int arg1) {
int Scene1337::subC2781(int arg1) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25)
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 25)
return i;
}
@@ -4133,7 +4738,7 @@ void Scene1337::subC2835(int arg1) {
switch (arg1) {
case 0:
for (i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ if (subC27F9(_gameBoardSide[arg1]._handCard[i]._cardId) != -1) {
found = true;
break;
}
@@ -4143,7 +4748,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ if (subC27B5(_gameBoardSide[arg1]._handCard[i]._cardId) != -1) {
found = true;
break;
}
@@ -4153,7 +4758,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
+ if ((_gameBoardSide[arg1]._handCard[i]._cardId > 1) && (_gameBoardSide[arg1]._handCard[i]._cardId <= 9)) {
found = true;
break;
}
@@ -4163,7 +4768,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
+ if ((_gameBoardSide[arg1]._handCard[i]._cardId >= 26) && (_gameBoardSide[arg1]._handCard[i]._cardId <= 33)) {
found = true;
break;
}
@@ -4173,7 +4778,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 1) {
found = true;
break;
}
@@ -4183,7 +4788,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 25) {
found = true;
break;
}
@@ -4193,7 +4798,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 13) {
found = true;
break;
}
@@ -4201,7 +4806,7 @@ void Scene1337::subC2835(int arg1) {
break;
case 1:
for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
+ if ((_gameBoardSide[arg1]._handCard[i]._cardId >= 26) && (_gameBoardSide[arg1]._handCard[i]._cardId <= 33)) {
found = true;
break;
}
@@ -4211,7 +4816,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 1) {
found = true;
break;
}
@@ -4221,7 +4826,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
+ if ((_gameBoardSide[arg1]._handCard[i]._cardId > 1) && (_gameBoardSide[arg1]._handCard[i]._cardId <= 9)) {
found = true;
break;
}
@@ -4231,7 +4836,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ if (subC27F9(_gameBoardSide[arg1]._handCard[i]._cardId) != -1) {
found = true;
break;
}
@@ -4241,7 +4846,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
+ if (subC27B5(_gameBoardSide[arg1]._handCard[i]._cardId) != -1) {
found = true;
break;
}
@@ -4251,7 +4856,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 25) {
found = true;
break;
}
@@ -4261,7 +4866,7 @@ void Scene1337::subC2835(int arg1) {
break;
for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
+ if (_gameBoardSide[arg1]._handCard[i]._cardId == 13) {
found = true;
break;
}
@@ -4272,14 +4877,14 @@ void Scene1337::subC2835(int arg1) {
return;
}
- subC4A39(&_arrunkObj1337[arg1]._arr1[i]);
+ subC4A39(&_gameBoardSide[arg1]._handCard[i]);
}
bool Scene1337::subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt) {
- if ((subObj1->_field36.x > pt.x) || (subObj1->_field36.x + 24 < pt.x))
+ if ((subObj1->_stationPos.x > pt.x) || (subObj1->_stationPos.x + 24 < pt.x))
return false;
- if ((subObj1->_field36.y > pt.y) || (subObj1->_field36.y + 24 < pt.y))
+ if ((subObj1->_stationPos.y > pt.y) || (subObj1->_stationPos.y + 24 < pt.y))
return false;
return true;
@@ -4288,8 +4893,8 @@ bool Scene1337::subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt) {
void Scene1337::subC2C2F() {
bool found = true;
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[3]._arr3[0]._field34) {
+ if (_gameBoardSide[3]._delayPile[0]._cardId != 0) {
+ switch (_gameBoardSide[3]._delayPile[0]._cardId) {
case 10:
// No break on purpose
case 12:
@@ -4305,14 +4910,14 @@ void Scene1337::subC2C2F() {
case 20:
// No break on purpose
case 21:
- subC4A39(&_arrunkObj1337[3]._arr3[0]);
+ subC4A39(&_gameBoardSide[3]._delayPile[0]);
found = false;
break;
default:
found = false;
int i;
for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[3]._arr3[0]._field34, _arrunkObj1337[3]._arr1[i]._field34)) {
+ if (subC3386(_gameBoardSide[3]._delayPile[0]._cardId, _gameBoardSide[3]._handCard[i]._cardId)) {
found = true;
break;
}
@@ -4320,7 +4925,7 @@ void Scene1337::subC2C2F() {
if (found) {
found = false;
- subC34A1(&_arrunkObj1337[3]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ subC34A1(&_gameBoardSide[3]._handCard[i], &_gameBoardSide[3]._delayPile[0]);
}
break;
}
@@ -4331,12 +4936,12 @@ void Scene1337::subC2C2F() {
int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 1) {
+ if (_gameBoardSide[3]._handCard[randIndx]._cardId == 1) {
found = false;
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[3]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[3]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
+ if ((_gameBoardSide[3]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[3]._delayPile[0]._cardId))) {
+ subC340B(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[3]._outpostStation[i]);
found = true;
break;
}
@@ -4345,11 +4950,11 @@ void Scene1337::subC2C2F() {
if (found) {
return;
}
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 <= 9) {
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId <= 9) {
found = false;
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[3]._arr2[i]._field34 == _arrunkObj1337[3]._arr1[randIndx]._field34) {
+ if (_gameBoardSide[3]._outpostStation[i]._cardId == _gameBoardSide[3]._handCard[randIndx]._cardId) {
found = true;
break;
}
@@ -4357,18 +4962,18 @@ void Scene1337::subC2C2F() {
if (!found) {
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[3]._arr2[i]._field34 == 1) && (!subC2687(_arrunkObj1337[3]._arr3[i]._field34))) {
+ if ((_gameBoardSide[3]._outpostStation[i]._cardId == 1) && (!subC2687(_gameBoardSide[3]._delayPile[0]._cardId))) {
int tmpVal = 0;
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr2[j]._field34 > 1) && (_arrunkObj1337[3]._arr2[j]._field34 <= 9))
+ if ((_gameBoardSide[3]._outpostStation[j]._cardId > 1) && (_gameBoardSide[3]._outpostStation[j]._cardId <= 9))
++tmpVal;
}
if (tmpVal == 7)
_field424A = 3;
- subC33C0(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
+ subC33C0(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[3]._outpostStation[i]);
found = true;
break;
}
@@ -4376,24 +4981,24 @@ void Scene1337::subC2C2F() {
if (found)
return;
}
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 13) {
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId == 13) {
int tmpVal = subC331B(3);
if (tmpVal != -1) {
- subC358E(&_arrunkObj1337[3]._arr1[randIndx], tmpVal);
+ subC358E(&_gameBoardSide[3]._handCard[randIndx], tmpVal);
return;
}
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 25) {
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId == 25) {
int tmpVal = -1;
found = false;
int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
for (int i = 0; i <= 3; i++) {
if ( (tmpRandIndx != 3)
- && ( (_arrunkObj1337[tmpRandIndx]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[3]._field34 != 0) )) {
+ && ( (_gameBoardSide[tmpRandIndx]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[3]._cardId != 0) )) {
tmpVal = tmpRandIndx;
break;
}
@@ -4404,11 +5009,11 @@ void Scene1337::subC2C2F() {
}
if (tmpVal != -1) {
- subC318B(3, &_arrunkObj1337[3]._arr1[randIndx], tmpVal);
+ subC318B(3, &_gameBoardSide[3]._handCard[randIndx], tmpVal);
return;
}
} else {
- switch (_arrunkObj1337[3]._arr1[randIndx]._field34) {
+ switch (_gameBoardSide[3]._handCard[randIndx]._cardId) {
case 10:
// No break on purpose
case 11:
@@ -4441,7 +5046,7 @@ void Scene1337::subC2C2F() {
// It's understandable for 'i', which helps making sure that tmpVal is used properly,
// but it's suspect for j
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[tmpRandIndx]._arr3[0]._field34 == 0) && (subC32B1(tmpRandIndx, _arrunkObj1337[3]._arr1[randIndx]._field34))) {
+ if ((_gameBoardSide[tmpRandIndx]._delayPile[0]._cardId == 0) && (subC32B1(tmpRandIndx, _gameBoardSide[3]._handCard[randIndx]._cardId))) {
tmpVal = j;
}
}
@@ -4457,7 +5062,7 @@ void Scene1337::subC2C2F() {
if (tmpVal != -1) {
// Useless second identical check skipped
- subC3456(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[tmpVal]._arr3[0]);
+ subC3456(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[tmpVal]._delayPile[0]);
return;
}
}
@@ -4466,7 +5071,7 @@ void Scene1337::subC2C2F() {
}
}
- subC4A39(&_arrunkObj1337[3]._arr1[randIndx]);
+ subC4A39(&_gameBoardSide[3]._handCard[randIndx]);
}
void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) {
@@ -4477,13 +5082,13 @@ void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) {
for (;;) {
randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- if (_arrunkObj1337[arg3]._arr1[randIndx]._field34 != 0)
+ if (_gameBoardSide[arg3]._handCard[randIndx]._cardId != 0)
break;
}
_field3EF0 = subObj1;
- _field3EF4 = &_arrunkObj1337[arg3]._arr4[0];
- _field3EF8 = &_arrunkObj1337[arg3]._arr1[randIndx];
+ _field3EF4 = &_gameBoardSide[arg3]._arr4[0];
+ _field3EF8 = &_gameBoardSide[arg3]._handCard[randIndx];
_item1.setAction(&_action11);
}
@@ -4525,9 +5130,9 @@ int Scene1337::subC3257(int arg1) {
bool Scene1337::subC32B1(int arg1, int arg2) {
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[arg1]._arr2[i]._field34 != 0) {
+ if (_gameBoardSide[arg1]._outpostStation[i]._cardId != 0) {
int tmpVal = subC3257(arg2);
- if (tmpVal == _arrunkObj1337[arg1]._arr2[i]._field34)
+ if (tmpVal == _gameBoardSide[arg1]._outpostStation[i]._cardId)
return false;
}
}
@@ -4540,7 +5145,7 @@ int Scene1337::subC331B(int arg1) {
for (int i = 0; i <= 3; i++) {
if (randIndx != arg1) {
for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[randIndx]._arr2[j]._field34 != 0)
+ if (_gameBoardSide[randIndx]._outpostStation[j]._cardId != 0)
return randIndx;
}
}
@@ -4582,16 +5187,16 @@ void Scene1337::subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
}
int Scene1337::subC3E92(int arg1) {
- if ( (_arrunkObj1337[arg1]._arr1[0]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[1]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[2]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[3]._field34 == 0))
+ if ( (_gameBoardSide[arg1]._handCard[0]._cardId == 0)
+ && (_gameBoardSide[arg1]._handCard[1]._cardId == 0)
+ && (_gameBoardSide[arg1]._handCard[2]._cardId == 0)
+ && (_gameBoardSide[arg1]._handCard[3]._cardId == 0))
return -1;
int randIndx;
for (;;) {
randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- if (_arrunkObj1337[arg1]._arr1[randIndx]._field34 == 0)
+ if (_gameBoardSide[arg1]._handCard[randIndx]._cardId == 0)
break;
}
@@ -4621,14 +5226,14 @@ void Scene1337::subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) {
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[arg1]._arr2[i]._field34 == 1) {
- return &_arrunkObj1337[arg1]._arr2[i];
+ if (_gameBoardSide[arg1]._outpostStation[i]._cardId == 1) {
+ return &_gameBoardSide[arg1]._outpostStation[i];
}
}
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[arg1]._arr2[i]._field34 != 0) && (_arrunkObj1337[arg1]._arr2[i]._field34 < 10)) {
- return &_arrunkObj1337[arg1]._arr2[i];
+ if ((_gameBoardSide[arg1]._outpostStation[i]._cardId != 0) && (_gameBoardSide[arg1]._outpostStation[i]._cardId < 10)) {
+ return &_gameBoardSide[arg1]._outpostStation[i];
}
}
@@ -4638,7 +5243,7 @@ Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) {
void Scene1337::subC358E(unkObj1337sub1 *subObj1, int arg2) {
_field3EF0 = subObj1;
_field3EF4 = subC34EC(arg2);
- _field3EF8 = &_arrunkObj1337[arg2]._arr4[0];
+ _field3EF8 = &_gameBoardSide[arg2]._arr4[0];
_field4240 = arg2;
_item1.setAction(&_action10);
}
@@ -4661,7 +5266,7 @@ void Scene1337::subC4CEC() {
return;
subD18F5();
- subD1940(1);
+ subD1940(true);
}
void Scene1337::subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
@@ -4781,148 +5386,148 @@ void Scene1337::subPostInit() {
R2_GLOBALS._scenePalette.addRotation(224, 235, 1);
- _field3E28[0] = 1;
- _field3E28[1] = 1;
- _field3E28[2] = 1;
- _field3E28[3] = 1;
- _field3E28[4] = 1;
- _field3E28[5] = 1;
- _field3E28[6] = 1;
- _field3E28[7] = 1;
- _field3E28[8] = 26;
- _field3E28[9] = 2;
- _field3E28[10] = 2;
- _field3E28[11] = 2;
- _field3E28[12] = 2;
- _field3E28[13] = 2;
- _field3E28[14] = 26;
- _field3E28[15] = 3;
- _field3E28[16] = 3;
- _field3E28[17] = 3;
- _field3E28[18] = 3;
- _field3E28[19] = 3;
- _field3E28[20] = 28;
- _field3E28[21] = 4;
- _field3E28[22] = 4;
- _field3E28[23] = 4;
- _field3E28[24] = 4;
- _field3E28[25] = 4;
- _field3E28[26] = 28;
- _field3E28[27] = 5;
- _field3E28[28] = 5;
- _field3E28[29] = 5;
- _field3E28[30] = 5;
- _field3E28[31] = 5;
- _field3E28[32] = 30;
- _field3E28[33] = 6;
- _field3E28[34] = 6;
- _field3E28[35] = 6;
- _field3E28[36] = 6;
- _field3E28[37] = 6;
- _field3E28[38] = 30;
- _field3E28[39] = 7;
- _field3E28[40] = 7;
- _field3E28[41] = 7;
- _field3E28[42] = 7;
- _field3E28[43] = 7;
- _field3E28[44] = 32;
- _field3E28[45] = 8;
- _field3E28[46] = 8;
- _field3E28[47] = 8;
- _field3E28[48] = 8;
- _field3E28[49] = 8;
- _field3E28[50] = 32;
- _field3E28[51] = 9;
- _field3E28[52] = 9;
- _field3E28[53] = 9;
- _field3E28[54] = 9;
- _field3E28[55] = 9;
- _field3E28[56] = 10;
- _field3E28[57] = 11;
- _field3E28[58] = 12;
- _field3E28[59] = 13;
- _field3E28[60] = 13;
- _field3E28[61] = 14;
- _field3E28[62] = 15;
- _field3E28[63] = 16;
- _field3E28[64] = 17;
- _field3E28[65] = 18;
- _field3E28[66] = 19;
- _field3E28[67] = 20;
- _field3E28[68] = 21;
- _field3E28[69] = 26;
- _field3E28[70] = 28;
- _field3E28[71] = 24;
- _field3E28[72] = 25;
- _field3E28[73] = 25;
- _field3E28[74] = 25;
- _field3E28[75] = 25;
- _field3E28[76] = 26;
- _field3E28[77] = 26;
- _field3E28[78] = 26;
- _field3E28[79] = 27;
- _field3E28[80] = 27;
- _field3E28[81] = 28;
- _field3E28[82] = 28;
- _field3E28[83] = 28;
- _field3E28[84] = 29;
- _field3E28[85] = 29;
- _field3E28[86] = 29;
- _field3E28[87] = 30;
- _field3E28[88] = 30;
- _field3E28[89] = 30;
- _field3E28[90] = 30;
- _field3E28[91] = 32;
- _field3E28[92] = 1;
- _field3E28[93] = 32;
- _field3E28[94] = 32;
- _field3E28[95] = 32;
- _field3E28[96] = 1;
- _field3E28[97] = 1;
- _field3E28[98] = 1;
- _field3E28[99] = 0;
-
- _field3E24 = 98;
+ _availableCardsPile[0] = 1;
+ _availableCardsPile[1] = 1;
+ _availableCardsPile[2] = 1;
+ _availableCardsPile[3] = 1;
+ _availableCardsPile[4] = 1;
+ _availableCardsPile[5] = 1;
+ _availableCardsPile[6] = 1;
+ _availableCardsPile[7] = 1;
+ _availableCardsPile[8] = 26;
+ _availableCardsPile[9] = 2;
+ _availableCardsPile[10] = 2;
+ _availableCardsPile[11] = 2;
+ _availableCardsPile[12] = 2;
+ _availableCardsPile[13] = 2;
+ _availableCardsPile[14] = 26;
+ _availableCardsPile[15] = 3;
+ _availableCardsPile[16] = 3;
+ _availableCardsPile[17] = 3;
+ _availableCardsPile[18] = 3;
+ _availableCardsPile[19] = 3;
+ _availableCardsPile[20] = 28;
+ _availableCardsPile[21] = 4;
+ _availableCardsPile[22] = 4;
+ _availableCardsPile[23] = 4;
+ _availableCardsPile[24] = 4;
+ _availableCardsPile[25] = 4;
+ _availableCardsPile[26] = 28;
+ _availableCardsPile[27] = 5;
+ _availableCardsPile[28] = 5;
+ _availableCardsPile[29] = 5;
+ _availableCardsPile[30] = 5;
+ _availableCardsPile[31] = 5;
+ _availableCardsPile[32] = 30;
+ _availableCardsPile[33] = 6;
+ _availableCardsPile[34] = 6;
+ _availableCardsPile[35] = 6;
+ _availableCardsPile[36] = 6;
+ _availableCardsPile[37] = 6;
+ _availableCardsPile[38] = 30;
+ _availableCardsPile[39] = 7;
+ _availableCardsPile[40] = 7;
+ _availableCardsPile[41] = 7;
+ _availableCardsPile[42] = 7;
+ _availableCardsPile[43] = 7;
+ _availableCardsPile[44] = 32;
+ _availableCardsPile[45] = 8;
+ _availableCardsPile[46] = 8;
+ _availableCardsPile[47] = 8;
+ _availableCardsPile[48] = 8;
+ _availableCardsPile[49] = 8;
+ _availableCardsPile[50] = 32;
+ _availableCardsPile[51] = 9;
+ _availableCardsPile[52] = 9;
+ _availableCardsPile[53] = 9;
+ _availableCardsPile[54] = 9;
+ _availableCardsPile[55] = 9;
+ _availableCardsPile[56] = 10;
+ _availableCardsPile[57] = 11;
+ _availableCardsPile[58] = 12;
+ _availableCardsPile[59] = 13;
+ _availableCardsPile[60] = 13;
+ _availableCardsPile[61] = 14;
+ _availableCardsPile[62] = 15;
+ _availableCardsPile[63] = 16;
+ _availableCardsPile[64] = 17;
+ _availableCardsPile[65] = 18;
+ _availableCardsPile[66] = 19;
+ _availableCardsPile[67] = 20;
+ _availableCardsPile[68] = 21;
+ _availableCardsPile[69] = 26;
+ _availableCardsPile[70] = 28;
+ _availableCardsPile[71] = 24;
+ _availableCardsPile[72] = 25;
+ _availableCardsPile[73] = 25;
+ _availableCardsPile[74] = 25;
+ _availableCardsPile[75] = 25;
+ _availableCardsPile[76] = 26;
+ _availableCardsPile[77] = 26;
+ _availableCardsPile[78] = 26;
+ _availableCardsPile[79] = 27;
+ _availableCardsPile[80] = 27;
+ _availableCardsPile[81] = 28;
+ _availableCardsPile[82] = 28;
+ _availableCardsPile[83] = 28;
+ _availableCardsPile[84] = 29;
+ _availableCardsPile[85] = 29;
+ _availableCardsPile[86] = 29;
+ _availableCardsPile[87] = 30;
+ _availableCardsPile[88] = 30;
+ _availableCardsPile[89] = 30;
+ _availableCardsPile[90] = 30;
+ _availableCardsPile[91] = 32;
+ _availableCardsPile[92] = 1;
+ _availableCardsPile[93] = 32;
+ _availableCardsPile[94] = 32;
+ _availableCardsPile[95] = 32;
+ _availableCardsPile[96] = 1;
+ _availableCardsPile[97] = 1;
+ _availableCardsPile[98] = 1;
+ _availableCardsPile[99] = 0;
+
+ _cardsAvailableNumb = 98;
_field3E26 = 98;
- _item7._field34 = 0;
- _item7._field36 = Common::Point(128, 95);
-
- _item8._field34 = 0;
- _item8._field36 = Common::Point(162, 95);
-
- _item6._field34 = 0;
-
- _item2._object1.postInit();
- _item2._object1.setVisage(1332);
- _item2._object1.setStrip(5);
- _item2._object1.setFrame(1);
- _item2._object1._moveDiff = Common::Point(10, 10);
- _item2._object1.fixPriority(400);
- _item2._object1.setPosition(Common::Point(128, 95), 0);
- _item2._object1.animate(ANIM_MODE_2, NULL);
- _item2._object1.hide();
-
- _object1.postInit();
- _object1.setVisage(1334);
- _object1.setStrip(1);
- _object1.setFrame(1);
- _object1._numFrames = 12;
- _object1.fixPriority(500);
- _object1.setPosition(Common::Point(174, 107), 0);
- _object1.animate(ANIM_MODE_2, NULL);
- _object1.hide();
-
- _field4244 = 1;
- _field4246 = 0;
+ _discardPile._cardId = 0;
+ _discardPile._stationPos = Common::Point(128, 95);
+
+ _item8._cardId = 0;
+ _item8._stationPos = Common::Point(162, 95);
+
+ _item6._cardId = 0;
+
+ _animatedCard._card.postInit();
+ _animatedCard._card.setVisage(1332);
+ _animatedCard._card.setStrip(5);
+ _animatedCard._card.setFrame(1);
+ _animatedCard._card._moveDiff = Common::Point(10, 10);
+ _animatedCard._card.fixPriority(400);
+ _animatedCard._card.setPosition(Common::Point(128, 95), 0);
+ _animatedCard._card.animate(ANIM_MODE_2, NULL);
+ _animatedCard._card.hide();
+
+ _currentPlayerArrow.postInit();
+ _currentPlayerArrow.setVisage(1334);
+ _currentPlayerArrow.setStrip(1);
+ _currentPlayerArrow.setFrame(1);
+ _currentPlayerArrow._numFrames = 12;
+ _currentPlayerArrow.fixPriority(500);
+ _currentPlayerArrow.setPosition(Common::Point(174, 107), 0);
+ _currentPlayerArrow.animate(ANIM_MODE_2, NULL);
+ _currentPlayerArrow.hide();
+
+ _field4244 = true;
+ _field4246 = false;
_field4248 = 0;
_field424A = -1;
_background1.setup2(9531, 1, 1, 249, 168, 155, 0);
_autoplay = false;
- _field424C = 0;
- _field424E = 0;
+ _instructionsDisplayedFl = 0;
+ _instructionsWaitCount = 0;
}
void Scene1337::suggestInstructions() {
@@ -4931,73 +5536,70 @@ void Scene1337::suggestInstructions() {
if (MessageDialog::show(NEED_INSTRUCTIONS, NO_MSG, YES_MSG) == 0) {
if (R2_GLOBALS._v57709 == 0)
subD18F5();
- subCCF26();
+ firstShuffle();
} else {
if (R2_GLOBALS._v57709 == 0)
subD18F5();
- subCB59B();
+ displayInstructions();
}
}
-void Scene1337::subCB59B() {
+void Scene1337::displayInstructions() {
_item1.setAction(&_action1);
}
void Scene1337::shuffleCards() {
R2_GLOBALS._sceneObjects->draw();
+ // Remove holes in card pile
for (int i = 0; i <= 98; i++) {
- if (_field3E28[i] == 0) {
+ if (_availableCardsPile[i] == 0) {
for (int j = i + 1; j <= 98; j ++) {
- if (_field3E28[j] != 0) {
- _field3E28[i] = _field3E28[j];
- _field3E28[j] = 0;
+ if (_availableCardsPile[j] != 0) {
+ _availableCardsPile[i] = _availableCardsPile[j];
+ _availableCardsPile[j] = 0;
break;
}
}
}
}
+ // Compute the number of available cards
for (int i = 0; i <= 99; i ++) {
- if (_field3E28[i] == 0) {
- _field3E24 = i - 1;
+ if (_availableCardsPile[i] == 0) {
+ // CHECKME: This will fail if i == 0, which shouldn't happen
+ // as we don't shuffle cards when no card is available.
+ _cardsAvailableNumb = i - 1;
_field3E26 = 98;
break;
}
}
- // tmpVal is never modified in the original. It looks weird but it works: at the end, the cards are suffled!
- int tmpVal = 0;
- int randIndx;
- int swap;
for (int i = 0; i < 2000; i ++) {
- randIndx = R2_GLOBALS._randomSource.getRandomNumber(_field3E24);
- swap = _field3E28[tmpVal];
- _field3E28[tmpVal] = _field3E28[randIndx];
- _field3E28[randIndx] = swap;
+ int randIndx = R2_GLOBALS._randomSource.getRandomNumber(_cardsAvailableNumb);
+ int swap = _availableCardsPile[0];
+ _availableCardsPile[0] = _availableCardsPile[randIndx];
+ _availableCardsPile[randIndx] = swap;
}
- _field423C = 0;
- _item2._object1.setAction(&_action2);
+ _shuffleEndedFl = false;
+ _animatedCard._card.setAction(&_action2);
- while(_field423C == 0) {
+ while(!_shuffleEndedFl && !g_vm->shouldQuit()) {
+ g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
g_globals->_scenePalette.signalListeners();
R2_GLOBALS._sceneObjects->draw();
- warning("TODO: recurse on draw() and on signalListeners()?");
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
-
- // Hack to avoid eternal loop
- // To be removed when the recurse is working properly
- _field423C = 1;
}
}
-void Scene1337::subCCF26() {
- _item2._object1._moveDiff = Common::Point(30, 30);
+void Scene1337::firstShuffle() {
+ _animatedCard._card._moveDiff = Common::Point(30, 30);
shuffleCards();
_item1.setAction(&_action3);
}
void Scene1337::subCD193() {
+ // Display menu with "Auto Play", "New Game", "Quit" and "Continue"
warning("STUBBED: subCD193()");
}
@@ -5008,10 +5610,10 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
if (arg1 == 3) {
int i;
for (i = 0; i <= 7; i++) {
- if ( (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) ) {
+ if ( (subC2BF8(&_gameBoardSide[2]._outpostStation[i], pt))
+ || (subC2BF8(&_gameBoardSide[0]._outpostStation[i], pt))
+ || (subC2BF8(&_gameBoardSide[1]._outpostStation[i], pt))
+ || (subC2BF8(&_gameBoardSide[3]._outpostStation[i], pt)) ) {
found = true;
break;
}
@@ -5020,26 +5622,26 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
if (found) {
switch (curReg) {
case 5:
- if (_arrunkObj1337[2]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[2]._arr2[i]._field34);
+ if (_gameBoardSide[2]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[2]._outpostStation[i]._cardId);
else
actionDisplay(1330, 20, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 10:
- if (_arrunkObj1337[3]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr2[i]._field34);
+ if (_gameBoardSide[3]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[3]._outpostStation[i]._cardId);
else
actionDisplay(1330, 22, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 15:
- if (_arrunkObj1337[0]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[0]._arr2[i]._field34);
+ if (_gameBoardSide[0]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[0]._outpostStation[i]._cardId);
else
actionDisplay(1330, 21, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 20:
- if (_arrunkObj1337[1]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[1]._arr2[i]._field34);
+ if (_gameBoardSide[1]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[1]._outpostStation[i]._cardId);
else
actionDisplay(1330, 23, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5047,36 +5649,36 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
break;
}
} else {
- if ( (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) ) {
+ if ( (subC2BF8(&_gameBoardSide[2]._delayPile[0], pt))
+ || (subC2BF8(&_gameBoardSide[0]._delayPile[0], pt))
+ || (subC2BF8(&_gameBoardSide[1]._delayPile[0], pt))
+ || (subC2BF8(&_gameBoardSide[3]._delayPile[0], pt)) ) {
found = true;
}
if (found) {
switch (curReg) {
case 5:
- if (_arrunkObj1337[2]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[2]._arr3[0]._field34);
+ if (_gameBoardSide[2]._delayPile[0]._cardId != 0)
+ displayDialog(_gameBoardSide[2]._delayPile[0]._cardId);
else
actionDisplay(1330, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 10:
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
+ if (_gameBoardSide[3]._delayPile[0]._cardId != 0)
+ displayDialog(_gameBoardSide[3]._delayPile[0]._cardId);
else
actionDisplay(1330, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 15:
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
+ if (_gameBoardSide[0]._delayPile[0]._cardId != 0)
+ displayDialog(_gameBoardSide[3]._delayPile[0]._cardId);
else
actionDisplay(1330, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 20:
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[1]._arr3[0]._field34);
+ if (_gameBoardSide[1]._delayPile[0]._cardId != 0)
+ displayDialog(_gameBoardSide[1]._delayPile[0]._cardId);
else
actionDisplay(1330, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5084,29 +5686,29 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
break;
}
} else {
- if (subC2BF8(&_item7, pt)) {
- if (_item7._field34 != 0)
- displayDialog(_item7._field34);
+ if (subC2BF8(&_discardPile, pt)) {
+ if (_discardPile._cardId != 0)
+ displayDialog(_discardPile._cardId);
else
actionDisplay(1330, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else if (_background1._bounds.contains(pt)) {
actionDisplay(1330, 43, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else if (subC2BF8(&_item8, pt)) {
actionDisplay(1330, 4, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if ( (subC2BF8(&_arrunkObj1337[2]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) ) {
+ } else if ( (subC2BF8(&_gameBoardSide[2]._arr4[0], pt))
+ || (subC2BF8(&_gameBoardSide[3]._arr4[0], pt))
+ || (subC2BF8(&_gameBoardSide[0]._arr4[0], pt))
+ || (subC2BF8(&_gameBoardSide[1]._arr4[0], pt)) ) {
actionDisplay(1330, 32, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
- if (subC2BF8(&_arrunkObj1337[2]._arr1[0], pt))
- displayDialog(_arrunkObj1337[2]._arr1[0]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[1], pt))
- displayDialog(_arrunkObj1337[2]._arr1[1]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[2], pt))
- displayDialog(_arrunkObj1337[2]._arr1[2]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[3], pt))
- displayDialog(_arrunkObj1337[2]._arr1[3]._field34);
+ if (subC2BF8(&_gameBoardSide[2]._handCard[0], pt))
+ displayDialog(_gameBoardSide[2]._handCard[0]._cardId);
+ else if (subC2BF8(&_gameBoardSide[2]._handCard[1], pt))
+ displayDialog(_gameBoardSide[2]._handCard[1]._cardId);
+ else if (subC2BF8(&_gameBoardSide[2]._handCard[2], pt))
+ displayDialog(_gameBoardSide[2]._handCard[2]._cardId);
+ else if (subC2BF8(&_gameBoardSide[2]._handCard[3], pt))
+ displayDialog(_gameBoardSide[2]._handCard[3]._cardId);
else if ((curReg >= 6) && (curReg <= 9))
actionDisplay(1330, 29, 159, 10, 1, 200, 0, 7, 0, 154, 154);
else if ((curReg >= 11) && (curReg <= 14))
@@ -5146,8 +5748,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
return;
for (int i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt)) {
- switch (_arrunkObj1337[2]._arr2[i]._field34) {
+ if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], pt)) {
+ switch (_gameBoardSide[2]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5160,8 +5762,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
}
found = true;
break;
- } else if (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt)) {
- switch (_arrunkObj1337[0]._arr2[i]._field34) {
+ } else if (subC2BF8(&_gameBoardSide[0]._outpostStation[i], pt)) {
+ switch (_gameBoardSide[0]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5171,8 +5773,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
}
found = true;
break;
- } else if (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt)) {
- switch (_arrunkObj1337[1]._arr2[i]._field34) {
+ } else if (subC2BF8(&_gameBoardSide[1]._outpostStation[i], pt)) {
+ switch (_gameBoardSide[1]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
break;
@@ -5182,8 +5784,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
}
found = true;
break;
- } else if (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) {
- switch (_arrunkObj1337[3]._arr2[i]._field34) {
+ } else if (subC2BF8(&_gameBoardSide[3]._outpostStation[i], pt)) {
+ switch (_gameBoardSide[3]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
break;
@@ -5196,8 +5798,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
}
}
- if (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt)) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ if (subC2BF8(&_gameBoardSide[2]._delayPile[0], pt)) {
+ if (_gameBoardSide[0]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 39, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
@@ -5205,8 +5807,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
found = true;
}
- if (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) {
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ if (subC2BF8(&_gameBoardSide[3]._delayPile[0], pt)) {
+ if (_gameBoardSide[3]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
} else {
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
@@ -5214,8 +5816,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
found = true;
}
- if (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt)) {
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ if (subC2BF8(&_gameBoardSide[1]._delayPile[0], pt)) {
+ if (_gameBoardSide[1]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
} else {
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
@@ -5223,8 +5825,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
found = true;
}
- if (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt)) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ if (subC2BF8(&_gameBoardSide[0]._delayPile[0], pt)) {
+ if (_gameBoardSide[0]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
@@ -5232,17 +5834,17 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
found = true;
}
- if (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt)) {
+ if (subC2BF8(&_gameBoardSide[3]._arr4[0], pt)) {
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
found = true;
}
- if (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) {
+ if (subC2BF8(&_gameBoardSide[1]._arr4[0], pt)) {
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
found = true;
}
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt)) {
+ if (subC2BF8(&_gameBoardSide[0]._arr4[0], pt)) {
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
found = true;
}
@@ -5255,7 +5857,7 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
return;
}
- if (subC2BF8(&_item7, pt))
+ if (subC2BF8(&_discardPile, pt))
actionDisplay(1330, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
else if (subC2BF8(&_item8, pt))
actionDisplay(1330, 5, 159, 10, 1, 200, 0, 7, 0, 154, 154);
@@ -5309,8 +5911,8 @@ void Scene1337::subCF31D() {
bool found;
int count;
- if (this->_arrunkObj1337[1]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[1]._arr3[0]._field34) {
+ if (this->_gameBoardSide[1]._delayPile[0]._cardId != 0) {
+ switch (_gameBoardSide[1]._delayPile[0]._cardId) {
case 10:
// No break on purpose
case 12:
@@ -5327,13 +5929,13 @@ void Scene1337::subCF31D() {
// No break on purpose
case 21:
tmpVal = 0;
- subC4A39(&_arrunkObj1337[1]._arr3[0]);
+ subC4A39(&_gameBoardSide[1]._delayPile[0]);
break;
default:
found = false;
int i;
for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[1]._arr3[0]._field34, _arrunkObj1337[1]._arr1[i]._field34)) {
+ if (subC3386(_gameBoardSide[1]._delayPile[0]._cardId, _gameBoardSide[1]._handCard[i]._cardId)) {
found = true;
break;
}
@@ -5341,7 +5943,7 @@ void Scene1337::subCF31D() {
if (found) {
tmpVal = 0;
- subC34A1(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ subC34A1(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[1]._delayPile[0]);
}
}
}
@@ -5357,7 +5959,7 @@ void Scene1337::subCF31D() {
tmpVal = 0;
for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[1]._arr2[j]._field34 == _arrunkObj1337[1]._arr1[tmpIndx]._field34) {
+ if (_gameBoardSide[1]._outpostStation[j]._cardId == _gameBoardSide[1]._handCard[tmpIndx]._cardId) {
tmpVal = 1;
break;
}
@@ -5367,18 +5969,18 @@ void Scene1337::subCF31D() {
break;
for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[1]._arr2[j]._field34 == 1) {
- if (!subC2687(_arrunkObj1337[1]._arr3[0]._field34)) {
+ if (_gameBoardSide[1]._outpostStation[j]._cardId == 1) {
+ if (!subC2687(_gameBoardSide[1]._delayPile[0]._cardId)) {
count = 0;
for (int k = 0; k <= 7; k++) {
- if ((_arrunkObj1337[1]._arr2[k]._field34 > 1) && (_arrunkObj1337[1]._arr2[k]._field34 <= 9))
+ if ((_gameBoardSide[1]._outpostStation[k]._cardId > 1) && (_gameBoardSide[1]._outpostStation[k]._cardId <= 9))
++count;
}
if (count == 7)
_field424A = 1;
- subC33C0(&_arrunkObj1337[1]._arr1[tmpIndx], &_arrunkObj1337[1]._arr2[j]);
+ subC33C0(&_gameBoardSide[1]._handCard[tmpIndx], &_gameBoardSide[1]._outpostStation[j]);
found = true;
break;
}
@@ -5392,9 +5994,10 @@ void Scene1337::subCF31D() {
tmpVal = subC2719(1);
if (tmpVal != -1) {
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[1]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[1]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[1]._arr1[tmpVal], &_arrunkObj1337[1]._arr2[i]);
+ if ((_gameBoardSide[1]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[1]._delayPile[0]._cardId))) {
+ subC340B(&_gameBoardSide[1]._handCard[tmpVal], &_gameBoardSide[1]._outpostStation[i]);
found = true;
+ break;
}
}
}
@@ -5405,8 +6008,10 @@ void Scene1337::subCF31D() {
tmpVal = subC274D(1);
int tmpVal2 = subC331B(1);
- if ((tmpVal != -1) && ( tmpVal2 != -1))
- subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
+ if ((tmpVal != -1) && ( tmpVal2 != -1)) {
+ subC358E(&_gameBoardSide[1]._handCard[tmpVal], tmpVal2);
+ found = true;
+ }
if (found)
return;
@@ -5417,14 +6022,14 @@ void Scene1337::subCF31D() {
int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
for (int i = 0; i <= 3; i++) {
if (rndVal != 1) {
- if ( (_arrunkObj1337[rndVal]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[3]._field34 == 0)) {
+ if ( (_gameBoardSide[rndVal]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[3]._cardId == 0)) {
count = rndVal;
break;
}
-
+ // CHECKME: inside the check on rndVal?
rndVal--;
if (rndVal < 0)
rndVal = 3;
@@ -5432,7 +6037,7 @@ void Scene1337::subCF31D() {
}
if (count != -1) {
- subC318B(1, &_arrunkObj1337[1]._arr1[tmpVal], count);
+ subC318B(1, &_gameBoardSide[1]._handCard[tmpVal], count);
found = true;
}
}
@@ -5443,16 +6048,17 @@ void Scene1337::subCF31D() {
count = -1;
int i;
for (i = 0; i <= 3; i++) {
- tmpVal = subC27B5(_arrunkObj1337[1]._arr1[i]._field34);
+ tmpVal = subC27B5(_gameBoardSide[1]._handCard[i]._cardId);
if (tmpVal != -1) {
int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
for (int j = 0; j <= 3; j++) {
+ //CHECKME: tmpVal or rndVal?
if (tmpVal != 1) {
for (int k = 0; k <= 7; k++) {
- // 'k' is not used in that loop.
+ // CHECKME: 'k' is not used in that loop.
// It looks suspicious.
- if ((_arrunkObj1337[tmpVal]._arr3[0]._field34 == 0) && (subC32B1(tmpVal, _arrunkObj1337[1]._arr1[i]._field34))) {
+ if ((_gameBoardSide[tmpVal]._delayPile[0]._cardId == 0) && (subC32B1(tmpVal, _gameBoardSide[1]._handCard[i]._cardId))) {
count = tmpVal;
break;
}
@@ -5474,22 +6080,19 @@ void Scene1337::subCF31D() {
}
}
- if (found) {
- if (count == -1)
- return;
-
- subC3456(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[count]._arr3[0]);
- } else {
+ if (found)
+ subC3456(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[count]._delayPile[0]);
+ else {
int j;
for (j = 0; j <= 3; j++) {
- if (subC27F9(_arrunkObj1337[1]._arr1[j]._field34) != -1) {
+ if (subC27F9(_gameBoardSide[1]._handCard[j]._cardId) != -1) {
count = -1;
int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
for (int l = 0; l <= 3; l++) {
if (rndVal != 1) {
for (int m = 0; m <= 7; m++) {
// 'm' is not used in that loop. It looks suspicious.
- if ((_arrunkObj1337[rndVal]._arr3[0]._field34 == 0) && (_arrunkObj1337[1]._arr1[j]._field34 == 1)) {
+ if ((_gameBoardSide[rndVal]._delayPile[0]._cardId == 0) && (_gameBoardSide[1]._handCard[j]._cardId == 1)) {
count = rndVal;
break;
}
@@ -5509,14 +6112,10 @@ void Scene1337::subCF31D() {
}
}
- if (found) {
- if (count == -1)
- return;
-
- subC3456(&_arrunkObj1337[1]._arr1[j], &_arrunkObj1337[count]._arr3[0]);
- } else {
+ if (found)
+ subC3456(&_gameBoardSide[1]._handCard[j], &_gameBoardSide[count]._delayPile[0]);
+ else
subC2835(1);
- }
}
}
@@ -5524,8 +6123,8 @@ void Scene1337::subCF31D() {
void Scene1337::subCF979() {
bool found = true;
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[0]._arr3[0]._field34) {
+ if (_gameBoardSide[0]._delayPile[0]._cardId != 0) {
+ switch (_gameBoardSide[0]._delayPile[0]._cardId) {
case 10:
//No break on purpose
case 12:
@@ -5541,7 +6140,7 @@ void Scene1337::subCF979() {
case 20:
//No break on purpose
case 21:
- subC4A39(&_arrunkObj1337[0]._arr3[0]);
+ subC4A39(&_gameBoardSide[0]._delayPile[0]);
found = false;
break;
default:
@@ -5549,7 +6148,7 @@ void Scene1337::subCF979() {
found = false;
for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[0]._arr3[0]._field34, _arrunkObj1337[0]._arr1[i]._field34)) {
+ if (subC3386(_gameBoardSide[0]._delayPile[0]._cardId, _gameBoardSide[0]._handCard[i]._cardId)) {
found = true;
break;
}
@@ -5557,7 +6156,7 @@ void Scene1337::subCF979() {
if (found) {
found = false;
- subC34A1(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[0]._arr3[0]);
+ subC34A1(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[0]._delayPile[0]);
}
break;
}
@@ -5574,7 +6173,7 @@ void Scene1337::subCF979() {
if (tmpVal != -1) {
bool flag = false;
for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[0]._arr2[j]._field34 == _arrunkObj1337[0]._arr1[tmpVal]._field34) {
+ if (_gameBoardSide[0]._outpostStation[j]._cardId == _gameBoardSide[0]._handCard[tmpVal]._cardId) {
flag = true;
break;
}
@@ -5582,10 +6181,10 @@ void Scene1337::subCF979() {
if (!flag) {
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[0]._arr2[j]._field34 == 1) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
+ if ((_gameBoardSide[0]._outpostStation[j]._cardId == 1) && (!subC2687(_gameBoardSide[0]._delayPile[0]._cardId))) {
int count = 0;
for (int k = 0; k <= 7; k++) {
- if ((_arrunkObj1337[0]._arr2[k]._field34 > 1) && (_arrunkObj1337[0]._arr2[k]._field34 <= 9)) {
+ if ((_gameBoardSide[0]._outpostStation[k]._cardId > 1) && (_gameBoardSide[0]._outpostStation[k]._cardId <= 9)) {
++count;
}
}
@@ -5593,7 +6192,7 @@ void Scene1337::subCF979() {
if (count == 7)
_field424A = 0;
- subC33C0(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[j]);
+ subC33C0(&_gameBoardSide[0]._handCard[tmpVal], &_gameBoardSide[0]._outpostStation[j]);
found = true;
}
}
@@ -5612,8 +6211,8 @@ void Scene1337::subCF979() {
if (tmpVal != -1) {
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[0]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[i]);
+ if ((_gameBoardSide[0]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[0]._delayPile[0]._cardId))) {
+ subC340B(&_gameBoardSide[0]._handCard[tmpVal], &_gameBoardSide[0]._outpostStation[i]);
found = true;
break;
}
@@ -5626,8 +6225,8 @@ void Scene1337::subCF979() {
tmpVal = subC274D(0);
if (tmpVal != -1) {
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[2]._arr2[i]._field34 != 0) {
- subC358E(&_arrunkObj1337[0]._arr1[tmpVal], 2);
+ if (_gameBoardSide[2]._outpostStation[i]._cardId != 0) {
+ subC358E(&_gameBoardSide[0]._handCard[tmpVal], 2);
found = true;
break;
}
@@ -5639,11 +6238,11 @@ void Scene1337::subCF979() {
tmpVal = subC2781(0);
if (tmpVal != -1) {
- if ( (_arrunkObj1337[2]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[3]._field34 != 0) ) {
- subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 2);
+ if ( (_gameBoardSide[2]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[3]._cardId != 0) ) {
+ subC318B(0, &_gameBoardSide[0]._handCard[tmpVal], 2);
found = true;
}
}
@@ -5652,11 +6251,11 @@ void Scene1337::subCF979() {
return;
for (int i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
+ if (subC27B5(_gameBoardSide[0]._handCard[i]._cardId) != -1) {
// The variable 'j' is not used in the inner code of the loop. It's suspect
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
+ if ((_gameBoardSide[2]._delayPile[0]._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayPile[0]);
found = true;
break;
}
@@ -5671,11 +6270,11 @@ void Scene1337::subCF979() {
return;
for (int i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
+ if (subC27F9(_gameBoardSide[0]._handCard[i]._cardId) != -1) {
// The variable 'j' is not used in the inner code of the loop. It's suspect
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
+ if ((_gameBoardSide[2]._delayPile[0]._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayPile[0]);
found = true;
}
}
@@ -5692,7 +6291,7 @@ void Scene1337::subCF979() {
int tmpVal2 = subC331B(0);
if ((tmpVal != -1) && (tmpVal2 != -1)) {
- subC358E(&_arrunkObj1337[0]._arr1[tmpVal], tmpVal2);
+ subC358E(&_gameBoardSide[0]._handCard[tmpVal], tmpVal2);
found = true;
}
@@ -5701,11 +6300,11 @@ void Scene1337::subCF979() {
tmpVal = subC2781(0);
if (tmpVal != -1) {
- if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
- subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 1);
+ if ( (_gameBoardSide[1]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[3]._cardId != 0) ) {
+ subC318B(0, &_gameBoardSide[0]._handCard[tmpVal], 1);
found = true;
}
}
@@ -5714,12 +6313,12 @@ void Scene1337::subCF979() {
return;
for (int i = 0; i <= 3; i++) {
- tmpVal = subC27F9(_arrunkObj1337[0]._arr1[i]._field34);
+ tmpVal = subC27F9(_gameBoardSide[0]._handCard[i]._cardId);
if (tmpVal != -1) {
// The variable 'j' is not used in the inner code of the loop. It's suspect.
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ if ((_gameBoardSide[1]._delayPile[0]._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayPile[0]);
found = true;
}
}
@@ -5727,8 +6326,8 @@ void Scene1337::subCF979() {
if (!found) {
// The variable 'j' is not used in the inner code of the loop. It's suspect.
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ if ((_gameBoardSide[3]._delayPile[0]._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayPile[0]);
found = true;
}
}
@@ -5743,12 +6342,12 @@ void Scene1337::subCF979() {
return;
for (int i = 0; i <= 3; i++) {
- tmpVal = subC27B5(_arrunkObj1337[0]._arr1[i]._field34);
+ tmpVal = subC27B5(_gameBoardSide[0]._handCard[i]._cardId);
if (tmpVal != -1) {
// The variable 'j' is not used in the inner code of the loop. It's suspect.
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
+ if ((_gameBoardSide[1]._delayPile[0]._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayPile[0]);
found = true;
}
}
@@ -5756,8 +6355,8 @@ void Scene1337::subCF979() {
if (!found) {
// The variable 'j' is not used in the inner code of the loop. It's suspect.
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
+ if ((_gameBoardSide[3]._delayPile[0]._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) {
+ subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayPile[0]);
found = true;
}
}
@@ -5779,83 +6378,83 @@ void Scene1337::subD026D() {
}
void Scene1337::subD0281() {
- if (subC27F9(this->_arrunkObj1337[2]._arr3[0]._field34) == -1)
+ if (subC27F9(this->_gameBoardSide[2]._delayPile[0]._cardId) == -1)
_unkFctPtr412 = &Scene1337::subD026D;
else
- subC4A39(&_arrunkObj1337[2]._arr3[0]);
+ subC4A39(&_gameBoardSide[2]._delayPile[0]);
}
void Scene1337::subD02CA() {
- _item6._field36 = g_globals->_events._mousePos;
+ _item6._stationPos = g_globals->_events._mousePos;
if (R2_GLOBALS._v57810 == 200) {
int di;
for (di = 0; di < 4; di++) {
- if ((subC2BF8(&_arrunkObj1337[2]._arr1[di], _item6._field36) != 0) && (_arrunkObj1337[2]._arr1[di]._field34 != 0)) {
- _item6._field34 = _arrunkObj1337[2]._arr1[di]._field34;
- _item6._field36 = _arrunkObj1337[2]._arr1[di]._field36;
+ if ((subC2BF8(&_gameBoardSide[2]._handCard[di], _item6._stationPos) != 0) && (_gameBoardSide[2]._handCard[di]._cardId != 0)) {
+ _item6._cardId = _gameBoardSide[2]._handCard[di]._cardId;
+ _item6._stationPos = _gameBoardSide[2]._handCard[di]._stationPos;
// _item6._actorName = _arrunkObj1337[2]._arr1[di]._actorName;
- _item6._fieldE = _arrunkObj1337[2]._arr1[di]._fieldE;
- _item6._field10 = _arrunkObj1337[2]._arr1[di]._field10;
+ _item6._fieldE = _gameBoardSide[2]._handCard[di]._fieldE;
+ _item6._field10 = _gameBoardSide[2]._handCard[di]._field10;
warning("_item6._field12 = _arrunkObj1337[2]._arr1[di]._field12;");
warning("_item6._field14 = _arrunkObj1337[2]._arr1[di]._field14;");
warning("_item6._field16 = _arrunkObj1337[2]._arr1[di]._field16;");
- _item6._sceneRegionId = _arrunkObj1337[2]._arr1[di]._sceneRegionId;
- _item6._position = _arrunkObj1337[2]._arr1[di]._position;
- _item6._yDiff = _arrunkObj1337[2]._arr1[di]._yDiff;
- _item6._bounds = _arrunkObj1337[2]._arr1[di]._bounds;
- _item6._resNum = _arrunkObj1337[2]._arr1[di]._resNum;
- _item6._lookLineNum = _arrunkObj1337[2]._arr1[di]._lookLineNum;
- _item6._talkLineNum = _arrunkObj1337[2]._arr1[di]._talkLineNum;
- _item6._useLineNum = _arrunkObj1337[2]._arr1[di]._useLineNum;
- _item6._action = _arrunkObj1337[2]._arr1[di]._action;
+ _item6._sceneRegionId = _gameBoardSide[2]._handCard[di]._sceneRegionId;
+ _item6._position = _gameBoardSide[2]._handCard[di]._position;
+ _item6._yDiff = _gameBoardSide[2]._handCard[di]._yDiff;
+ _item6._bounds = _gameBoardSide[2]._handCard[di]._bounds;
+ _item6._resNum = _gameBoardSide[2]._handCard[di]._resNum;
+ _item6._lookLineNum = _gameBoardSide[2]._handCard[di]._lookLineNum;
+ _item6._talkLineNum = _gameBoardSide[2]._handCard[di]._talkLineNum;
+ _item6._useLineNum = _gameBoardSide[2]._handCard[di]._useLineNum;
+ _item6._action = _gameBoardSide[2]._handCard[di]._action;
warning("_item6._field0 = _arrunkObj1337[2]._arr1[di]._field0;");
- _item6._object1._updateStartFrame = _arrunkObj1337[2]._arr1[di]._object1._updateStartFrame;
- _item6._object1._walkStartFrame = _arrunkObj1337[2]._arr1[di]._object1._walkStartFrame;
+ _item6._card._updateStartFrame = _gameBoardSide[2]._handCard[di]._card._updateStartFrame;
+ _item6._card._walkStartFrame = _gameBoardSide[2]._handCard[di]._card._walkStartFrame;
// _field2E is named _field3C in R2R
- _item6._object1._field2E = _arrunkObj1337[2]._arr1[di]._object1._field2E;
- _item6._object1._percent = _arrunkObj1337[2]._arr1[di]._object1._percent;
- _item6._object1._priority = _arrunkObj1337[2]._arr1[di]._object1._priority;
- _item6._object1._angle = _arrunkObj1337[2]._arr1[di]._object1._angle;
- _item6._object1._flags = _arrunkObj1337[2]._arr1[di]._object1._flags;
- _item6._object1._xe = _arrunkObj1337[2]._arr1[di]._object1._xe;
- _item6._object1._xs = _arrunkObj1337[2]._arr1[di]._object1._xs;
- _item6._object1._paneRects[0] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[0];
- _item6._object1._paneRects[1] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[1];
- _item6._object1._visage = _arrunkObj1337[2]._arr1[di]._object1._visage;
- _item6._object1._objectWrapper = _arrunkObj1337[2]._arr1[di]._object1._objectWrapper;
- _item6._object1._strip = _arrunkObj1337[2]._arr1[di]._object1._strip;
- _item6._object1._animateMode = _arrunkObj1337[2]._arr1[di]._object1._animateMode;
- _item6._object1._frame = _arrunkObj1337[2]._arr1[di]._object1._frame;
- _item6._object1._endFrame = _arrunkObj1337[2]._arr1[di]._object1._endFrame;
+ _item6._card._field2E = _gameBoardSide[2]._handCard[di]._card._field2E;
+ _item6._card._percent = _gameBoardSide[2]._handCard[di]._card._percent;
+ _item6._card._priority = _gameBoardSide[2]._handCard[di]._card._priority;
+ _item6._card._angle = _gameBoardSide[2]._handCard[di]._card._angle;
+ _item6._card._flags = _gameBoardSide[2]._handCard[di]._card._flags;
+ _item6._card._xe = _gameBoardSide[2]._handCard[di]._card._xe;
+ _item6._card._xs = _gameBoardSide[2]._handCard[di]._card._xs;
+ _item6._card._paneRects[0] = _gameBoardSide[2]._handCard[di]._card._paneRects[0];
+ _item6._card._paneRects[1] = _gameBoardSide[2]._handCard[di]._card._paneRects[1];
+ _item6._card._visage = _gameBoardSide[2]._handCard[di]._card._visage;
+ _item6._card._objectWrapper = _gameBoardSide[2]._handCard[di]._card._objectWrapper;
+ _item6._card._strip = _gameBoardSide[2]._handCard[di]._card._strip;
+ _item6._card._animateMode = _gameBoardSide[2]._handCard[di]._card._animateMode;
+ _item6._card._frame = _gameBoardSide[2]._handCard[di]._card._frame;
+ _item6._card._endFrame = _gameBoardSide[2]._handCard[di]._card._endFrame;
// _field68 is named _field76 in R2R
- _item6._object1._field68 = _arrunkObj1337[2]._arr1[di]._object1._field68;
- _item6._object1._frameChange = _arrunkObj1337[2]._arr1[di]._object1._frameChange;
- _item6._object1._numFrames = _arrunkObj1337[2]._arr1[di]._object1._numFrames;
- _item6._object1._regionIndex = _arrunkObj1337[2]._arr1[di]._object1._regionIndex;
- _item6._object1._mover = _arrunkObj1337[2]._arr1[di]._object1._mover;
- _item6._object1._moveDiff = _arrunkObj1337[2]._arr1[di]._object1._moveDiff;
- _item6._object1._moveRate = _arrunkObj1337[2]._arr1[di]._object1._moveRate;
- _item6._object1._field8A = _arrunkObj1337[2]._arr1[di]._object1._field8A;
- _item6._object1._endAction = _arrunkObj1337[2]._arr1[di]._object1._endAction;
- _item6._object1._regionBitList = _arrunkObj1337[2]._arr1[di]._object1._regionBitList;
+ _item6._card._field68 = _gameBoardSide[2]._handCard[di]._card._field68;
+ _item6._card._frameChange = _gameBoardSide[2]._handCard[di]._card._frameChange;
+ _item6._card._numFrames = _gameBoardSide[2]._handCard[di]._card._numFrames;
+ _item6._card._regionIndex = _gameBoardSide[2]._handCard[di]._card._regionIndex;
+ _item6._card._mover = _gameBoardSide[2]._handCard[di]._card._mover;
+ _item6._card._moveDiff = _gameBoardSide[2]._handCard[di]._card._moveDiff;
+ _item6._card._moveRate = _gameBoardSide[2]._handCard[di]._card._moveRate;
+ _item6._card._actorDestPos = _gameBoardSide[2]._handCard[di]._card._actorDestPos;
+ _item6._card._endAction = _gameBoardSide[2]._handCard[di]._card._endAction;
+ _item6._card._regionBitList = _gameBoardSide[2]._handCard[di]._card._regionBitList;
// _item6._object1._actorName = _arrunkObj1337[2]._arr1[di]._object1._actorName;
- _item6._object1._fieldE = _arrunkObj1337[2]._arr1[di]._object1._fieldE;
- _item6._object1._field10 = _arrunkObj1337[2]._arr1[di]._object1._field10;
+ _item6._card._fieldE = _gameBoardSide[2]._handCard[di]._card._fieldE;
+ _item6._card._field10 = _gameBoardSide[2]._handCard[di]._card._field10;
warning("_item6._object1._field12 = _arrunkObj1337[2]._arr1[di]._object1._field12;");
warning("_item6._object1._field14 = _arrunkObj1337[2]._arr1[di]._object1._field14;");
warning("_item6._object1._field16 = _arrunkObj1337[2]._arr1[di]._object1._field16;");
- _item6._object1 = _arrunkObj1337[2]._arr1[di]._object1;
+ _item6._card = _gameBoardSide[2]._handCard[di]._card;
}
}
if (di == 4) {
- subCDB90(1, _item6._field36);
+ subCDB90(1, _item6._stationPos);
subD0281();
return;
}
} else if (R2_GLOBALS._v57810 == 300) {
- subCDB90(3, _item6._field36);
+ subCDB90(3, _item6._stationPos);
subD0281();
return;
} else {
@@ -5865,7 +6464,7 @@ void Scene1337::subD02CA() {
}
// That continues the block when R2_GLOBALS._v57810 == 200 and di != 4
- subD18B5(1332, _item6._object1._strip, _item6._object1._frame);
+ setCursorData(1332, _item6._card._strip, _item6._card._frame);
R2_GLOBALS._sceneObjects->draw();
Event event;
bool found = false;
@@ -5873,23 +6472,23 @@ void Scene1337::subD02CA() {
for (;;) {
if ( ((g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN)) && (event.btnState == BTNSHIFT_RIGHT))
|| (g_globals->_events.getEvent(event, EVENT_KEYPRESS)) ){
- _item6._field36 = g_globals->_events._mousePos;
+ _item6._stationPos = g_globals->_events._mousePos;
found_di = false;
for (int i = 0; i <= 3; i ++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr1[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[2]._arr1[i]._field34 == 0) {
- _arrunkObj1337[2]._arr1[i]._field34 = _item6._field34;
- _arrunkObj1337[2]._arr1[i]._object1.postInit();
- _arrunkObj1337[2]._arr1[i]._object1.hide();
- _arrunkObj1337[2]._arr1[i]._object1.setVisage(1332);
- _arrunkObj1337[2]._arr1[i]._object1.setPosition(_arrunkObj1337[2]._arr1[i]._field36, 0);
- _arrunkObj1337[2]._arr1[i]._object1.fixPriority(170);
- setAnimationInfo(&_arrunkObj1337[2]._arr1[i]);
- subD18B5(5, 1, 4);
+ if (subC2BF8(&_gameBoardSide[2]._handCard[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if (_gameBoardSide[2]._handCard[i]._cardId == 0) {
+ _gameBoardSide[2]._handCard[i]._cardId = _item6._cardId;
+ _gameBoardSide[2]._handCard[i]._card.postInit();
+ _gameBoardSide[2]._handCard[i]._card.hide();
+ _gameBoardSide[2]._handCard[i]._card.setVisage(1332);
+ _gameBoardSide[2]._handCard[i]._card.setPosition(_gameBoardSide[2]._handCard[i]._stationPos, 0);
+ _gameBoardSide[2]._handCard[i]._card.fixPriority(170);
+ setAnimationInfo(&_gameBoardSide[2]._handCard[i]);
+ setCursorData(5, 1, 4);
found = true;
- _field423E--;
- _field4244 = 0;
+ _currentPlayerNumb--;
+ _field4244 = false;
subC20F9();
} else {
actionDisplay(1330, 127, 159, 10, 1, 200, 0, 7, 0, 154, 154);
@@ -5900,68 +6499,68 @@ void Scene1337::subD02CA() {
}
if ((!found) && (!found_di)) {
- if (subC2BF8(&_item7, Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (subC2BF8(&_discardPile, Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
subC4A39(&_item6);
} else if (!found) {
bool foundVar4;
int i;
- if (_item6._field34 == 1) {
+ if (_item6._cardId == 1) {
foundVar4 = false;
for (i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
foundVar4 = true;
break;
}
}
- if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 0)) {
- if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
+ if ((foundVar4) && (_gameBoardSide[2]._outpostStation[i]._cardId == 0)) {
+ if (subC27B5(_gameBoardSide[2]._delayPile[0]._cardId) != -1) {
actionDisplay(1330, 55, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
- subC340B(&_item6, &_arrunkObj1337[2]._arr2[i]);
+ subC340B(&_item6, &_gameBoardSide[2]._outpostStation[i]);
return;
}
} else {
actionDisplay(1330, 56, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
- } else if (_item6._field34 <= 9) {
+ } else if (_item6._cardId <= 9) {
foundVar4 = false;
for (i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
foundVar4 = true;
break;
}
}
- if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 1)) {
+ if ((foundVar4) && (_gameBoardSide[2]._outpostStation[i]._cardId == 1)) {
foundVar4 = false;
int j;
for (j = 0; j <= 7; j++) {
- if (_item6._field34 == _arrunkObj1337[2]._arr2[j]._field34) {
+ if (_item6._cardId == _gameBoardSide[2]._outpostStation[j]._cardId) {
foundVar4 = true;
break;
}
}
if (foundVar4) {
actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
+ } else if (subC27B5(_gameBoardSide[2]._delayPile[0]._cardId) != -1) {
actionDisplay(1330, 35, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
if (j == 7)
_field424A = 2;
- subC33C0(&_item6, &_arrunkObj1337[2]._arr2[i]);
+ subC33C0(&_item6, &_gameBoardSide[2]._outpostStation[i]);
return;
}
} else {
actionDisplay(1330, 37, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
} else {
- if ((_item6._field34 == 26) || (_item6._field34 == 30) ||(_item6._field34 == 32) || (_item6._field34 == 28)) {
- if (subC2BF8(&_arrunkObj1337[2]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if ((_item6._cardId == 26) || (_item6._cardId == 30) ||(_item6._cardId == 32) || (_item6._cardId == 28)) {
+ if (subC2BF8(&_gameBoardSide[2]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
actionDisplay(1330, 42, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC3386(_arrunkObj1337[2]._arr3[0]._field34, _item6._field34)) {
- if (_arrunkObj1337[2]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[2]._arr3[0]._field34) {
+ } else if (!subC3386(_gameBoardSide[2]._delayPile[0]._cardId, _item6._cardId)) {
+ if (_gameBoardSide[2]._delayPile[0]._cardId != 0) {
+ switch (_gameBoardSide[2]._delayPile[0]._cardId) {
case 11:
actionDisplay(1330, 68, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5981,15 +6580,15 @@ void Scene1337::subD02CA() {
actionDisplay(1330, 41, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
} else {
- subC34A1(&_item6, &_arrunkObj1337[2]._arr3[0]);
+ subC34A1(&_item6, &_gameBoardSide[2]._delayPile[0]);
return;
}
} else {
- if ((subC27F9(_item6._field34) == -1) && (subC27B5(_item6._field34) == -1)) {
- if (_item6._field34 == 13) {
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ if ((subC27F9(_item6._cardId) == -1) && (subC27B5(_item6._cardId) == -1)) {
+ if (_item6._cardId == 13) {
+ if (subC2BF8(&_gameBoardSide[0]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[0]._arr2[k]._field34 != 0) {
+ if (_gameBoardSide[0]._outpostStation[k]._cardId != 0) {
found = true;
subC358E(&_item6, 0);
}
@@ -5997,18 +6596,18 @@ void Scene1337::subD02CA() {
if (!found)
actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ } else if (subC2BF8(&_gameBoardSide[3]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[3]._arr2[k]._field34 != 0) {
+ if (_gameBoardSide[3]._outpostStation[k]._cardId != 0) {
found = true;
subC358E(&_item6, 3);
}
}
if (!found)
actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
+ } else if (subC2BF8(&_gameBoardSide[1]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[1]._arr2[k]._field34 == 0) {
+ if (_gameBoardSide[1]._outpostStation[k]._cardId == 0) {
found = true;
subC358E(&_item6, 1);
}
@@ -6018,48 +6617,48 @@ void Scene1337::subD02CA() {
} else {
actionDisplay(1330, 128, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
- } else if (_item6._field34 == 25) {
+ } else if (_item6._cardId == 25) {
int k;
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[0]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[3]._field34 != 0) ) {
+ if (subC2BF8(&_gameBoardSide[0]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if ( (_gameBoardSide[0]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[3]._cardId != 0) ) {
for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
}
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 0);
+ subC318B(2, &_gameBoardSide[2]._handCard[k], 0);
return;
} else {
actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
- } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
+ } else if (subC2BF8(&_gameBoardSide[1]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if ( (_gameBoardSide[1]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[3]._cardId != 0) ) {
for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
}
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 1);
+ subC318B(2, &_gameBoardSide[2]._handCard[k], 1);
return;
} else {
actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
}
- if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[3]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[3]._field34 != 0) ) {
+ if (subC2BF8(&_gameBoardSide[3]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if ( (_gameBoardSide[3]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[3]._cardId != 0) ) {
for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
}
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 3);
+ subC318B(2, &_gameBoardSide[2]._handCard[k], 3);
return;
} else {
actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
@@ -6067,17 +6666,17 @@ void Scene1337::subD02CA() {
} else {
actionDisplay(1330, 129, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
- } else if (_item6._field34 == 29) {
+ } else if (_item6._cardId == 29) {
actionDisplay(1330, 136, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (_item6._field34 == 27) {
+ } else if (_item6._cardId == 27) {
actionDisplay(1330, 137, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
} else {
- if (subC2BF8(&_arrunkObj1337[0]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ if (subC2BF8(&_gameBoardSide[0]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if (_gameBoardSide[0]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(0, _item6._field34)) {
- switch (_item6._field34) {
+ } else if (!subC32B1(0, _item6._cardId)) {
+ switch (_item6._cardId) {
case 10:
actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -6106,14 +6705,14 @@ void Scene1337::subD02CA() {
break;
}
} else {
- subC3456(&_item6, &_arrunkObj1337[0]._arr3[0]);
+ subC3456(&_item6, &_gameBoardSide[0]._delayPile[0]);
found = true;
}
- } else if (subC2BF8(&_arrunkObj1337[3]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ } else if (subC2BF8(&_gameBoardSide[3]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if (_gameBoardSide[3]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(3, _item6._field34)) {
- switch (_item6._field34) {
+ } else if (!subC32B1(3, _item6._cardId)) {
+ switch (_item6._cardId) {
case 10:
actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -6142,14 +6741,14 @@ void Scene1337::subD02CA() {
break;
}
} else {
- subC3456(&_item6, &_arrunkObj1337[3]._arr3[0]);
+ subC3456(&_item6, &_gameBoardSide[3]._delayPile[0]);
found = true;
}
- } else if (subC2BF8(&_arrunkObj1337[1]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ } else if (subC2BF8(&_gameBoardSide[1]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) {
+ if (_gameBoardSide[1]._delayPile[0]._cardId != 0) {
actionDisplay(1330, 19, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(1, _item6._field34)) {
- switch (_item6._field34) {
+ } else if (!subC32B1(1, _item6._cardId)) {
+ switch (_item6._cardId) {
case 10:
actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -6178,7 +6777,7 @@ void Scene1337::subD02CA() {
break;
}
} else {
- subC3456(&_item6, &_arrunkObj1337[1]._arr3[0]);
+ subC3456(&_item6, &_gameBoardSide[1]._delayPile[0]);
found = true;
}
} else {
@@ -6226,42 +6825,48 @@ void Scene1337::subD183F(int arg1, int arg2) {
}
}
-void Scene1337::subD18B5(int resNum, int rlbNum, int arg3) {
- warning("STUBBED lvl3 Scene1337::subD18B5()");
+void Scene1337::setCursorData(int resNum, int rlbNum, int frameNum) {
+ // Change the mouse cursor and set it to the desired frame (if different than 0)
+ if (!frameNum)
+ return;
+
+ uint size;
+ byte *cursor = g_resourceManager->getSubResource(resNum, rlbNum, frameNum, &size);
+ // Decode the cursor
+ GfxSurface s = surfaceFromRes(cursor);
+
+ Graphics::Surface surface = s.lockSurface();
+ const byte *cursorData = (const byte *)surface.getPixels();
+ CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
+ s.unlockSurface();
}
-int Scene1337::subD18F5() {
+void Scene1337::subD18F5() {
if (R2_GLOBALS._v57709 == 0)
// The cursor looks... very dummy
// To be checked
warning("TODO: CursorManager.setData(R2_GLOBALS.off_57705)");
++R2_GLOBALS._v57709;
-
- return R2_GLOBALS._v57709;
}
-int Scene1337::subD1917() {
+void Scene1337::subD1917() {
if (R2_GLOBALS._v57709 != 0) {
R2_GLOBALS._v57709--;
if (R2_GLOBALS._v57709 != 0)
warning("FIXME: subD195F(_width, _data);");
}
-
- return R2_GLOBALS._v57709;
}
-int Scene1337::subD1940(bool flag) {
+void Scene1337::subD1940(bool flag) {
if (flag)
++R2_GLOBALS._v5780C;
else if (R2_GLOBALS._v5780C != 0)
--R2_GLOBALS._v5780C;
-
- return R2_GLOBALS._v5780C;
}
void Scene1337::subD195F(int arg1, int arg2) {
- subD18B5(5, arg1, arg2);
+ setCursorData(5, arg1, arg2);
}
void Scene1337::subD1975(int arg1, int arg2) {
@@ -6293,62 +6898,63 @@ void Scene1337::subD1A48(int arg1) {
* Scene 1500 - Cutscene: Ship landing
*
*--------------------------------------------------------------------------*/
+
void Scene1500::postInit(SceneObjectList *OwnerList) {
loadScene(1500);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.top = 0;
- R2_GLOBALS._v5589E.bottom = 200;
setZoomPercents(170, 13, 240, 100);
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
scalePalette(65, 65, 65);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor2.postInit();
- _actor2.setup(1401, 1, 1);
- _actor2._effect = 5;
- _actor2.fixPriority(10);
- _actor2._field9C = _field312;
+ _starshipShadow.postInit();
+ _starshipShadow.setup(1401, 1, 1);
+ _starshipShadow._effect = EFFECT_SHADOW_MAP;
+ _starshipShadow.fixPriority(10);
+ _starshipShadow._shadowMap = _shadowPaletteMap;
- _actor1.postInit();
- _actor1.setup(1400, 1, 1);
- _actor1._moveDiff = Common::Point(1, 1);
- _actor1._linkedActor = &_actor2;
+ _starship.postInit();
+ _starship.setup(1400, 1, 1);
+ _starship._moveDiff = Common::Point(1, 1);
+ _starship._linkedActor = &_starshipShadow;
if (R2_GLOBALS._sceneManager._previousScene != 1010) {
- _actor4.postInit();
- _actor4.setup(1401, 2, 1);
- _actor4._effect = 5;
- _actor4.fixPriority(10);
- _actor4._field9C = _field312;
+ _smallShipShadow.postInit();
+ _smallShipShadow.setup(1401, 2, 1);
+ _smallShipShadow._effect = EFFECT_SHADOW_MAP;
+ _smallShipShadow.fixPriority(10);
+ _smallShipShadow._shadowMap = _shadowPaletteMap;
- _actor3.postInit();
- _actor3._moveRate = 30;
- _actor3._moveDiff = Common::Point(1, 1);
- _actor3._linkedActor = &_actor4;
+ _smallShip.postInit();
+ _smallShip._moveRate = 30;
+ _smallShip._moveDiff = Common::Point(1, 1);
+ _smallShip._linkedActor = &_smallShipShadow;
}
if (R2_GLOBALS._sceneManager._previousScene == 300) {
- _actor1.setPosition(Common::Point(189, 139), 5);
+ _starship.setPosition(Common::Point(189, 139), 5);
- _actor3.setup(1400, 1, 2);
- _actor3.setPosition(Common::Point(148, 108), 0);
+ _smallShip.setup(1400, 1, 2);
+ _smallShip.setPosition(Common::Point(148, 108), 0);
_sceneMode = 20;
R2_GLOBALS._sound1.play(110);
} else if (R2_GLOBALS._sceneManager._previousScene == 1550) {
- _actor1.setPosition(Common::Point(189, 139), 5);
+ _starship.setPosition(Common::Point(189, 139), 5);
- _actor3.setup(1400, 2, 1);
- _actor3.changeZoom(-1);
- _actor3.setPosition(Common::Point(298, 258), 5);
+ _smallShip.setup(1400, 2, 1);
+ _smallShip.changeZoom(-1);
+ _smallShip.setPosition(Common::Point(298, 258), 5);
_sceneMode = 10;
R2_GLOBALS._sound1.play(106);
} else {
- _actor1.setPosition(Common::Point(289, 239), -30);
+ _starship.setPosition(Common::Point(289, 239), -30);
_sceneMode = 0;
R2_GLOBALS._sound1.play(102);
}
@@ -6356,9 +6962,8 @@ void Scene1500::postInit(SceneObjectList *OwnerList) {
}
void Scene1500::remove() {
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements._visible = true;
SceneExt::remove();
}
@@ -6370,8 +6975,8 @@ void Scene1500::signal() {
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
// No break on purpose
case 1:
- if (_actor1._yDiff < 50) {
- _actor1.setPosition(Common::Point(289, 239), _actor1._yDiff + 1);
+ if (_starship._yDiff < 50) {
+ _starship.setPosition(Common::Point(289, 239), _starship._yDiff + 1);
_sceneMode = 1;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -6379,12 +6984,12 @@ void Scene1500::signal() {
case 2: {
Common::Point pt(189, 139);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _starship.addMover(mover, &pt, this);
}
break;
case 3:
- if (_actor1._yDiff > 5) {
- _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff - 1);
+ if (_starship._yDiff > 5) {
+ _starship.setPosition(Common::Point(189, 139), _starship._yDiff - 1);
_sceneMode = 3;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -6403,7 +7008,7 @@ void Scene1500::signal() {
case 11: {
Common::Point pt(148, 108);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, this);
+ _smallShip.addMover(mover, &pt, this);
}
break;
case 12:
@@ -6412,13 +7017,13 @@ void Scene1500::signal() {
case 21: {
Common::Point pt(-2, -42);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, NULL);
+ _smallShip.addMover(mover, &pt, NULL);
signal();
}
break;
case 22:
- if (_actor1._yDiff < 50) {
- _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff + 1);
+ if (_starship._yDiff < 50) {
+ _starship.setPosition(Common::Point(189, 139), _starship._yDiff + 1);
_sceneMode = 22;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -6426,11 +7031,11 @@ void Scene1500::signal() {
case 23: {
Common::Point pt(-13, -61);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _starship.addMover(mover, &pt, this);
}
break;
case 24:
- R2_GLOBALS._sceneManager.changeScene(300);
+ R2_GLOBALS._sceneManager.changeScene(1550);
break;
default:
break;
@@ -6439,9 +7044,9 @@ void Scene1500::signal() {
void Scene1500::dispatch() {
if (_sceneMode > 10) {
- float yDiff = sqrt((float) (_actor3._position.x * _actor3._position.x) + (_actor3._position.y * _actor3._position.y));
+ float yDiff = sqrt((float) (_smallShip._position.x * _smallShip._position.x) + (_smallShip._position.y * _smallShip._position.y));
if (yDiff > 6)
- _actor3.setPosition(_actor3._position, (int) yDiff);
+ _smallShip.setPosition(_smallShip._position, (int) yDiff);
}
Scene::dispatch();
@@ -6451,6 +7056,7 @@ void Scene1500::dispatch() {
* Scene 1525 - Cutscene - Ship
*
*--------------------------------------------------------------------------*/
+
void Scene1525::postInit(SceneObjectList *OwnerList) {
loadScene(1525);
R2_GLOBALS._uiElements._active = false;
@@ -6490,9 +7096,10 @@ void Scene1525::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1530 - Cutscene - Elevator
+ * Scene 1530 - Cutscene - Crashing on Rimwall
*
*--------------------------------------------------------------------------*/
+
void Scene1530::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 1000)
loadScene(1650);
@@ -6503,6 +7110,7 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
@@ -6526,15 +7134,15 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveRate = 30;
R2_GLOBALS._player._moveDiff = Common::Point(4, 1);
- _actor2.postInit();
- _actor2.setup(1516, 7, 1);
- _actor2.setPosition(Common::Point(121, 41));
- _actor2.animate(ANIM_MODE_2, NULL);
+ _leftReactor.postInit();
+ _leftReactor.setup(1516, 7, 1);
+ _leftReactor.setPosition(Common::Point(121, 41));
+ _leftReactor.animate(ANIM_MODE_2, NULL);
- _actor3.postInit();
- _actor3.setup(1516, 8, 1);
- _actor3.setPosition(Common::Point(107, 116));
- _actor3.animate(ANIM_MODE_2, NULL);
+ _rightReactor.postInit();
+ _rightReactor.setup(1516, 8, 1);
+ _rightReactor.setPosition(Common::Point(107, 116));
+ _rightReactor.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.disableControl();
Common::Point pt(480, 75);
@@ -6544,14 +7152,14 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
_sceneMode = 1;
} else {
- _actor1.postInit();
- _actor1._effect = 1;
+ _seeker.postInit();
+ _seeker._effect = EFFECT_SHADED;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_seeker, NULL);
_sceneMode = 2;
}
@@ -6584,28 +7192,28 @@ void Scene1530::dispatch() {
int16 x = R2_GLOBALS._player._position.x;
int16 y = R2_GLOBALS._player._position.y;
- _actor2.setPosition(Common::Point(x - 39, y - 85));
- _actor3.setPosition(Common::Point(x - 53, y - 9));
+ _leftReactor.setPosition(Common::Point(x - 39, y - 85));
+ _rightReactor.setPosition(Common::Point(x - 53, y - 9));
Scene::dispatch();
}
/*--------------------------------------------------------------------------
- * Scene 1550 -
+ * Scene 1550 - Spaceport
*
*--------------------------------------------------------------------------*/
-Scene1550::UnkObj15501::UnkObj15501() {
- _fieldA4 = _fieldA6 = 0;
+
+Scene1550::Junk::Junk() {
+ _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) {
@@ -6624,13 +7232,13 @@ bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
if (_visage == 1561) {
switch (_frame) {
case 2:
- SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 3:
- SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 4:
- SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
break;
@@ -6638,13 +7246,13 @@ bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
} else {
switch ((((_strip - 1) * 5) + _frame) % 3) {
case 0:
- SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 1:
- SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 2:
- SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
break;
@@ -6658,131 +7266,131 @@ 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) {
- scene->_field412 = 1;
+ if (_componentId == 8) {
+ scene->_dontExit = true;
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)
- SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ if (_componentId == 8)
+ SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else if (_frame == 1)
- SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else
- SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case R2_FUEL_CELL:
- scene->_field412 = 1;
- if (_fieldA4 == 6) {
+ scene->_dontExit = true;
+ if (_componentId == 6) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_wreckage2.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1574;
else
scene->_sceneMode = 1582;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GYROSCOPE:
- scene->_field412 = 1;
- if (_fieldA4 == 3) {
+ scene->_dontExit = true;
+ if (_componentId == 3) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_wreckage2.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1571;
else
scene->_sceneMode = 1581;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GUIDANCE_MODULE:
- scene->_field412 = 1;
- if (_fieldA4 == 1) {
+ scene->_dontExit = true;
+ if (_componentId == 1) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_wreckage2.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1569;
else
scene->_sceneMode = 1579;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_THRUSTER_VALVE:
- scene->_field412 = 1;
- if (_fieldA4 == 4) {
+ scene->_dontExit = true;
+ 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->_wreckage2.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_RADAR_MECHANISM:
- scene->_field412 = 1;
- if (_fieldA4 == 2) {
+ scene->_dontExit = true;
+ if (_componentId == 2) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_wreckage2.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1570;
else
scene->_sceneMode = 1580;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_IGNITOR:
- scene->_field412 = 1;
- if (_fieldA4 == 5) {
+ scene->_dontExit = true;
+ 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->_wreckage2.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_BATTERY:
- scene->_field412 = 1;
- if (_fieldA4 == 7) {
+ scene->_dontExit = true;
+ if (_componentId == 7) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_wreckage2.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1575;
else
scene->_sceneMode = 1583;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
@@ -6793,47 +7401,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;
@@ -6846,47 +7455,53 @@ void Scene1550::UnkObj15502::subA5CDF(int strip) {
default:
break;
}
+
+ fixPriority(92);
+ setDetails(1550, 70, -1, -1, 2, (SceneItem *)NULL);
}
-Scene1550::UnkObj15503::UnkObj15503() {
- _fieldA4 = 0;
+Scene1550::DishControlsWindow::DishControl::DishControl() {
+ _controlId = 0;
}
-void Scene1550::UnkObj15503::synchronize(Serializer &s) {
+void Scene1550::DishControlsWindow::DishControl::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_controlId);
}
-bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
- Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1550::DishControlsWindow::DishControl::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- switch (_fieldA4) {
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_controlId) {
case 1:
- if (scene->_actor13._frame == 5) {
+ // Button control
+ if (scene->_dish._frame == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 25;
- if (scene->_actor4._frame == 1) {
- scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_actor4, NULL);
+ if (scene->_walkway._frame == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_walkway, NULL);
R2_GLOBALS.setFlag(20);
setFrame(2);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_walkway, NULL);
R2_GLOBALS.clearFlag(20);
setFrame(1);
}
- scene->_unkArea1.remove();
+ scene->_dishControlsWindow.remove();
}
break;
case 2:
+ // Lever control
R2_GLOBALS._player.disableControl();
- if (scene->_actor13._frame == 1) {
+ if (scene->_dish._frame == 1) {
scene->_sceneMode = 23;
scene->setAction(&scene->_sequenceManager1, scene, 1560, this, NULL);
} else {
- if (scene->_actor4._frame == 1)
+ if (scene->_walkway._frame == 1)
scene->_sceneMode = 24;
else
scene->_sceneMode = 22;
@@ -6899,22 +7514,19 @@ bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1550::UnkArea1550::remove() {
+void Scene1550::DishControlsWindow::remove() {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- _unkObj155031.remove();
- _unkObj155032.remove();
- // sub201EA is a common part with UnkArea1200
- R2_GLOBALS._sceneItems.remove((SceneItem *)this);
- _areaActor.remove();
- SceneArea::remove();
- R2_GLOBALS._insetUp--;
- //
+ _button.remove();
+ _lever.remove();
+
+ ModalWindow::remove();
+
if ((scene->_sceneMode >= 20) && (scene->_sceneMode <= 29))
return;
R2_GLOBALS._player.disableControl();
- if (scene->_actor4._frame == 1) {
+ if (scene->_walkway._frame == 1) {
scene->_sceneMode = 1559;
scene->setAction(&scene->_sequenceManager1, scene, 1559, &R2_GLOBALS._player, NULL);
} else {
@@ -6923,95 +7535,45 @@ void Scene1550::UnkArea1550::remove() {
}
}
-void Scene1550::UnkArea1550::process(Event &event) {
-// This is a copy of Scene1200::Area1::process
- if (_field20 != R2_GLOBALS._insetUp)
- return;
-
- CursorType cursor = R2_GLOBALS._events.getCursor();
-
- if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
- if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
- }
- } 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);
- remove();
- }
- }
-}
+void Scene1550::DishControlsWindow::setup2(int visage, int stripFrameNum, int frameNum,
+ int posX, int posY) {
+ // Call inherited setup
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
-void Scene1550::UnkArea1550::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
- // UnkArea1200::proc12();
+ // Further setup
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
-
- _areaActor.postInit();
- _areaActor.setup(visage, stripFrameNum, frameNum);
- _areaActor.setPosition(Common::Point(posX, posY));
- _areaActor.fixPriority(250);
- _cursorNum = CURSOR_INVALID;
- scene->_sceneAreas.push_front(this);
- ++R2_GLOBALS._insetUp;
- _field20 = R2_GLOBALS._insetUp;
- //
-
- proc13(1550, 67, -1, -1);
- _unkObj155031.postInit();
- _unkObj155031._fieldA4 = 1;
- if (scene->_actor4._frame == 1)
- _unkObj155031.setup(1559, 3, 1);
+ setup3(1550, 67, -1, -1);
+ _button.postInit();
+ _button._controlId = 1;
+ if (scene->_walkway._frame == 1)
+ _button.setup(1559, 3, 1);
else
- _unkObj155031.setup(1559, 3, 2);
- _unkObj155031.setPosition(Common::Point(142, 79));
- _unkObj155031.fixPriority(251);
- _unkObj155031.setDetails(1550, 68, -1, -1, 2, (SceneItem *) NULL);
-
- _unkObj155032.postInit();
- _unkObj155032._numFrames = 5;
- _unkObj155032._fieldA4 = 2;
- if (scene->_actor13._frame == 1)
- _unkObj155032.setup(1559, 2, 1);
+ _button.setup(1559, 3, 2);
+ _button.setPosition(Common::Point(142, 79));
+ _button.fixPriority(251);
+ _button.setDetails(1550, 68, -1, -1, 2, (SceneItem *) NULL);
+
+ _lever.postInit();
+ _lever._numFrames = 5;
+ _lever._controlId = 2;
+ if (scene->_dish._frame == 1)
+ _lever.setup(1559, 2, 1);
else
- _unkObj155032.setup(1559, 2, 2);
- _unkObj155032.setPosition(Common::Point(156, 103));
- _unkObj155032.fixPriority(251);
- _unkObj155032.setDetails(1550, 69, -1, -1, 2, (SceneItem *) NULL);
+ _lever.setup(1559, 2, 2);
+ _lever.setPosition(Common::Point(156, 103));
+ _lever.fixPriority(251);
+ _lever.setDetails(1550, 69, -1, -1, 2, (SceneItem *) NULL);
}
-void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- // Copy of Scene1200::Area1::proc13
- _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
-}
-
-bool Scene1550::Hotspot1::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));
- // 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]);
-
+bool Scene1550::WorkingShip::startAction(CursorType action, Event &event) {
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);
@@ -7022,23 +7584,23 @@ bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1550::AirBag::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
R2_GLOBALS._player.disableControl();
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_dontExit = true;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1552;
else
scene->_sceneMode = 1588;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_airbag, NULL);
return true;
}
-bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
+bool Scene1550::Joystick::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -7046,14 +7608,14 @@ 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);
return true;
break;
case CURSOR_LOOK:
- SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
@@ -7061,53 +7623,55 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
}
}
-bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
+bool Scene1550::Gyroscope::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
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;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor10, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_gyroscope, NULL);
return true;
}
-bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
+bool Scene1550::DiagnosticsDisplay::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_dontExit = true;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1586;
else
scene->_sceneMode = 1587;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor11, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_diagnosticsDisplay, NULL);
return true;
}
-bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
+bool Scene1550::DishTower::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
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);
} else {
R2_GLOBALS._player.disableControl();
- switch(scene->_field415) {
+ switch(scene->_dishMode) {
case 0:
- scene->_actor13.fixPriority(168);
- scene->_actor4.fixPriority(125);
+ scene->_dish.fixPriority(168);
+ scene->_walkway.fixPriority(125);
scene->_sceneMode = 1558;
scene->setAction(&scene->_sequenceManager1, scene, 1558, &R2_GLOBALS._player, NULL);
break;
@@ -7115,9 +7679,9 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
break;
case 2:
- scene->_field415 = 1;
+ scene->_dishMode = 1;
scene->_sceneMode = 1563;
- scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_walkway, NULL);
break;
default:
break;
@@ -7127,12 +7691,12 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
}
-bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
+bool Scene1550::Dish::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (scene->_field415 != 2)
+ if (scene->_dishMode != 2)
return SceneActor::startAction(action, event);
if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
@@ -7140,17 +7704,17 @@ bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1564;
scene->setAction(&scene->_sequenceManager1, scene, 1564, &R2_GLOBALS._player, NULL);
} else
- SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case CURSOR_LOOK:
- if (scene->_field415 != 2)
+ if (scene->_dishMode != 2)
return SceneActor::startAction(action, event);
if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
- SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
} else
- SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
@@ -7159,42 +7723,47 @@ bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
}
}
+/*--------------------------------------------------------------------------*/
+
Scene1550::Scene1550() {
- _field412 = 0;
- _field414 = 0;
- _field415 = 0;
- _field417 = 0;
- _field419 = 0;
+ _dontExit = false;
+ _wallType = 0;
+ _dishMode = 0;
+ _sceneResourceId = 0;
+ _walkRegionsId = 0;
}
void Scene1550::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsByte(_field414);
- s.syncAsSint16LE(_field415);
- s.syncAsSint16LE(_field417);
- s.syncAsSint16LE(_field419);
+ s.syncAsSint16LE(_dontExit);
+ s.syncAsByte(_wallType);
+ s.syncAsSint16LE(_dishMode);
+ s.syncAsSint16LE(_sceneResourceId);
+ s.syncAsSint16LE(_walkRegionsId);
}
void Scene1550::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._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();
+ _sceneResourceId = 1550;
+ _walkRegionsId = 0;
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;
- R2_GLOBALS._player._characterScene[2] = 1550;
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] != 1550) && (R2_GLOBALS._player._characterScene[R2_QUINN] != 1580)) {
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1550;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1550;
}
_stripManager.setColors(60, 255);
@@ -7203,16 +7772,17 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
- if (R2_GLOBALS._player._characterIndex == 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));
@@ -7220,13 +7790,13 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _field414 = 0;
- _actor7.changeZoom(-1);
+ _wallType = 0;
+ _companion.changeZoom(-1);
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._sceneManager._previousScene) {
case 1530:
- R2_GLOBALS._v565AE = 0;
+ R2_GLOBALS._stripModifier = 0;
// No break on purpose
case 300:
// No break on purpose
@@ -7236,21 +7806,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;
+ _dontExit = true;
- _actor1.postInit();
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[7].hide();
- if (R2_GLOBALS._player._characterIndex == 1)
+ _wreckage2.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, &_wreckage2, &_shipComponents[7], NULL);
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
} else {
R2_GLOBALS._player.enableControl();
@@ -7260,29 +7831,29 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
break;
}
- subA2B2F();
+ enterArea();
- _item1.setDetails(16, 1550, 10, -1, -1);
- _item2.setDetails(24, 1550, 10, -1, -1);
- _item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
+ _intactHull1.setDetails(16, 1550, 10, -1, -1);
+ _intactHull2.setDetails(24, 1550, 10, -1, -1);
+ _background.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
_sceneMode = 70;
- 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]);
+ assert(_walkRegionsId >= 1550);
+ R2_GLOBALS._walkRegions.disableRegion(k5A750[_walkRegionsId - 1550]);
- setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1590, &_companion, NULL);
} else if ((_sceneMode != 1577) && (_sceneMode != 1578))
R2_GLOBALS._player.enableControl();
}
@@ -7296,9 +7867,8 @@ void Scene1550::signal() {
case 5:
// No break on purpose
case 7:
- _field412 = 0;
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _dontExit = false;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 20:
// No break on purpose
@@ -7307,27 +7877,28 @@ void Scene1550::signal() {
case 25:
// No break on purpose
case 1563:
+ // Show the communication dish controls window
R2_GLOBALS.clearFlag(20);
- _unkArea1.proc12(1559, 1, 1, 160, 125);
+ _dishControlsWindow.setup2(1559, 1, 1, 160, 125);
R2_GLOBALS._player.enableControl();
_sceneMode = 0;
break;
case 22:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 24;
- setAction(&_sequenceManager1, this, 1561, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1561, &_walkway, NULL);
R2_GLOBALS.clearFlag(20);
break;
case 23:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 20;
- setAction(&_sequenceManager1, this, 1566, &_actor13, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1566, &_dish, &_dishTowerShadow, NULL);
R2_GLOBALS.setFlag(21);
break;
case 24:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 21;
- setAction(&_sequenceManager1, this, 1567, &_actor13, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1567, &_dish, &_dishTowerShadow, NULL);
R2_GLOBALS.clearFlag(19);
break;
case 30:
@@ -7339,14 +7910,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);
@@ -7354,37 +7925,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.enableRegion(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);
@@ -7395,49 +7971,50 @@ void Scene1550::signal() {
R2_GLOBALS._player.enableControl();
break;
case 50:
- warning("STUB: sub_1D227()");
+ // Removed (useless ?) call to sub_1D227
++_sceneMode;
setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
- if (g_globals->_sceneObjects->contains(&_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], &_joystick, NULL);
else
- setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion,
+ &_junk[0], &_joystick, NULL);
break;
case 61:
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _field415 = 2;
+ _dishMode = 2;
break;
case 62:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
- if (_field415 == 2) {
+ if (_dishMode == 2) {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
}
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);
@@ -7447,33 +8024,33 @@ void Scene1550::signal() {
_sceneMode = 60;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._stripModifier >= 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
- ++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
- _stripManager.start(499 + R2_GLOBALS._v565AE, this);
+ ++R2_GLOBALS._stripModifier;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _stripManager.start(499 + R2_GLOBALS._stripModifier, this);
else
- _stripManager.start(502 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(502 + R2_GLOBALS._stripModifier, this);
}
} else {
_sceneMode = 60;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._v565AE >= 4) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._stripModifier >= 4) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
- ++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
- _stripManager.start(563 + R2_GLOBALS._v565AE, this);
+ ++R2_GLOBALS._stripModifier;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _stripManager.start(563 + R2_GLOBALS._stripModifier, this);
else
- _stripManager.start(567 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(567 + R2_GLOBALS._stripModifier, this);
}
}
break;
@@ -7484,8 +8061,8 @@ void Scene1550::signal() {
// No break on purpose
case 1588:
R2_INVENTORY.setObjectScene(R2_AIRBAG, R2_GLOBALS._player._characterIndex);
- _actor8.remove();
- _field412 = 0;
+ _airbag.remove();
+ _dontExit = false;
R2_GLOBALS._player.enableControl();
break;
case 1553:
@@ -7493,33 +8070,33 @@ void Scene1550::signal() {
break;
case 1554:
R2_GLOBALS._player.enableControl();
- _field412 = 0;
+ _dontExit = false;
break;
case 1555:
// No break on purpose
case 1589:
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, R2_GLOBALS._player._characterIndex);
- _actor10.remove();
+ _gyroscope.remove();
R2_GLOBALS._player.enableControl();
break;
case 1558:
- _actor13.fixPriority(124);
- _field415 = 1;
- _unkArea1.proc12(1559, 1, 1, 160, 125);
+ _dish.fixPriority(124);
+ _dishMode = 1;
+ _dishControlsWindow.setup2(1559, 1, 1, 160, 125);
R2_GLOBALS._player.enableControl();
break;
case 1559:
- _actor13.fixPriority(168);
- _actor4.fixPriority(169);
+ _dish.fixPriority(168);
+ _walkway.fixPriority(169);
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.changeZoom(-1);
- _field415 = 0;
+ _dishMode = 0;
R2_GLOBALS._player.enableControl();
break;
case 1562:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field415 = 2;
+ _dishMode = 2;
break;
case 1564:
R2_INVENTORY.setObjectScene(R2_BATTERY, 1);
@@ -7533,52 +8110,52 @@ void Scene1550::signal() {
case 1569:
// No break on purpose
case 1579:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1570:
// No break on purpose
case 1580:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
R2_GLOBALS._player.enableControl();
break;
case 1571:
// No break on purpose
case 1581:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1572:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1573:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
R2_GLOBALS._player.enableControl();
break;
case 1574:
// No break on purpose
case 1582:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
R2_GLOBALS._player.enableControl();
break;
case 1575:
// No break on purpose
case 1583:
- _field412 = 0;
- _actor1.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -7592,34 +8169,32 @@ void Scene1550::signal() {
// No break on purpose
case 1578:
_sceneMode = 0;
- _actor1.remove();
- _field412 = 0;
+ _wreckage2.remove();
+ _dontExit = false;
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.enableControl();
break;
case 1585:
- SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
R2_GLOBALS._player.enableControl();
break;
case 1586:
// No break on purpose
case 1587:
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
- _actor1.remove();
- _field412 = 0;
+ _diagnosticsDisplay.remove();
+ _dontExit = false;
R2_GLOBALS._player.enableControl();
break;
case 1592:
- _actor9.remove();
+ _joystick.remove();
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
- if (R2_GLOBALS._player._characterIndex == 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();
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
_sceneMode = 62;
@@ -7632,14 +8207,14 @@ void Scene1550::process(Event &event) {
if ((!R2_GLOBALS._player._canWalk) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) && (event.eventType == EVENT_BUTTON_DOWN) && (this->_screenNumber == 1234)) {
int curReg = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
if (curReg == 0)
- _field412 = 1;
+ _dontExit = true;
else if (((R2_GLOBALS._player._position.y < 90) && (event.mousePos.y > 90)) || ((R2_GLOBALS._player._position.y > 90) && (event.mousePos.y < 90)))
- _field412 = 1;
+ _dontExit = true;
else
- _field412 = 0;
+ _dontExit = false;
if ((curReg == 13) || (curReg == 14))
- _field412 = 0;
+ _dontExit = false;
}
Scene::process(event);
@@ -7649,24 +8224,27 @@ 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.
- // Until we understand what should really happen there, this code is unused on purpose
+
+ // NOTE: Original game contains a switch based on an uninitialized variable.
+ // We're leaving this code here, but ifdef'ed out, in case we can ever figure out
+ // what the original programmers intended the value to come from
+#if 0
int missingVariable = 0;
switch (missingVariable) {
case 144:
// No break on purpose
case 146:
- _actor13._frame = 5;
+ _dish._frame = 5;
R2_GLOBALS._player._shade = 3;
break;
case 148:
// No break on purpose
case 149:
- _actor13._frame = 1;
+ _dish._frame = 1;
// No break on purpose
case 147:
// No break on purpose
@@ -7676,21 +8254,23 @@ void Scene1550::dispatch() {
default:
break;
}
+#endif
}
- if (_field412 != 0)
+ if (_dontExit)
return;
switch (R2_GLOBALS._player.getRegionIndex() - 11) {
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];
+ _dontExit = true;
+ --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) {
@@ -7708,12 +8288,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];
+ _dontExit = true;
+ ++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) {
@@ -7731,14 +8312,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];
+ _dontExit = true;
+ ++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);
@@ -7758,16 +8340,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)) {
+ _dontExit = true;
+ --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);
@@ -7792,17 +8378,17 @@ 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);
}
-void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
+void Scene1550::Wall::setupWall(int frameNumber, int strip) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
postInit();
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1551, strip, frameNumber);
else
setup(1554, strip, frameNumber);
@@ -7913,7 +8499,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
switch (frameNumber) {
case 2:
fixPriority(2);
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1553, 2, 1);
else
setup(1556, 2, 1);
@@ -7938,7 +8524,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
case 4:
if (frameNumber == 2) {
fixPriority(250);
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1553, 1, 1);
else
setup(1556, 1, 1);
@@ -7982,54 +8568,52 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
}
-void Scene1550::subA2B2F() {
- Rect tmpRect;
- _field419 = 0;
- _field415 = 0;
-
- tmpRect = R2_GLOBALS._v5589E;
+void Scene1550::enterArea() {
+ _walkRegionsId = 0;
+ _dishMode = 0;
- _actor14.remove();
- _actor17.remove();
- _actor15.remove();
- _actor19.remove();
- _actor16.remove();
- _actor18.remove();
+ _wallCorner1.remove();
+ _westWall.remove();
+ _northWall.remove();
+ _southWall.remove();
+ _wallCorner2.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();
- _actor10.remove();
- _actor3.remove();
- _actor11.remove();
+ _airbag.remove();
+ _joystick.remove();
+ _gyroscope.remove();
+ _wreckage4.remove();
+ _diagnosticsDisplay.remove();
if ((_sceneMode != 1577) && (_sceneMode != 1578))
- _actor1.remove();
+ _wreckage2.remove();
- _actor2.remove();
- _actor7.remove();
- _actor13.remove();
- _actor5.remove();
- _actor12.remove();
- _actor4.remove();
+ _wreckage3.remove();
+ _companion.remove();
+ _dish.remove();
+ _dishTowerShadow.remove();
+ _dishTower.remove();
+ _walkway.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;
+ _walkRegionsId = 1554;
break;
case 4:
R2_GLOBALS._walkRegions.load(1553);
- _field419 = 1553;
+ _walkRegionsId = 1553;
break;
default:
break;
@@ -8038,54 +8622,54 @@ 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;
+ _walkRegionsId = 1559;
}
}
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;
+ _walkRegionsId = 1555;
break;
case 11:
R2_GLOBALS._walkRegions.load(1556);
- _field419 = 1556;
+ _walkRegionsId = 1556;
break;
default:
break;
}
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;
+ _walkRegionsId = 1558;
break;
case 25:
R2_GLOBALS._walkRegions.load(1557);
- _field419 = 1557;
+ _walkRegionsId = 1557;
break;
default:
break;
}
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;
+ _walkRegionsId = 1552;
break;
case 3:
R2_GLOBALS._walkRegions.load(1551);
- _field419 = 1551;
+ _walkRegionsId = 1551;
break;
case 15:
R2_GLOBALS._walkRegions.load(1575);
- _field419 = 1575;
+ _walkRegionsId = 1575;
default:
break;
}
@@ -8096,13 +8680,15 @@ void Scene1550::subA2B2F() {
int varA = 0;
+ // This section handles checks if the ARM spacecraft have not yet seized
+ // control of Lance of Truth.
if (!R2_GLOBALS.getFlag(16)) {
- switch (R2_GLOBALS._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.setupWall(6, 0);
break;
case 1:
// No break on purpose
@@ -8115,7 +8701,7 @@ void Scene1550::subA2B2F() {
break;
case 5:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.setupWall(6, 0);
break;
default:
break;
@@ -8124,14 +8710,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.setupWall(9, 0);
break;
case 1:
varA = 1552;
- _actor15.subA4D14(10, 0);
+ _northWall.setupWall(10, 0);
break;
case 2:
// No break on purpose
@@ -8144,25 +8730,25 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1552;
- _actor15.subA4D14(7, 0);
+ _northWall.setupWall(7, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(8, 0);
+ _northWall.setupWall(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.setupWall(4, 0);
break;
case 1:
varA = 1550;
- _actor15.subA4D14(3, 0);
+ _northWall.setupWall(3, 0);
break;
case 2:
// No break on purpose
@@ -8175,11 +8761,11 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1550;
- _actor15.subA4D14(2, 0);
+ _northWall.setupWall(2, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(1, 0);
+ _northWall.setupWall(1, 0);
break;
default:
break;
@@ -8188,40 +8774,46 @@ 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))) {
+ // In an area where the cutscene can be triggered, so start it
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;
+ _wallType = 0;
}
} else {
- if (R2_GLOBALS._sceneManager._sceneNumber == 1234) {
+ if (_screenNumber == 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1550);
R2_GLOBALS._sceneManager._hasPalette = false;
}
}
- if (R2_GLOBALS._sceneManager._sceneNumber == 1234)
- _field419 = 1576;
+ if (_screenNumber == 1234)
+ _walkRegionsId = 1576;
- if (_field414 == 0) {
- _field414 = 1;
+ if (_wallType == 0) {
+ _wallType = 1;
} else {
- if (_field414 == 2) {
- _field414 = 3;
+ if (_wallType == 2) {
+ _wallType = 3;
} else {
- _field414 = 2;
+ _wallType = 2;
}
if (R2_GLOBALS._sceneManager._sceneNumber == 1550){
+#if 0
warning("Mouse_hideIfNeeded()");
warning("gfx_set_pane_p");
for (int i = 3; i != 168; ++i) {
@@ -8231,10 +8823,11 @@ void Scene1550::subA2B2F() {
}
warning("Missing sub2957D()");
warning("gfx_set_pane_p()");
+#endif
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
if (varA == 0) {
- if (_field417 != 1550) {
+ if (_sceneResourceId != 1550) {
g_globals->_scenePalette.loadPalette(1550);
R2_GLOBALS._sceneManager._hasPalette = true;
}
@@ -8244,137 +8837,142 @@ void Scene1550::subA2B2F() {
}
if (R2_GLOBALS._sceneManager._hasPalette)
- _field417 = varA;
+ _sceneResourceId = varA;
- warning("sub_2C429()");
+// warning("sub_2C429()");
}
}
- 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:
- if (_field419 == 0) {
+ // Standard cell
+ if (_walkRegionsId == 0) {
R2_GLOBALS._walkRegions.load(1550);
- _field419 = 1550;
+ _walkRegionsId = 1550;
}
break;
case 1:
- if (_field419 == 0) {
+ // North end of the spaceport
+ if (_walkRegionsId == 0) {
R2_GLOBALS._walkRegions.load(1560);
- _field419 = 1560;
+ _walkRegionsId = 1560;
}
- _actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
+ _wallCorner1.setupWall(2, 1);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
break;
case 2:
R2_GLOBALS._walkRegions.load(1561);
- _field419 = 1561;
- _actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
- _actor15.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
+ _walkRegionsId = 1561;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(2, 2);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
break;
case 3:
R2_GLOBALS._walkRegions.load(1562);
- _field419 = 1562;
- _actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _walkRegionsId = 1562;
+ _wallCorner1.setupWall(2, 1);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(2, 6);
break;
case 4:
R2_GLOBALS._walkRegions.load(1563);
- _field419 = 1563;
- _actor15.subA4D14(2, 3);
+ _walkRegionsId = 1563;
+ _northWall.setupWall(2, 3);
break;
case 5:
R2_GLOBALS._walkRegions.load(1564);
- _field419 = 1564;
- _actor19.subA4D14(2, 4);
+ _walkRegionsId = 1564;
+ _southWall.setupWall(2, 4);
break;
case 6:
R2_GLOBALS._walkRegions.load(1565);
- _field419 = 1565;
- _actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(3, 3);
+ _walkRegionsId = 1565;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _northWall.setupWall(3, 3);
break;
case 7:
R2_GLOBALS._walkRegions.load(1566);
- _field419 = 1566;
- _actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(2, 4);
+ _walkRegionsId = 1566;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _northWall.setupWall(2, 4);
break;
case 8:
R2_GLOBALS._walkRegions.load(1567);
- _field419 = 1567;
- _actor17.subA4D14(5, 2);
+ _walkRegionsId = 1567;
+ _westWall.setupWall(5, 2);
break;
case 9:
R2_GLOBALS._walkRegions.load(1568);
- _field419 = 1568;
- _actor17.subA4D14(4, 2);
+ _walkRegionsId = 1568;
+ _westWall.setupWall(4, 2);
break;
case 10:
R2_GLOBALS._walkRegions.load(1569);
- _field419 = 1569;
- _actor14.subA4D14(3, 1);
+ _walkRegionsId = 1569;
+ _wallCorner1.setupWall(3, 1);
break;
case 11:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
break;
case 12:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(1, 5);
+ _eastWall.setupWall(1, 6);
break;
case 13:
R2_GLOBALS._walkRegions.load(1572);
- _field419 = 1572;
- _actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor19.subA4D14(1, 4);
+ _walkRegionsId = 1572;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _southWall.setupWall(1, 4);
break;
case 14:
R2_GLOBALS._walkRegions.load(1573);
- _field419 = 1573;
- _actor19.subA4D14(1, 4);
- _actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _walkRegionsId = 1573;
+ _southWall.setupWall(1, 4);
+ _wallCorner2.setupWall(1, 5);
+ _eastWall.setupWall(1, 6);
break;
case 15:
+ // South wall
R2_GLOBALS._walkRegions.load(1574);
- _field419 = 1574;
- _actor19.subA4D14(1, 4);
+ _walkRegionsId = 1574;
+ _southWall.setupWall(1, 4);
break;
case 16:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(2, 2);
break;
case 17:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(2, 1);
- _actor17.subA4D14(3, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(3, 2);
break;
case 18:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(2, 6);
break;
case 19:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(2, 5);
- _actor18.subA4D14(3, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(3, 6);
break;
default:
break;
@@ -8382,278 +8980,284 @@ 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 = EFFECT_SHADED2;
+ _junk[di]._shade = 0;
+ //_junk[di]._junkState = tmpIdx;
+ _junk[di]._junkNumber = i;
+ _junk[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] == 41) {
+ _junk[di].changeZoom(-1);
+ _junk[di].setPosition(Common::Point(150, 70));
+ _junk[di].setup(1562, 1, 1);
+
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[2]);
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[3]);
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[6]);
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[7]);
+
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
- _actor9.postInit();
- _actor9.setup(1562, 3, 1);
- _actor9.setPosition(Common::Point(150, 70));
- _actor9.fixPriority(10);
- _actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
+ _joystick.postInit();
+ _joystick.setup(1562, 3, 1);
+ _joystick.setPosition(Common::Point(150, 70));
+ _joystick.fixPriority(10);
+ _joystick.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
}
} else {
- if (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(scene1550JunkX[tmpIdx], scene1550JunkY[tmpIdx]));
+ if (scene1550JunkRegions[tmpIdx] != 0)
+ R2_GLOBALS._walkRegions.disableRegion(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])) {
- tmpIdx = k5A79B[i + 2];
- switch (tmpIdx - 1) {
- case 0:
+ // Loop for detecting and setting up certain special areas within the map
+ for (int i = 0; i < 15 * 3; i += 3) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == scene1550SpecialAreas[i])
+ && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == scene1550SpecialAreas[i + 1])) {
+ int areaType = scene1550SpecialAreas[i + 2];
+ switch (areaType) {
+ case 1:
if (!R2_GLOBALS.getFlag(16)) {
- _actor1.postInit();
- if (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 3)
- _actor1.setup(1555, 2, 1);
+ _wreckage2.postInit();
+ if (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 3)
+ _wreckage2.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);
+ _wreckage2.setup(1555, 1, 1);
+ _wreckage2.setPosition(Common::Point(150, 100));
+ _wreckage2.fixPriority(92);
+ _wreckage2.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
}
break;
- case 1:
- _actor13.postInit();
- warning("_actor13._actorName = \"dish\";");
+ case 2:
+ _dish.postInit();
if (R2_GLOBALS.getFlag(19))
- _actor13.setup(1556, 3, 5);
+ _dish.setup(1556, 3, 5);
else
- _actor13.setup(1556, 3, 1);
- _actor13.changeZoom(95);
- _actor13.setPosition(Common::Point(165, 83));
- _actor13.fixPriority(168);
- _actor13.setDetails(1550, 17, -1, 19, 2, (SceneItem *) NULL);
-
- _actor12.postInit();
- _actor12.setup(1556, 4, 1);
- _actor12.setPosition(Common::Point(191, 123));
- _actor12.changeZoom(95);
- _actor12.setDetails(1550, 65, -1, 66, 2, (SceneItem *) NULL);
-
- _actor5.postInit();
- _actor5._numFrames = 5;
+ _dish.setup(1556, 3, 1);
+ _dish.changeZoom(95);
+ _dish.setPosition(Common::Point(165, 83));
+ _dish.fixPriority(168);
+ _dish.setDetails(1550, 17, -1, 19, 2, (SceneItem *) NULL);
+
+ _dishTower.postInit();
+ _dishTower.setup(1556, 4, 1);
+ _dishTower.setPosition(Common::Point(191, 123));
+ _dishTower.changeZoom(95);
+ _dishTower.setDetails(1550, 65, -1, 66, 2, (SceneItem *) NULL);
+
+ _dishTowerShadow.postInit();
+ _dishTowerShadow._numFrames = 5;
if (R2_GLOBALS.getFlag(19))
- _actor5.setup(1556, 8, 5);
+ _dishTowerShadow.setup(1556, 8, 5);
else
- _actor5.setup(1556, 8, 1);
+ _dishTowerShadow.setup(1556, 8, 1);
- _actor5.setPosition(Common::Point(156, 151));
- _actor5.fixPriority(10);
+ _dishTowerShadow.setPosition(Common::Point(156, 151));
+ _dishTowerShadow.fixPriority(10);
- _actor4.postInit();
+ _walkway.postInit();
if (R2_GLOBALS.getFlag(20))
- _actor4.setup(1558, 3, 10);
+ _walkway.setup(1558, 3, 10);
else
- _actor4.setup(1558, 3, 1);
+ _walkway.setup(1558, 3, 1);
- _actor4.setPosition(Common::Point(172, 48));
- _actor4.fixPriority(169);
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[15]);
+ _walkway.setPosition(Common::Point(172, 48));
+ _walkway.fixPriority(169);
+ R2_GLOBALS._walkRegions.disableRegion(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);
+ case 3:
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 1);
+ _wreckage.setPosition(Common::Point(259, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 1, 2);
+ _wreckage2.setPosition(Common::Point(259, 133));
+ _wreckage2.fixPriority(105);
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
- _actor10.postInit();
- _actor10.setup(1550, 7, 2);
- _actor10.setPosition(Common::Point(227, 30));
- _actor10.fixPriority(130);
- _actor10.setDetails(1550, 29, -1, 63, 2, (SceneItem *) NULL);
+ _gyroscope.postInit();
+ _gyroscope.setup(1550, 7, 2);
+ _gyroscope.setPosition(Common::Point(227, 30));
+ _gyroscope.fixPriority(130);
+ _gyroscope.setDetails(1550, 29, -1, 63, 2, (SceneItem *) NULL);
}
break;
- case 3:
- _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);
+ case 4:
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 4);
+ _wreckage.setPosition(Common::Point(76, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 1, 3);
+ _wreckage2.setPosition(Common::Point(76, 64));
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
- _actor11.postInit();
- _actor11.setup(1504, 4, 1);
- _actor11.setPosition(Common::Point(49, 35));
- _actor11.animate(ANIM_MODE_2, NULL);
- _actor11._numFrames = 4;
- _actor11.fixPriority(65);
- _actor11.setDetails(1550, 14, 15, 63, 2, (SceneItem *) NULL);
+ _diagnosticsDisplay.postInit();
+ _diagnosticsDisplay.setup(1504, 4, 1);
+ _diagnosticsDisplay.setPosition(Common::Point(49, 35));
+ _diagnosticsDisplay.animate(ANIM_MODE_2, NULL);
+ _diagnosticsDisplay._numFrames = 4;
+ _diagnosticsDisplay.fixPriority(65);
+ _diagnosticsDisplay.setDetails(1550, 14, 15, 63, 2, (SceneItem *) NULL);
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1550) {
- _actor8.postInit();
- _actor8.setup(1550, 7, 1);
- _actor8.setPosition(Common::Point(45, 44));
- _actor8.fixPriority(150);
- _actor8.setDetails(1550, 44, -1, 63, 2, (SceneItem *) NULL);
+ _airbag.postInit();
+ _airbag.setup(1550, 7, 1);
+ _airbag.setPosition(Common::Point(45, 44));
+ _airbag.fixPriority(150);
+ _airbag.setDetails(1550, 44, -1, 63, 2, (SceneItem *) NULL);
}
break;
- case 4:
- _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);
- 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, 4);
+ _wreckage.setPosition(Common::Point(243, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 2, 3);
+ _wreckage2.setPosition(Common::Point(243, 64));
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 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, 2, 1);
+ _wreckage.setPosition(Common::Point(60, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 2, 2);
+ _wreckage2.setPosition(Common::Point(60, 133));
+ _wreckage2.fixPriority(106);
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 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);
-
- _actor2.postInit();
- _actor2.setup(1550, 3, 4);
- _actor2.setPosition(Common::Point(64, 137));
- _actor2.fixPriority(115);
- _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3.setup(1550, 5, 1);
- _actor3.setPosition(Common::Point(60, 90));
- _actor3.fixPriority(45);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 3, 1);
+ _wreckage.setPosition(Common::Point(281, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
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);
-
- _actor2.postInit();
- _actor2.setup(1550, 4, 4);
- _actor2.setPosition(Common::Point(255, 137));
- _actor2.fixPriority(115);
- _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3.setup(1550, 6, 1);
- _actor3.setPosition(Common::Point(259, 90));
- _actor3.fixPriority(45);
+ _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);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 3, 3);
+ _wreckage2.setPosition(Common::Point(145, 88));
+ _wreckage2.fixPriority(55);
+ _wreckage2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage3.postInit();
+ _wreckage3.setup(1550, 3, 4);
+ _wreckage3.setPosition(Common::Point(64, 137));
+ _wreckage3.fixPriority(115);
+ _wreckage3.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage4.postInit();
+ _wreckage4.setup(1550, 5, 1);
+ _wreckage4.setPosition(Common::Point(60, 90));
+ _wreckage4.fixPriority(45);
break;
case 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, 2);
+ _wreckage.setPosition(Common::Point(262, 96));
+ _wreckage.fixPriority(70);
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 4, 3);
+ _wreckage2.setPosition(Common::Point(174, 88));
+ _wreckage2.fixPriority(55);
+ _wreckage2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage3.postInit();
+ _wreckage3.setup(1550, 4, 4);
+ _wreckage3.setPosition(Common::Point(255, 137));
+ _wreckage3.fixPriority(115);
+ _wreckage3.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage4.postInit();
+ _wreckage4.setup(1550, 6, 1);
+ _wreckage4.setPosition(Common::Point(259, 90));
+ _wreckage4.fixPriority(45);
+ break;
+ case 10:
+ _wreckage.postInit();
+ _wreckage.setup(1550, 4, 1);
+ _wreckage.setPosition(Common::Point(38, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ break;
+ case 12:
+ // 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);
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);
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 = EFFECT_SHADED2;
+ _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) {
- 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]);
+ assert((_walkRegionsId >= 1550) && (_walkRegionsId <= 2008));
+ R2_GLOBALS._walkRegions.disableRegion(k5A750[_walkRegionsId - 1550]);
+ _companion.setPosition(Common::Point(scene1550JunkX[k5A76D[_walkRegionsId - 1550]], scene1550JunkY[k5A76D[_walkRegionsId - 1550]] + 8));
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 1580) {
+ _companion.setup(1516, 3, 17);
+ _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]);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 1580) {
+ _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);
}
}
}
@@ -8661,177 +9265,206 @@ void Scene1550::subA2B2F() {
}
/*--------------------------------------------------------------------------
- * Scene 1575 -
+ * Scene 1575 - Spaceport - unused ship scene
*
*--------------------------------------------------------------------------*/
-Scene1575::Scene1575() {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = 0;
- _field41A = 0;
-}
-
-void Scene1575::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
-}
-Scene1575::Hotspot1::Hotspot1() {
- _field34 = 0;
- _field36 = 0;
+Scene1575::Button::Button() {
+ _buttonId = 0;
+ _pressed = false;
}
-void Scene1575::Hotspot1::synchronize(Serializer &s) {
+void Scene1575::Button::synchronize(Serializer &s) {
NamedHotspot::synchronize(s);
- s.syncAsSint16LE(_field34);
- s.syncAsSint16LE(_field36);
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_pressed);
}
-void Scene1575::Hotspot1::process(Event &event) {
- if ((event.eventType != EVENT_BUTTON_DOWN) || (R2_GLOBALS._events.getCursor() != R2_STEPPING_DISKS) || (!_bounds.contains(event.mousePos))) {
- if (_field36 == 0)
- return;
- if ((_field34 == 1) || (event.eventType == EVENT_BUTTON_UP) || (!_bounds.contains(event.mousePos))) {
- _field36 = 0;
- return;
- }
- }
- _field36 = 1;
+void Scene1575::Button::process(Event &event) {
Scene1575 *scene = (Scene1575 *)R2_GLOBALS._sceneManager._scene;
+ bool isInBounds = _bounds.contains(event.mousePos);
+ CursorType cursor = R2_GLOBALS._events.getCursor();
- event.handled = true;
- if (R2_GLOBALS.getFlag(18) && (_field34 > 1) && (_field34 < 6)) {
- warning("sub1A03B(\"Better not move the laser while it\'s firing!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
- return;
- }
- int di = scene->_actor1._position.x;
+ if ((event.eventType == EVENT_BUTTON_DOWN && cursor == CURSOR_USE && isInBounds) ||
+ (_pressed && _buttonId != 1 && event.eventType == EVENT_BUTTON_UP && isInBounds)) {
+ // Button pressed
+ _pressed = true;
+ Common::Point pos = scene->_actor1._position;
+ event.handled = true;
- switch (_field34 - 1) {
- case 0:
- if (R2_GLOBALS.getFlag(18)) {
- scene->_actor14.hide();
- scene->_actor15.hide();
- R2_GLOBALS.clearFlag(18);
- } else if ((scene->_actor12._position.x == 85) && (scene->_actor12._position.y == 123)) {
- scene->_actor14.show();
- scene->_actor15.show();
- R2_GLOBALS.setFlag(18);
+ if (!R2_GLOBALS.getFlag(18) || _buttonId <= 1 || _buttonId >= 6) {
+ switch (_buttonId) {
+ case 1:
+ if (R2_GLOBALS.getFlag(18)) {
+ scene->_actor14.hide();
+ scene->_actor15.hide();
+ R2_GLOBALS.clearFlag(18);
+ } else if ((scene->_actor12._position.x == 85) && (scene->_actor12._position.y == 123)) {
+ scene->_actor14.show();
+ scene->_actor15.show();
+ R2_GLOBALS.setFlag(18);
+ } else {
+ SceneItem::display("That's probably not a good thing, ya know!");
+ }
+ break;
+ case 2:
+ if (scene->_field41A < 780) {
+ if (pos.x > 54)
+ pos.x -= 65;
+ pos.x += 2;
+ scene->_field41A += 2;
+
+ for (int i = 0; i < 17; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x + 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x + 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x + 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ break;
+ case 3:
+ if (scene->_field41A > 0) {
+ if (pos.x < -8)
+ pos.x += 65;
+
+ pos.x -= 2;
+ scene->_field41A -= 2;
+ for (int i = 0; i < 17; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x - 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x - 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x - 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ break;
+ case 4: {
+ if (pos.y < 176) {
+ ++pos.y;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y + 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y + 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y + 1));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ }
+ break;
+ case 5: {
+ if (pos.y > 145) {
+ --pos.y;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y - 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y - 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y - 1));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ }
+ break;
+ case 6:
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ break;
+ default:
+ break;
+ }
+
+ int j = 0;
+ for (int i = 0; i < 17; i++) {
+ if (scene->_arrActor[i]._bounds.contains(85, 116))
+ j = i;
+ }
+
+ if (scene->_actor13._bounds.contains(85, 116))
+ j = 18;
+
+ if (scene->_actor12._bounds.contains(85, 116))
+ j = 19;
+
+ if (j)
+ scene->_actor11.show();
+ else
+ scene->_actor11.hide();
} else {
- warning("sub1A03B(\"That\'s probably not a good thing, ya know!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
+ SceneItem::display("Better not move the laser while it's firing!");
}
- break;
- case 1:
- if (scene->_field41A < 780) {
- if (di > 54)
- di -= 65;
- di += 2;
- scene->_field41A += 2;
+ } else {
+ _pressed = false;
+ }
+}
+
+bool Scene1575::Button::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ return SceneHotspot::startAction(action, event);
+}
- for (int i = 0; i < 17; i++)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x + 2, scene->_arrActor[i]._position.y));
+void Scene1575::Button::initButton(int buttonId) {
+ _buttonId = buttonId;
+ _pressed = false;
+ EventHandler::postInit();
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x + 2, scene->_actor13._position.y));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x + 2, scene->_actor12._position.y));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
+ switch (_buttonId) {
+ case 1:
+ setDetails(Rect(53, 165, 117, 190), -1, -1, -1, 2, 1, NULL);
break;
case 2:
- if (scene->_field41A > 0) {
- if (di < -8)
- di += 65;
-
- di -= 2;
- scene->_field41A -= 2;
- for (int i = 0; i < 178; i++)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x - 2, scene->_arrActor[i]._position.y));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x - 2, scene->_actor13._position.y));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x - 2, scene->_actor12._position.y));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
+ setDetails(Rect(151, 142, 189, 161), -1, -1, -1, 2, 1, NULL);
break;
- case 3: {
- int tmpPosY = scene->_actor1._position.y;
- if (tmpPosY < 176) {
- ++tmpPosY;
- for (int i = 0; i < 17; ++i)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y + 1));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y + 1));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y + 1));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
- }
+ case 3:
+ setDetails(Rect(225, 142, 263, 161), -1, -1, -1, 2, 1, NULL);
break;
- case 4: {
- int tmpPosY = scene->_actor1._position.y;
- if (tmpPosY > 145) {
- tmpPosY--;
- for (int i = 0; i < 17; ++i)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y - 1));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y - 1));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y - 1));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
- }
+ case 4:
+ setDetails(Rect(188, 122, 226, 140), -1, -1, -1, 2, 1, NULL);
break;
case 5:
- R2_GLOBALS._sceneManager.changeScene(1550);
+ setDetails(Rect(188, 162, 226, 180), -1, -1, -1, 2, 1, NULL);
+ break;
+ case 6:
+ setDetails(Rect(269, 169, 301, 185), -1, -1, -1, 2, 1, NULL);
break;
default:
break;
}
+}
- int j = 0;
- for (int i = 0; i < 17; i++) {
- if (scene->_arrActor[i]._bounds.contains(85, 116))
- j = i;
- }
-
- if (scene->_actor13._bounds.contains(85, 116))
- j = 18;
-
- if (scene->_actor12._bounds.contains(85, 116))
- j = 19;
+/*--------------------------------------------------------------------------*/
- if (j)
- scene->_actor11.show();
- else
- scene->_actor11.hide();
+Scene1575::Scene1575() {
+ _field412 = 0;
+ _field414 = 390;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
}
-bool Scene1575::Hotspot1::startAction(CursorType action, Event &event) {
- if (action == CURSOR_USE)
- return false;
- return SceneHotspot::startAction(action, event);
+void Scene1575::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
}
-void Scene1575::Hotspot1::subA910D(int indx) {
- warning("STUB: Scene1575:Hotspot1::subA910D(%d)", indx);
+double hypotenuse(double v1, double v2) {
+ return sqrt(v1 * v1 + v2 * v2);
}
void Scene1575::postInit(SceneObjectList *OwnerList) {
loadScene(1575);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E = Rect(0, 0, 320, 200);
SceneExt::postInit();
- _field414 = 390;
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_actor1.postInit();
_actor1.setup(1575, 1, 1);
@@ -8850,8 +9483,17 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
for (int i = 0; i < 17; i++) {
_arrActor[i].postInit();
- _arrActor[i].setup(1575, 2, k5A7F6[(3 * i) + 2]);
- warning("TODO: immense pile of floating operations");
+ _arrActor[i].setup(1575, 2, k5A7F6[3 * i + 2]);
+
+ double v1 = hypotenuse(2.0, 3 - k5A7F6[3 * i]);
+ v1 += hypotenuse(2.0, 3 - k5A7F6[3 * i + 1]);
+ int yp = (int)(sqrt(v1) * 75.0 / 17.0 - 161.0);
+
+ int angle = R2_GLOBALS._gfxManagerInstance.getAngle(
+ Common::Point(3, 16), Common::Point(k5A7F6[3 * i], k5A7F6[3 * i + 1]));
+ int xp = angle * 78 / 9 - 319;
+
+ _arrActor[i].setPosition(Common::Point(xp, yp));
_arrActor[i].fixPriority(6);
}
@@ -8883,12 +9525,13 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
_actor10.setup(1575, 3, 2);
_actor10.setPosition(Common::Point(287, 91));
- _item1.subA910D(1);
- _item1.subA910D(2);
- _item1.subA910D(3);
- _item1.subA910D(4);
- _item1.subA910D(5);
- _item1.subA910D(6);
+ // Initialize buttons
+ _button1.initButton(1);
+ _button2.initButton(2);
+ _button3.initButton(3);
+ _button4.initButton(4);
+ _button5.initButton(5);
+ _button6.initButton(6);
_actor11.postInit();
_actor11.setup(1575, 4, 2);
@@ -8916,6 +9559,7 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
_actor13.postInit();
_actor13.setup(1575, 2, 4);
+ // TODO
warning("TODO: another immense pile of floating operations");
_actor12.postInit();
@@ -8941,8 +9585,6 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
void Scene1575::remove() {
SceneExt::remove();
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
}
@@ -8954,7 +9596,6 @@ void Scene1575::process(Event &event) {
Scene::process(event);
g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
- warning("TODO: check Scene1575::process");
}
void Scene1575::dispatch() {
@@ -9044,26 +9685,24 @@ void Scene1575::dispatch() {
* Scene 1580 - Inside wreck
*
*--------------------------------------------------------------------------*/
+
Scene1580::Scene1580() {
- _field412 = 0;
}
void Scene1580::synchronize(Serializer &s) {
SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
}
-bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
- Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1580::JoystickPlug::startAction(CursorType action, Event &event) {
if (action == R2_JOYSTICK) {
- R2_INVENTORY.setObjectScene(26, 1580);
- R2_GLOBALS._sceneItems.remove(&scene->_item1);
- scene->_actor2.postInit();
- scene->_actor2.setup(1580, 1, 4);
- scene->_actor2.setPosition(Common::Point(159, 163));
- scene->_actor2.setDetails(1550, 78, -1, -1, 2, (SceneItem *) NULL);
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1580);
+ R2_GLOBALS._sceneItems.remove(&scene->_joystickPlug);
+ scene->_joystick.postInit();
+ scene->_joystick.setup(1580, 1, 4);
+ scene->_joystick.setPosition(Common::Point(159, 163));
+ scene->_joystick.setDetails(1550, 78, -1, -1, 2, (SceneItem *) NULL);
scene->_arrActor[5].remove();
@@ -9073,29 +9712,29 @@ bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
- Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1580::ScreenSlot::startAction(CursorType action, Event &event) {
if (action == R2_DIAGNOSTICS_DISPLAY) {
- R2_INVENTORY.setObjectScene(28, 1580);
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1580);
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._sceneItems.remove(&scene->_item2);
+ R2_GLOBALS._sceneItems.remove(&scene->_screenSlot);
- scene->_actor3.postInit();
- scene->_actor3.setup(1580, 1, 1);
- scene->_actor3.setPosition(Common::Point(124, 108));
- scene->_actor3.fixPriority(10);
+ scene->_screen.postInit();
+ scene->_screen.setup(1580, 1, 1);
+ scene->_screen.setPosition(Common::Point(124, 108));
+ scene->_screen.fixPriority(10);
- if (R2_INVENTORY.getObjectScene(26) == 1580)
- scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580)
+ scene->_screen.setDetails(1550, 14, -1, -1, 5, &scene->_joystick);
else
- scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
+ scene->_screen.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
- scene->_actor1.postInit();
- scene->_actor1.setup(1580, 3, 1);
- scene->_actor1.setPosition(Common::Point(124, 109));
- scene->_actor1.fixPriority(20);
- scene->_field412 = 1;
+ scene->_screenDisplay.postInit();
+ scene->_screenDisplay.setup(1580, 3, 1);
+ scene->_screenDisplay.setPosition(Common::Point(124, 109));
+ scene->_screenDisplay.fixPriority(20);
+ //scene->_field412 = 1;
scene->_sceneMode = 10;
scene->setAction(&scene->_sequenceManager, scene, 1, &R2_GLOBALS._player, NULL);
@@ -9105,16 +9744,16 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, 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)) {
+bool Scene1580::Joystick::startAction(CursorType action, Event &event) {
+ if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580)
+ && (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0) && (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0) && (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
+ && (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);
@@ -9125,13 +9764,13 @@ bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(51) == 1580)) {
+bool Scene1580::Screen::startAction(CursorType action, Event &event) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
- R2_INVENTORY.setObjectScene(51, R2_GLOBALS._player._characterIndex);
- scene->_item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
- scene->_actor1.remove();
+ R2_INVENTORY.setObjectScene(R2_BROKEN_DISPLAY, R2_GLOBALS._player._characterIndex);
+ scene->_screenSlot.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
+ scene->_screenDisplay.remove();
remove();
return true;
}
@@ -9139,21 +9778,21 @@ bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor4::startAction(CursorType action, Event &event) {
+bool Scene1580::StorageCompartment::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._sceneItems.remove(&scene->_actor4);
+ R2_GLOBALS._sceneItems.remove(&scene->_storageCompartment);
scene->_sceneMode = 0;
animate(ANIM_MODE_5, scene);
return true;
}
-bool Scene1580::Actor5::startAction(CursorType action, Event &event) {
+bool Scene1580::HatchButton::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -9167,13 +9806,13 @@ bool Scene1580::Actor5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1580::ThrusterValve::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
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;
}
@@ -9199,13 +9838,13 @@ bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1580::Ignitor::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
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;
}
@@ -9235,7 +9874,6 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
loadScene(1580);
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_GRADUAL;
SceneExt::postInit();
- _field412 = 0;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -9245,136 +9883,134 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(26) == 1580) {
- _actor2.postInit();
- _actor2.setup(1580, 1, 4);
- _actor2.setPosition(Common::Point(159, 163));
- _actor2.setDetails(1550, 78, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580) {
+ _joystick.postInit();
+ _joystick.setup(1580, 1, 4);
+ _joystick.setPosition(Common::Point(159, 163));
+ _joystick.setDetails(1550, 78, -1, -1, 1, (SceneItem *) NULL);
} else {
- _item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
- }
-
- if (R2_INVENTORY.getObjectScene(51) == 1580) {
- _actor3.postInit();
- _actor3.setup(1580, 1, 1);
- _actor3.setPosition(Common::Point(124, 108));
- _actor3.fixPriority(10);
- _actor3.setDetails(1550, 13, -1, -1, 1, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1580, 1, 3);
- _actor1.setPosition(Common::Point(124, 96));
- _actor1.fixPriority(20);
- } else if (R2_INVENTORY.getObjectScene(28) == 1580) {
- _actor3.postInit();
- _actor3.setup(1580, 1, 1);
- _actor3.setPosition(Common::Point(124, 108));
- _actor3.fixPriority(10);
- _actor3.setDetails(1550, 14, -1, -1, 1, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1580, 3, 1);
- _actor1.setPosition(Common::Point(124, 109));
- _actor1.fixPriority(20);
+ _joystickPlug.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
+ }
+
+ if (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580) {
+ _screen.postInit();
+ _screen.setup(1580, 1, 1);
+ _screen.setPosition(Common::Point(124, 108));
+ _screen.fixPriority(10);
+ _screen.setDetails(1550, 13, -1, -1, 1, (SceneItem *) NULL);
+
+ _screenDisplay.postInit();
+ _screenDisplay.setup(1580, 1, 3);
+ _screenDisplay.setPosition(Common::Point(124, 96));
+ _screenDisplay.fixPriority(20);
+ } else if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580) {
+ _screen.postInit();
+ _screen.setup(1580, 1, 1);
+ _screen.setPosition(Common::Point(124, 108));
+ _screen.fixPriority(10);
+ _screen.setDetails(1550, 14, -1, -1, 1, (SceneItem *) NULL);
+
+ _screenDisplay.postInit();
+ _screenDisplay.setup(1580, 3, 1);
+ _screenDisplay.setPosition(Common::Point(124, 109));
+ _screenDisplay.fixPriority(20);
_sceneMode = 10;
} else {
- _item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 1, NULL);
+ _screenSlot.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 1, NULL);
}
- _actor4.postInit();
- if (R2_INVENTORY.getObjectScene(58) == 0) {
- _actor4.setup(1580, 5, 1);
- _actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
+ _storageCompartment.postInit();
+ if (R2_GLOBALS.getFlag(58) == 0) {
+ _storageCompartment.setup(1580, 5, 1);
+ _storageCompartment.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor4.setup(1580, 5, 6);
+ _storageCompartment.setup(1580, 5, 6);
}
- _actor4.setPosition(Common::Point(216, 108));
- _actor4.fixPriority(100);
+ _storageCompartment.setPosition(Common::Point(216, 108));
+ _storageCompartment.fixPriority(100);
- _actor5.postInit();
- _actor5.setup(1580, 4, 1);
- _actor5.setPosition(Common::Point(291, 147));
- _actor5.fixPriority(100);
- _actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
+ _hatchButton.postInit();
+ _hatchButton.setup(1580, 4, 1);
+ _hatchButton.setPosition(Common::Point(291, 147));
+ _hatchButton.fixPriority(100);
+ _hatchButton.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(23) == 1580) {
- _actor6.postInit();
- _actor6.setup(1580, 6, 2);
- _actor6.setPosition(Common::Point(222, 108));
- _actor6.fixPriority(50);
- _actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 1580) {
+ _thrusterValve.postInit();
+ _thrusterValve.setup(1580, 6, 2);
+ _thrusterValve.setPosition(Common::Point(222, 108));
+ _thrusterValve.fixPriority(50);
+ _thrusterValve.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
}
- if (R2_INVENTORY.getObjectScene(27) == 1580) {
- _actor7.postInit();
- _actor7.setup(1580, 6, 1);
- _actor7.setPosition(Common::Point(195, 108));
- _actor7.fixPriority(50);
- _actor7.setDetails(1550, 38, -1, 34, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 1580) {
+ _ignitor.postInit();
+ _ignitor.setup(1580, 6, 1);
+ _ignitor.setPosition(Common::Point(195, 108));
+ _ignitor.fixPriority(50);
+ _ignitor.setDetails(1550, 38, -1, 34, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._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);
-
+ _background.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
}
void Scene1580::signal() {
switch (_sceneMode++) {
case 10:
- _actor1.animate(ANIM_MODE_5, this);
+ _screenDisplay.animate(ANIM_MODE_5, this);
break;
case 11:
- _actor1.setup(1580, 1, 2);
- _actor1.setPosition(Common::Point(124, 94));
+ _screenDisplay.setup(1580, 1, 2);
+ _screenDisplay.setPosition(Common::Point(124, 94));
- if (R2_INVENTORY.getObjectScene(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));
@@ -9400,17 +10036,8 @@ void Scene1580::signal() {
* Scene 1625 - Miranda being questioned
*
*--------------------------------------------------------------------------*/
-Scene1625::Scene1625() {
- _field412 = 0;
-}
-
-void Scene1625::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
-}
-bool Scene1625::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1625::Wire::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -9418,11 +10045,18 @@ bool Scene1625::Actor7::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1631;
- scene->_actor3.postInit();
- scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_actor3, &scene->_actor7, NULL);
+ scene->_mirandaMouth.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_mirandaMouth, &scene->_wire, NULL);
return true;
}
+Scene1625::Scene1625() {
+}
+
+void Scene1625::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+}
+
void Scene1625::postInit(SceneObjectList *OwnerList) {
loadScene(1625);
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
@@ -9433,41 +10067,42 @@ void Scene1625::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_soldierSpeaker);
R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
- _actor7.postInit();
- _actor7.setup(1626, 2, 1);
- _actor7.setPosition(Common::Point(206, 133));
- _actor7.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
+ _wire.postInit();
+ _wire.setup(1626, 2, 1);
+ _wire.setPosition(Common::Point(206, 133));
+ _wire.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5.setup(1625, 8, 1);
- _actor5.setPosition(Common::Point(190, 131));
- _actor5.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
+ _wristRestraints.postInit();
+ _wristRestraints.setup(1625, 8, 1);
+ _wristRestraints.setPosition(Common::Point(190, 131));
+ _wristRestraints.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
- if (R2_GLOBALS._player._oldCharacterScene[3] == 1625) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 1625) {
if (!R2_GLOBALS.getFlag(83)) {
- _actor4.postInit();
- _actor4.setup(1626, 4, 1);
- _actor4.setPosition(Common::Point(96, 166));
- _actor4.setDetails(1625, -1, -1, -1, 1, (SceneItem *) NULL);
+ _glass.postInit();
+ _glass.setup(1626, 4, 1);
+ _glass.setPosition(Common::Point(96, 166));
+ _glass.setDetails(1625, -1, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
} else {
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _teal.postInit();
+ _teal.fixPriority(10);
- _actor6.postInit();
+ _tealRightArm.postInit();
R2_GLOBALS._player.disableControl();
_sceneMode = 1625;
- setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager, this, 1625, &_teal, &_tealRightArm, NULL);
}
R2_GLOBALS._sound1.play(245);
- _item1.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
- R2_GLOBALS._player._oldCharacterScene[3] = 1625;
- R2_GLOBALS._player._characterScene[3] = 1625;
+ _background.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1625;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 1625;
}
void Scene1625::remove() {
@@ -9479,101 +10114,100 @@ void Scene1625::signal() {
switch (_sceneMode) {
case 10:
R2_GLOBALS._player.disableControl();
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1626;
- setAction(&_sequenceManager, this, 1626, &_actor2, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1626, &_tealHead, &_glass, NULL);
break;
case 12:
- // TODO: check if OK_BTN_STRING is required
MessageDialog::show(DONE_MSG, OK_BTN_STRING);
break;
case 14:
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(831, this);
break;
case 99:
R2_GLOBALS._player.disableControl();
- switch (_stripManager._field2E8) {
- case 0:
+ switch (_stripManager._exitMode) {
+ case 1:
_sceneMode = 1627;
- setAction(&_sequenceManager, this, 1627, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1627, &_mirandaMouth, &_glass, NULL);
break;
- case 1:
+ case 2:
_sceneMode = 1629;
- setAction(&_sequenceManager, this, 1629, &_actor2, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1629, &_tealHead, &_wristRestraints, NULL);
break;
- case 3:
- R2_GLOBALS._player._oldCharacterScene[3] = 3150;
- R2_GLOBALS._player._characterScene[3] = 3150;
+ case 4:
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3150;
R2_GLOBALS._player._characterIndex = R2_QUINN;
- R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[1]);
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[R2_QUINN]);
break;
- case 4:
+ case 5:
_sceneMode = 1628;
- _actor2.remove();
- setAction(&_sequenceManager, this, 1628, &_actor3, &_actor4, NULL);
+ _tealHead.remove();
+ setAction(&_sequenceManager, this, 1628, &_mirandaMouth, &_glass, NULL);
break;
- case 5:
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ case 6:
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1632;
- setAction(&_sequenceManager, this, 1632, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1632, &_glass, NULL);
break;
- case 6:
+ case 7:
_sceneMode = 1633;
- setAction(&_sequenceManager, this, 1633, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1633, &_glass, NULL);
break;
- case 7:
+ case 8:
_sceneMode = 1635;
- setAction(&_sequenceManager, this, 1635, &_actor3, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1635, &_mirandaMouth, &_wristRestraints, NULL);
break;
- case 8:
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ case 9:
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1634;
- setAction(&_sequenceManager, this, 1634, &_actor3, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1634, &_mirandaMouth, &_wristRestraints, NULL);
break;
- case 2:
+ case 3:
// No break on purpose
default:
_sceneMode = 1630;
- _actor2.postInit();
- setAction(&_sequenceManager, this, 1630, &_actor1, &_actor6, NULL);
+ _tealHead.remove();
+ setAction(&_sequenceManager, this, 1630, &_teal, &_tealRightArm, NULL);
break;
}
- _field412 = _stripManager._field2E8;
+ //_field412 = _stripManager._field2E8;
_stripManager._field2E8 = 0;
break;
case 1625:
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
_sceneMode = 10;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(800, this);
break;
case 1626:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
- _actor3.postInit();
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
+ _mirandaMouth.postInit();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(832, this);
break;
case 1627:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -9581,22 +10215,22 @@ void Scene1625::signal() {
break;
case 1628:
R2_GLOBALS.setFlag(83);
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(834, this);
break;
case 1629:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -9607,34 +10241,33 @@ void Scene1625::signal() {
R2_GLOBALS._player._canWalk = true;
break;
case 1631:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
- _actor7.remove();
+ _wire.remove();
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _teal.postInit();
+ _teal.fixPriority(10);
- _actor6.postInit();
- warning("_actor6._actorName = \"arm\";");
+ _tealRightArm.postInit();
- R2_INVENTORY.setObjectScene(40, 3);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3);
_sceneMode = 14;
- setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager, this, 1625, &_teal, &_tealRightArm, NULL);
break;
case 1632:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(835, this);
break;
case 1633:
- _actor4.remove();
+ _glass.remove();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(818, this);
@@ -9645,9 +10278,9 @@ void Scene1625::signal() {
_stripManager.start(836, this);
break;
case 1635:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -9666,35 +10299,27 @@ void Scene1625::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 1700 -
+ * Scene 1700 - Rim
*
*--------------------------------------------------------------------------*/
+
Scene1700::Scene1700() {
- _field77A = 0;
- _field77C = 0;
+ _walkFlag = 0;
}
void Scene1700::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field77A);
- s.syncAsSint16LE(_field77C);
-}
-
-bool Scene1700::Item2::startAction(CursorType action, Event &event) {
- // The original contains a debug trace. It's currently skipped.
- // TODO: either add the debug trace, or remove this function and associated class
- return SceneHotspot::startAction(action, event);
+ s.syncAsSint16LE(_walkFlag);
}
-bool Scene1700::Actor11::startAction(CursorType action, Event &event) {
+bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._v558B6.set(80, 0, 240, 200);
scene->_sceneMode = 4;
Common::Point pt(271, 90);
@@ -9704,7 +10329,7 @@ bool Scene1700::Actor11::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1700::Actor12::startAction(CursorType action, Event &event) {
+bool Scene1700::Companion::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
@@ -9715,7 +10340,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();
@@ -9727,7 +10352,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();
@@ -9739,7 +10364,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();
@@ -9751,97 +10376,92 @@ 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();
- _actor10.remove();
+ _ledgeHopper.remove();
+ _hatch.remove();
}
- warning("tmpRect = _v5589E;");
- warning("Mouse_hideIfNeeded");
- warning("set_pane_p(_paneNumber);");
- warning("Big loop calling gfx_draw_slice_p");
-
- if (_field77A == 0)
- _field77A = 1;
- else
- _field77A = 0;
-
- warning("set_pane_p(_paneNumber);");
+ // The original had manual code here to redraw the background manually when
+ // changing areas within the scene. Which seems to be totally redundant.
- if ((_sceneMode != 40) && (R2_GLOBALS._v565F6 != 0)){
- _actor9.postInit();
- _actor9.setup(1701, 1, 1);
- _actor9.setPosition(Common::Point(220, 137));
- _actor9.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(12);
+ 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.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(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);
+ R2_GLOBALS._walkRegions.disableRegion(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;
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ _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;
+ _walkFlag = true;
- _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);
}
}
@@ -9855,12 +10475,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));
@@ -9873,44 +10490,44 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 1);
}
- _actor12.postInit();
- _actor12.animate(ANIM_MODE_1, NULL);
- _actor12.setObjectWrapper(new SceneObjectWrapper());
+ _companion.postInit();
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor12.setVisage(1506);
- _actor12._moveDiff = Common::Point(3, 1);
- _actor12.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setVisage(1506);
+ _companion._moveDiff = Common::Point(3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor12.setVisage(1501);
- _actor12._moveDiff = Common::Point(2, 1);
- _actor12.setDetails(9001, 1, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setVisage(1501);
+ _companion._moveDiff = Common::Point(2, 1);
+ _companion.setDetails(9001, 1, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._sound1.play(134);
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _playerShadow.postInit();
+ _playerShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor1.setVisage(1112);
+ _playerShadow.setVisage(1112);
else
- _actor1.setVisage(1111);
+ _playerShadow.setVisage(1111);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
+ _playerShadow._effect = EFFECT_SHADOW_MAP;
+ _playerShadow._shadowMap = _shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_playerShadow;
- _actor2.postInit();
- _actor2.fixPriority(10);
+ _companionShadow.postInit();
+ _companionShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor2.setVisage(1111);
+ _companionShadow.setVisage(1111);
else
- _actor2.setVisage(1112);
+ _companionShadow.setVisage(1112);
- _actor2._effect = 5;
- _actor2._field9C = _field312;
- _actor12._linkedActor = &_actor2;
+ _companionShadow._effect = EFFECT_SHADOW_MAP;
+ _companionShadow._shadowMap = _shadowPaletteMap;
+ _companion._linkedActor = &_companionShadow;
R2_GLOBALS._sound1.play(134);
@@ -9919,75 +10536,74 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.hide();
- _actor12.hide();
+ _companion.hide();
- _actor10.postInit();
- warning("_actor10._actorName = \"hatch\";");
- _actor10.hide();
+ _hatch.postInit();
+ _hatch.hide();
- _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);
+ _playerShadow.hide();
+ _companionShadow.hide();
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(539, this);
_sceneMode = 40;
break;
case 1750: {
R2_GLOBALS._player.setPosition(Common::Point(282, 121));
- _actor12.setPosition(Common::Point(282, 139));
+ _companion.setPosition(Common::Point(282, 139));
_sceneMode = 8;
Common::Point pt(262, 101);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
Common::Point pt2(262, 119);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, this);
+ _companion.addMover(mover2, &pt2, this);
}
break;
case 1800: {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.setPosition(Common::Point(0, 86));
- _actor12.setPosition(Common::Point(0, 64));
+ _companion.setPosition(Common::Point(0, 64));
_sceneMode = 7;
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player._strip = 1;
Common::Point pt(64, 86);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- _actor12.setObjectWrapper(NULL);
- _actor12._strip = 1;
+ _companion.setObjectWrapper(NULL);
+ _companion._strip = 1;
Common::Point pt2(77, 64);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
+ _companion.addMover(mover2, &pt2, NULL);
}
break;
default:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setPosition(Common::Point(109, 160));
- _actor12.setPosition(Common::Point(156, 160));
- R2_GLOBALS._walkRegions.enableRegion(15);
+ _companion.setPosition(Common::Point(156, 160));
+ R2_GLOBALS._walkRegions.disableRegion(15);
} else {
R2_GLOBALS._player.setPosition(Common::Point(156, 160));
- _actor12.setPosition(Common::Point(109, 160));
- R2_GLOBALS._walkRegions.enableRegion(17);
+ _companion.setPosition(Common::Point(109, 160));
+ R2_GLOBALS._walkRegions.disableRegion(17);
}
_sceneMode = 50;
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
break;
}
- R2_GLOBALS._player._characterScene[1] = 1700;
- R2_GLOBALS._player._characterScene[2] = 1700;
- R2_GLOBALS._player._oldCharacterScene[1] = 1700;
- R2_GLOBALS._player._oldCharacterScene[2] = 1700;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1700;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1700;
+
+ enterArea();
- R2_GLOBALS._v558B6.set(20, 0, 320, 200);
- subAF3F8();
- _item1.setDetails(1, 1700, 3, -1, -1);
- _item2.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
+ _surface.setDetails(1, 1700, 3, -1, -1);
+ _background.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
}
void Scene1700::remove() {
@@ -9999,62 +10615,62 @@ 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();
R2_GLOBALS._player.addMover(mover, &pt, this);
if (R2_GLOBALS._player._position.x < 132) {
- _actor12.setPosition(Common::Point(156, 170));
+ _companion.setPosition(Common::Point(156, 170));
Common::Point pt2(156, 160);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
- R2_GLOBALS._walkRegions.enableRegion(15);
+ _companion.addMover(mover2, &pt2, NULL);
+ R2_GLOBALS._walkRegions.disableRegion(15);
} else {
- _actor12.setPosition(Common::Point(109, 170));
+ _companion.setPosition(Common::Point(109, 170));
Common::Point pt3(109, 160);
NpcMover *mover3 = new NpcMover();
- _actor12.addMover(mover3, &pt3, NULL);
- R2_GLOBALS._walkRegions.enableRegion(17);
+ _companion.addMover(mover3, &pt3, NULL);
+ R2_GLOBALS._walkRegions.disableRegion(17);
}
}
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();
R2_GLOBALS._player.addMover(mover, &pt, this);
if (R2_GLOBALS._player._position.x >= 171) {
- _actor12.setPosition(Common::Point(155, 0));
+ _companion.setPosition(Common::Point(155, 0));
Common::Point pt2(155, 10);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
- R2_GLOBALS._walkRegions.enableRegion(15);
+ _companion.addMover(mover2, &pt2, NULL);
+ R2_GLOBALS._walkRegions.disableRegion(15);
} else {
- _actor12.setPosition(Common::Point(188, 0));
+ _companion.setPosition(Common::Point(188, 0));
Common::Point pt3(188, 10);
NpcMover *mover3 = new NpcMover();
- _actor12.addMover(mover3, &pt3, NULL);
- R2_GLOBALS._walkRegions.enableRegion(17);
+ _companion.addMover(mover3, &pt3, NULL);
+ R2_GLOBALS._walkRegions.disableRegion(17);
}
}
break;
case 3:
- if (_field77C == 0) {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ if (!_walkFlag) {
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
R2_GLOBALS.setFlag(15);
- _field77C = 0;
+ _walkFlag = false;
_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
@@ -10065,11 +10681,11 @@ void Scene1700::signal() {
_sceneMode = 5;
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);
+ _companion.addMover(mover, &pt, 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:
@@ -10081,16 +10697,16 @@ void Scene1700::signal() {
case 7:
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
R2_GLOBALS._player._strip = 1;
- _actor12.setObjectWrapper(new SceneObjectWrapper());
- _actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- R2_GLOBALS._walkRegions.enableRegion(14);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
+ _companion._strip = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ R2_GLOBALS._walkRegions.disableRegion(14);
break;
case 8:
R2_GLOBALS._player._strip = 2;
- _actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- R2_GLOBALS._walkRegions.enableRegion(12);
+ _companion._strip = 1;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ R2_GLOBALS._walkRegions.disableRegion(12);
break;
case 30:
_sceneMode = 31;
@@ -10102,29 +10718,29 @@ void Scene1700::signal() {
_stripManager.start(541, this);
break;
case 31:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
case 40:
R2_GLOBALS._player.disableControl();
_sceneMode = 1704;
- setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_actor9, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_companion,
+ &_hatch, &_ledgeHopper, &_playerShadow, &_companionShadow, NULL);
break;
case 50:
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- R2_GLOBALS._walkRegions.enableRegion(15);
+ R2_GLOBALS._walkRegions.disableRegion(15);
else
- R2_GLOBALS._walkRegions.enableRegion(17);
+ R2_GLOBALS._walkRegions.disableRegion(17);
R2_GLOBALS._player.enableControl();
break;
case 1704:
R2_GLOBALS._sound1.play(134);
- R2_GLOBALS._walkRegions.enableRegion(15);
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(12);
+ R2_GLOBALS._walkRegions.disableRegion(15);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(12);
R2_GLOBALS._player.fixPriority(-1);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
R2_GLOBALS._player.enableControl();
@@ -10133,182 +10749,189 @@ 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);
-}
-
-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;
+ s.syncAsSint16LE(_incrAmount);
+ s.syncAsSint16LE(_xp);
+ s.syncAsSint16LE(_ys);
+ s.syncAsSint16LE(_height);
+ s.syncAsSint16LE(_thumbHeight);
+ s.syncAsSint16LE(_mouseDown);
+}
+
+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);
-
- setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * tmpVar2) / (_fieldAC - 1))));
- scene->_field415 = scene->_field412 * tmpVar2;
-}
+ int tmpVar = (_height / (_thumbHeight - 1)) / 2;
+ int tmpVar2 = ((_position.y - _ys + tmpVar) * _thumbHeight) / (_height + 2 * tmpVar);
-void Scene1750::Actor4::remove() {
- // Function kept to match IDA. Could be removed.
- SceneActor::remove();
+ setPosition(Common::Point(_xp, _ys + ((_height * tmpVar2) / (_thumbHeight - 1))));
+ scene->_speed = scene->_direction * tmpVar2;
}
-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;
+ _speedCurrent = 0;
+ _speed = 0;
+ _speedDelta = 0;
+ _rotationSegment = 0;
+ _rotationSegCurrent = 0;
+ _newRotation = 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;
- }
+ _rotation = nullptr;
+}
- return true;
+void Scene1750::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+
+ s.syncAsSint16LE(_direction);
+ s.syncAsSint16LE(_speedCurrent);
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_speedDelta);
+ s.syncAsSint16LE(_rotationSegment);
+ s.syncAsSint16LE(_rotationSegCurrent);
+ s.syncAsSint16LE(_newRotation);
}
void Scene1750::postInit(SceneObjectList *OwnerList) {
loadScene(1750);
R2_GLOBALS._sound1.play(115);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.set(0, 0, 320, 200);
+
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
- R2_GLOBALS._player._characterScene[1] = 1750;
- R2_GLOBALS._player._characterScene[2] = 1750;
- R2_GLOBALS._player._oldCharacterScene[1] = 1750;
- R2_GLOBALS._player._oldCharacterScene[2] = 1750;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1750;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1750;
_rotation = R2_GLOBALS._scenePalette.addRotation(224, 254, 1);
_rotation->setDelay(0);
_rotation->_idxChange = 0;
_rotation->_countdown = 2;
- switch ((R2_GLOBALS._v565F6 + 2) % 4) {
+ switch ((R2_GLOBALS._rimLocation + 2) % 4) {
case 0:
_rotation->_currIndex = 247;
break;
@@ -10346,79 +10969,75 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.enableControl();
- _actor3.postInit();
- _actor3.setup(1750, 3, 1);
- _actor3.setPosition(Common::Point(49, 185));
- _actor3.fixPriority(7);
- _actor3.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL);
+ _radarSweep.postInit();
+ _radarSweep.setup(1750, 3, 1);
+ _radarSweep.setPosition(Common::Point(49, 185));
+ _radarSweep.fixPriority(7);
+ _radarSweep.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(1750, 2, 1);
- _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._v565F6 % 800) * 4) - 1440));
- _actor1.fixPriority(8);
+ _scannerIcon.postInit();
+ _scannerIcon.setup(1750, 2, 1);
+ _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
+ _scannerIcon.fixPriority(8);
- _actor2.postInit();
- _actor2.setup(1750, 1, 4);
+ _redLights.postInit();
+ _redLights.setup(1750, 1, 4);
- int tmpVar = abs(_actor1._position.y - 158) / 100;
+ int tmpVar = ABS(_scannerIcon._position.y - 158) / 100;
if (tmpVar >= 8)
- _actor2.hide();
- else if (_actor1._position.y <= 158)
- _actor2.setPosition(Common::Point(137, (tmpVar * 7) + 122));
+ _redLights.hide();
+ else if (_scannerIcon._position.y <= 158)
+ _redLights.setPosition(Common::Point(137, (tmpVar * 7) + 122));
else
- _actor2.setPosition(Common::Point(148, (tmpVar * 7) + 122));
-
- _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;
- _field417 = 0;
- _field413 = 0;
- _field415 = 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.setPosition(Common::Point(148, (tmpVar * 7) + 122));
+
+ _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
+ _speedDelta = 0;
+ _speedCurrent = 0;
+ _speed = 0;
+ _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4;
+
+ _redLightsDescr.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
+ _greenLights.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
+ _frontView.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
+ _rearView.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
+ _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);
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
}
@@ -10429,26 +11048,97 @@ 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 (!_speedDelta && (_speed != _speedCurrent)) {
+ if (_speedCurrent >= _speed)
+ --_speedCurrent;
+ else
+ ++_speedCurrent;
+
+ _speedDelta = 21 - ABS(_speedCurrent);
+ }
+
+ if (_speedDelta == 1) {
+ if (_speedCurrent == 0) {
+ _radarSweep.show();
+ _rotation->_idxChange = 0;
+ } else {
+ if (_rotation->_idxChange == 0)
+ _radarSweep.hide();
+
+ if (_speedCurrent < -12) {
+ _rotation->setDelay(15 - ABS(_speedCurrent));
+ _rotation->_idxChange = -2;
+ } else if (_speedCurrent < 0) {
+ _rotation->setDelay(10 - ABS(_speedCurrent));
+ _rotation->_idxChange = -1;
+ } else if (_speedCurrent < 11) {
+ _rotation->setDelay(10 - _speedCurrent);
+ _rotation->_idxChange = 1;
+ } else {
+ _rotation->setDelay(15 - _speedCurrent);
+ _rotation->_idxChange = 2;
+ }
+ }
+ }
+
+ if (_speedDelta)
+ --_speedDelta;
+
+ _rotationSegCurrent = _rotationSegment;
+ _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4;
+
+ if ((_rotationSegCurrent + 1) == _rotationSegment || (_rotationSegCurrent - 3) == _rotationSegment) {
+ if (R2_GLOBALS._rimLocation < 2400) {
+ ++R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if ((_rotationSegCurrent - 1) == _rotationSegment || (_rotationSegCurrent + 3) == _rotationSegment) {
+ if (R2_GLOBALS._rimLocation > -2400) {
+ --R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if (_rotation->_currIndex != _newRotation) {
+ // Handle setting the position of the lift icon in the scanner display
+ _newRotation = _rotation->_currIndex;
+ _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) +
+ ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
+ }
+ }
+
+ int v = ABS(_scannerIcon._position.y - 158) / 100;
+ if (v < 8) {
+ // Show how close the user is to the lift on the second column of lights
+ _redLights.show();
+ _redLights.setPosition(Common::Point((_scannerIcon._position.y <= 158) ? 137 : 148,
+ v * 7 + 122));
+ } else {
+ _redLights.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;
@@ -10457,7 +11147,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;
@@ -10465,7 +11155,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;
@@ -10478,7 +11168,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);
@@ -10494,40 +11184,47 @@ 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 {
+ // Seeker failing to force open doors
scene->_sceneMode = 1813;
- scene->setAction(&scene->_sequenceManager, scene, 1813, &R2_GLOBALS._player, NULL);
+ // Original was using 1813 in setAction too, but it somewhat broken.
+ // Seeker goes 2 pixels to high, hiding behind the door
+ scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_doors, NULL);
}
} else if (R2_GLOBALS.getFlag(14)) {
return SceneActor::startAction(action, event);
} else {
+ // Quinn trying to force open doors
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1812;
scene->setAction(&scene->_sequenceManager, scene, 1812, &R2_GLOBALS._player, NULL);
@@ -10536,40 +11233,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);
@@ -10577,20 +11274,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);
}
}
}
@@ -10599,25 +11296,25 @@ bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1800::Exit1::changeScene() {
+void Scene1800::SouthExit::changeScene() {
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
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);
}
}
@@ -10629,95 +11326,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);
+ _southExit.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
+ _background.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
+
+ _lever.postInit();
+ _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();
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ _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();
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ _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) {
@@ -10725,12 +11425,12 @@ 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));
- R2_GLOBALS._walkRegions.enableRegion(8);
+ _companion.setPosition(Common::Point(160, 139));
+ R2_GLOBALS._walkRegions.disableRegion(8);
} else {
- _actor2.setPosition(Common::Point(209, 150));
- _actor2.setStrip(6);
- R2_GLOBALS._walkRegions.enableRegion(8);
+ _companion.setPosition(Common::Point(209, 150));
+ _companion.setStrip(6);
+ R2_GLOBALS._walkRegions.disableRegion(8);
}
} else {
if (R2_GLOBALS.getFlag(14)) {
@@ -10740,55 +11440,55 @@ 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);
- R2_GLOBALS._walkRegions.enableRegion(10);
- R2_GLOBALS._walkRegions.enableRegion(11);
+ _companion.setPosition(Common::Point(114, 150));
+ _companion.setStrip(5);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._walkRegions.disableRegion(11);
}
} else {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setPosition(Common::Point(140, 160));
- _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));
}
}
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _playerShadow.postInit();
+ _playerShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor1.setVisage(1111);
+ _playerShadow.setVisage(1111);
else
- _actor1.setVisage(1110);
+ _playerShadow.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
+ _playerShadow._effect = EFFECT_SHADOW_MAP;
+ _playerShadow._shadowMap = _shadowPaletteMap;
- R2_GLOBALS._player._linkedActor = &_actor1;
+ R2_GLOBALS._player._linkedActor = &_playerShadow;
- _actor3.postInit();
- _actor3.fixPriority(10);
+ _companionShadow.postInit();
+ _companionShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor3.setVisage(1110);
+ _companionShadow.setVisage(1110);
else
- _actor3.setVisage(1111);
+ _companionShadow.setVisage(1111);
- _actor3._effect = 5;
- _actor3._field9C = _field312;
+ _companionShadow._effect = EFFECT_SHADOW_MAP;
+ _companionShadow._shadowMap = _shadowPaletteMap;
- _actor2._linkedActor = &_actor3;
+ _companion._linkedActor = &_companionShadow;
- R2_GLOBALS._player._characterScene[1] = 1800;
- R2_GLOBALS._player._characterScene[2] = 1800;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1800;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1800;
- _item2.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
- _item1.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
+ _elevatorContents.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
+ _elevator.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
// Original was calling _item3.setDetails(Rect(1800, 11, 24, 23), 25, -1, -1, -1, 1, NULL);
// This is *wrong*. The following statement is a wild guess based on good common sense
- _item3.setDetails(11, 1800, 23, 24, 25);
- _item4.setDetails(Rect(0, 0, 320, 200), 1800, 17, -1, 19, 1, NULL);
+ _surface.setDetails(11, 1800, 23, 24, 25);
+ _secBackground.setDetails(Rect(0, 0, 320, 200), 1800, 17, -1, 19, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
@@ -10796,38 +11496,38 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
} else {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
}
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
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);
}
}
- R2_GLOBALS._player._oldCharacterScene[1] = 1800;
- R2_GLOBALS._player._oldCharacterScene[2] = 1800;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1800;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1800;
}
void Scene1800::signal() {
@@ -10835,27 +11535,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
@@ -10884,8 +11584,31 @@ void Scene1800::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
+ // Cases 23 and 24 have been added to fix missing hardcoded logic in the original,
+ // when Seeker tries to open the door
+ case 23:
+ _sceneMode = 24;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.setup(1801, 5, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_8, NULL);
+ _stripManager.start(550, this);
+ break;
+ case 24:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(1507, 4, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+
+ _doors.setup(1801, 3, 1);
+ _doors.setPosition(Common::Point(160, 139));
+ _doors.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
+ _doors.show();
+
+ R2_GLOBALS._player._position.y += 2;
+ R2_GLOBALS._player.show();
+ break;
case 1800:
- R2_GLOBALS._walkRegions.enableRegion(8);
+ R2_GLOBALS._walkRegions.disableRegion(8);
if (R2_GLOBALS.getFlag(63))
R2_GLOBALS._player.enableControl(CURSOR_USE);
else {
@@ -10895,14 +11618,14 @@ void Scene1800::signal() {
}
break;
case 1801:
- R2_GLOBALS._walkRegions.enableRegion(10);
- R2_GLOBALS._walkRegions.enableRegion(11);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._walkRegions.disableRegion(11);
R2_GLOBALS.setFlag(63);
// The following check is completely dumb.
// Either an original bug, or dead code.
if (R2_GLOBALS.getFlag(63)) {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
_sceneMode = 10;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -10925,24 +11648,29 @@ 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:
_sceneMode = 13;
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
+ // Case 1813 has been added to fix Seeker missing animation in the original game
+ case 1813:
+ _sceneMode = 23;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
case 1814:
// No break on purpose
case 1815:
- R2_GLOBALS._walkRegions.enableRegion(10);
- R2_GLOBALS._walkRegions.enableRegion(11);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._walkRegions.disableRegion(11);
R2_GLOBALS._player.enableControl();
break;
case 1816:
// No break on purpose
case 1817:
- R2_GLOBALS._walkRegions.enableRegion(8);
+ R2_GLOBALS._walkRegions.disableRegion(8);
R2_GLOBALS._player.enableControl();
break;
default:
@@ -10959,18 +11687,11 @@ void Scene1800::saveCharacter(int characterIndex) {
}
/*--------------------------------------------------------------------------
- * Scene 1850 -
+ * Scene 1850 - Rim Lift Interior
*
*--------------------------------------------------------------------------*/
-Scene1850::Scene1850() {
- warning("STUBBED: Scene1850()");
-}
-
-void Scene1850::synchronize(Serializer &s) {
- warning("STUBBED: Scene1850::synchronize()");
-}
-bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
+bool Scene1850::Button::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
@@ -10984,13 +11705,13 @@ bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
else
scene->setAction(&scene->_sequenceManager1, scene, 1852, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(30)) {
- scene->_field41E = 1;
+ scene->_seqNumber = 1;
scene->_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_robot, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_robot, NULL);
R2_GLOBALS.clearFlag(30);
} else {
@@ -11005,30 +11726,30 @@ bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
+bool Scene1850::Robot::startAction(CursorType action, Event &event) {
Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if ((R2_GLOBALS._player._characterIndex != R2_SEEKER) || (R2_GLOBALS.getFlag(33)) || (R2_GLOBALS.getFlag(30)))
+ if ((R2_GLOBALS._player._characterIndex != R2_SEEKER) || R2_GLOBALS.getFlag(33) || R2_GLOBALS.getFlag(30))
return SceneActor::startAction(action, event);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1857;
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1858, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1858, &R2_GLOBALS._player, &scene->_robot, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1857, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1857, &R2_GLOBALS._player, &scene->_robot, NULL);
R2_GLOBALS.setFlag(30);
return true;
break;
case CURSOR_LOOK:
if (R2_GLOBALS.getFlag(34))
- SceneItem::display(1850, 2, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1850, 2, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else
- SceneItem::display(1850, 1, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1850, 1, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
@@ -11038,7 +11759,7 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 30;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
scene->_stripManager.start(558, scene);
return true;
@@ -11048,18 +11769,20 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
} else if (R2_GLOBALS.getFlag(30)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1875;
- scene->_actor2.postInit();
+ scene->_airbag.postInit();
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1876, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1876,
+ &R2_GLOBALS._player, &scene->_airbag, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1875, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1875,
+ &R2_GLOBALS._player, &scene->_airbag, NULL);
return true;
} else if (R2_GLOBALS.getFlag(70)) {
R2_GLOBALS._player.disableControl();
- scene->_sceneMode = 30;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
scene->_stripManager.start(557, scene);
R2_GLOBALS.setFlag(69);
@@ -11075,7 +11798,8 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1878;
- scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player,
+ &scene->_robot, &scene->_airbag, NULL);
}
return true;
@@ -11086,20 +11810,20 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
}
}
-bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1850::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
- Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
-
if (R2_GLOBALS.getFlag(32)) {
- SceneItem::display(3240, 4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3240, 4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
}
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- if (scene->_field412 == 1851)
- R2_GLOBALS._player._effect = 1;
+ if (scene->_sceneMode == 1851)
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
if (_position.x >= 160)
R2_GLOBALS.setFlag(29);
@@ -11108,30 +11832,30 @@ bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
if ((R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
if (_position.x >= 160)
- scene->_field41E = 3;
+ scene->_seqNumber = 3;
else
- scene->_field41E = 2;
+ scene->_seqNumber = 2;
scene->_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32)) {
- scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_robot, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_robot, NULL);
}
} else {
scene->_sceneMode = 11;
if (_position.x >= 160) {
- scene->setAction(&scene->_sequenceManager1, scene, 1866, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1866, &R2_GLOBALS._player, &scene->_rightDoor, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1865, &R2_GLOBALS._player, &scene->_actor6, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1865, &R2_GLOBALS._player, &scene->_leftDoor, NULL);
}
}
return true;
}
-bool Scene1850::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1850::DisplayScreen::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (_position.y != 120))
return SceneHotspot::startAction(action, event);
@@ -11149,6 +11873,28 @@ bool Scene1850::Actor8::startAction(CursorType action, Event &event) {
return true;
}
+/*------------------------------------------------------------------------*/
+
+Scene1850::Scene1850() {
+ _sceneMode = 0;
+ _shadeCountdown = 0;
+ _shadeDirection = 0;
+ _shadeChanging = false;
+ _seqNumber = 0;
+}
+
+void Scene1850::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_sceneMode);
+ s.syncAsSint16LE(_shadeCountdown);
+ s.syncAsSint16LE(_shadeDirection);
+ s.syncAsSint16LE(_shadeChanging);
+ s.syncAsSint16LE(_seqNumber);
+ s.syncAsSint16LE(_playerDest.x);
+ s.syncAsSint16LE(_playerDest.y);
+}
+
void Scene1850::postInit(SceneObjectList *OwnerList) {
loadScene(1850);
@@ -11158,10 +11904,10 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_palette1.loadPalette(0);
if (R2_GLOBALS.getFlag(31)) {
- _field412 = 1850;
+ _sceneMode = 1850;
g_globals->_scenePalette.loadPalette(1850);
} else {
- _field412 = 1851;
+ _sceneMode = 1851;
g_globals->_scenePalette.loadPalette(1851);
}
@@ -11173,173 +11919,173 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _field418 = 0;
- _field41E = 0;
- _field41A = Common::Point(0, 0);
+ _shadeChanging = false;
+ _seqNumber = 0;
+ _playerDest = Common::Point(0, 0);
- R2_GLOBALS._player._characterScene[1] = 1850;
- R2_GLOBALS._player._characterScene[2] = 1850;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1850;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1850;
- _item2.setDetails(Rect(101, 56, 111, 63), 1850, 19, -1, -1, 1, NULL);
+ _button.setDetails(Rect(101, 56, 111, 63), 1850, 19, -1, -1, 1, NULL);
- _actor6.postInit();
- _actor6.setup(1850, 3, 1);
- _actor6.setPosition(Common::Point(66, 102));
- _actor6.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+ _leftDoor.postInit();
+ _leftDoor.setup(1850, 3, 1);
+ _leftDoor.setPosition(Common::Point(66, 102));
+ _leftDoor.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
- _actor7.postInit();
- _actor7.setup(1850, 2, 1);
- _actor7.setPosition(Common::Point(253, 102));
- _actor7.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+ _rightDoor.postInit();
+ _rightDoor.setup(1850, 2, 1);
+ _rightDoor.setPosition(Common::Point(253, 102));
+ _rightDoor.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
- R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(1);
- _actor5.postInit();
+ _robot.postInit();
if (R2_GLOBALS.getFlag(34)) {
- R2_GLOBALS._walkRegions.enableRegion(2);
- _actor5.setup(1851, 4, 3);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ _robot.setup(1851, 4, 3);
} else if (R2_GLOBALS.getFlag(30)) {
- _actor5.setup(1851, 2, 2);
+ _robot.setup(1851, 2, 2);
} else {
- R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(5);
if (R2_GLOBALS.getFlag(33)) {
- R2_GLOBALS._walkRegions.enableRegion(2);
- _actor5.setup(1851, 1, 3);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ _robot.setup(1851, 1, 3);
} else {
- _actor5.setup(1851, 2, 1);
+ _robot.setup(1851, 2, 1);
}
}
- _actor5.setPosition(Common::Point(219, 130));
- _actor5.fixPriority(114);
- _actor5.setDetails(1850, -1, -1, -1, 1, (SceneItem *) NULL);
+ _robot.setPosition(Common::Point(219, 130));
+ _robot.fixPriority(114);
+ _robot.setDetails(1850, -1, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
} else {
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
- R2_GLOBALS._player._effect = 6;
- _actor1._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
+ _companion._effect = EFFECT_SHADED2;
if (R2_GLOBALS.getFlag(31)) {
R2_GLOBALS._player._shade = 0;
- _actor1._shade = 0;
+ _companion._shade = 0;
} else {
R2_GLOBALS._player._shade = 6;
- _actor1._shade = 6;
+ _companion._shade = 6;
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
- _actor2.postInit();
+ _airbag.postInit();
if (R2_GLOBALS.getFlag(34)) {
- _actor2.setup(1851, 4, 2);
- _actor2.fixPriority(114);
+ _airbag.setup(1851, 4, 2);
+ _airbag.fixPriority(114);
} else {
- _actor2.setup(1851, 4, 1);
+ _airbag.setup(1851, 4, 1);
}
- _actor2.setPosition(Common::Point(179, 113));
+ _airbag.setPosition(Common::Point(179, 113));
- if ((_actor5._strip == 1) && (_actor5._frame == 3)){
- _actor2.hide();
+ if ((_robot._strip == 1) && (_robot._frame == 3)){
+ _airbag.hide();
}
- _actor2.setDetails(1850, 6, -1, -1, 1, (SceneItem *) NULL);
+ _airbag.setDetails(1850, 6, -1, -1, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setVisage(1511);
- _actor1.setVisage(1508);
+ _companion.setVisage(1508);
- _actor3.postInit();
- _actor3.setup(1853, 3, 1);
- _actor3.setPosition(Common::Point(122, 113));
- _actor3.fixPriority(114);
- _actor3._effect = 6;
+ _screen.postInit();
+ _screen.setup(1853, 3, 1);
+ _screen.setPosition(Common::Point(122, 113));
+ _screen.fixPriority(114);
+ _screen._effect = EFFECT_SHADED2;
// Totally useless test
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ _screen.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
} else {
// And the associated dead code
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
+ _screen.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
}
- _actor4.postInit();
- _actor4.setup(1853, 3, 2);
- _actor4.setPosition(Common::Point(139, 111));
- _actor4.fixPriority(114);
- _actor4._effect = 6;
+ _helmet.postInit();
+ _helmet.setup(1853, 3, 2);
+ _helmet.setPosition(Common::Point(139, 111));
+ _helmet.fixPriority(114);
+ _helmet._effect = EFFECT_SHADED2;
// Still totally useless test
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *) NULL);
+ _helmet.setDetails(1850, 29, -1, -1, 2, (SceneItem *) NULL);
} else {
// Another piece of dead code
- _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ _helmet.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
}
if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- _actor3._shade = 6;
- _actor4._shade = 6;
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
} else {
R2_GLOBALS._player.setVisage(1500);
- _actor1.setVisage(1505);
+ _companion.setVisage(1505);
}
} else { // Not Quinn
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setVisage(1508);
- _actor1.setVisage(1511);
+ _companion.setVisage(1511);
- _actor3.postInit();
- _actor3.setup(1853, 3, 1);
- _actor3.setPosition(Common::Point(122, 113));
- _actor3.fixPriority(114);
- _actor3._effect = 6;
+ _screen.postInit();
+ _screen.setup(1853, 3, 1);
+ _screen.setPosition(Common::Point(122, 113));
+ _screen.fixPriority(114);
+ _screen._effect = EFFECT_SHADED2;
// Totally useless test
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
// Dead code
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
+ _screen.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
} else {
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
+ _screen.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
}
- _actor4.postInit();
- _actor4.setup(1853, 3, 2);
- _actor4.setPosition(Common::Point(139, 111));
- _actor4.fixPriority(114);
- _actor4._effect = 6;
+ _helmet.postInit();
+ _helmet.setup(1853, 3, 2);
+ _helmet.setPosition(Common::Point(139, 111));
+ _helmet.fixPriority(114);
+ _helmet._effect = EFFECT_SHADED2;
// Again, useless test
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
// and dead code
- _actor4.setDetails(1850, 29, -1, -1, 1, (SceneItem *) NULL);
+ _helmet.setDetails(1850, 29, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor4.setDetails(1850, 28, -1, -1, 1, (SceneItem *) NULL);
+ _helmet.setDetails(1850, 28, -1, -1, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- _actor3._shade = 6;
- _actor4._shade = 6;
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
} else {
R2_GLOBALS._player.setVisage(1505);
- _actor1.setVisage(1500);
+ _companion.setVisage(1500);
}
}
@@ -11347,25 +12093,25 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.setPosition(Common::Point(80, 114));
- _actor1.animate(ANIM_MODE_1, NULL);
- _actor1.setObjectWrapper(new SceneObjectWrapper());
- _actor1.setStrip(3);
- _actor1.setPosition(Common::Point(180, 96));
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
+ _companion.setStrip(3);
+ _companion.setPosition(Common::Point(180, 96));
if (R2_GLOBALS.getFlag(30)) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setObjectWrapper(NULL);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
if (R2_GLOBALS.getFlag(32)) {
- _actor1.setup(1854, 1, 3);
+ _companion.setup(1854, 1, 3);
} else {
- _actor1.setup(1854, 2, 3);
+ _companion.setup(1854, 2, 3);
}
- _actor1.setPosition(Common::Point(164, 106));
+ _companion.setPosition(Common::Point(164, 106));
} else {
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setObjectWrapper(NULL);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setup(1854, 1, 3);
} else {
@@ -11378,58 +12124,58 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
} else { // R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 1850
- R2_GLOBALS._player._effect = 1;
- _actor1._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion._effect = EFFECT_SHADED;
R2_GLOBALS._player.disableControl();
_sceneMode = 10;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(29)) {
- setAction(&_sequenceManager1, this, 1863, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1863, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
- setAction(&_sequenceManager1, this, 1861, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1861, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(29)) {
- setAction(&_sequenceManager1, this, 1864, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1864, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
- setAction(&_sequenceManager1, this, 1862, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1862, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
}
}
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion._moveDiff = Common::Point(5, 3);
} else {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion._moveDiff = Common::Point(3, 2);
}
- _actor8.postInit();
- _actor8.setup(1850, 1, 1);
+ _displayScreen.postInit();
+ _displayScreen.setup(1850, 1, 1);
if (R2_GLOBALS.getFlag(62)) {
- _actor8.setPosition(Common::Point(159, 120));
+ _displayScreen.setPosition(Common::Point(159, 120));
} else {
- _actor8.setPosition(Common::Point(159, 184));
+ _displayScreen.setPosition(Common::Point(159, 184));
}
- _actor8.fixPriority(113);
+ _displayScreen.fixPriority(113);
if (R2_GLOBALS.getFlag(34)) {
- _actor8.setDetails(1850, 25, -1, -1, 4, &_actor5);
+ _displayScreen.setDetails(1850, 25, -1, -1, 4, &_robot);
} else {
- _actor8.setDetails(1850, 25, -1, -1, 2, (SceneItem *) NULL);
+ _displayScreen.setDetails(1850, 25, -1, -1, 2, (SceneItem *) NULL);
}
if (!R2_GLOBALS.getFlag(62)) {
- _actor8.hide();
+ _displayScreen.hide();
}
- _item1.setDetails(Rect(0, 0, 320, 200), 1850, 16, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1850, 16, -1, -1, 1, NULL);
- R2_GLOBALS._player._oldCharacterScene[1] = 1850;
- R2_GLOBALS._player._oldCharacterScene[2] = 1850;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1850;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1850;
}
void Scene1850::remove() {
@@ -11445,13 +12191,13 @@ void Scene1850::remove() {
void Scene1850::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 6;
- _actor1._effect = 6;
- _actor1._shade = 6;
+ _companion._effect = EFFECT_SHADED2;
+ _companion._shade = 6;
- R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(5);
if (R2_GLOBALS.getFlag(68)) {
R2_GLOBALS._player.enableControl();
@@ -11471,7 +12217,8 @@ void Scene1850::signal() {
break;
case 16:
_sceneMode = 1870;
- setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_actor1, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_companion,
+ &_screen, &_helmet, NULL);
break;
case 20:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
@@ -11479,7 +12226,8 @@ void Scene1850::signal() {
case 21:
R2_GLOBALS._player.disableControl();
_sceneMode = 1877;
- setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_actor1, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_companion,
+ &_robot, NULL);
break;
case 30:
R2_GLOBALS._player.disableControl();
@@ -11489,40 +12237,41 @@ void Scene1850::signal() {
case 1852:
// No break on purpose:
case 1853:
- if (_field412 == 1851) {
+ if (_sceneMode == 1851) { // At this point, SceneMode can't be equal to 1851 => dead code
R2_GLOBALS.setFlag(31);
_palette1.loadPalette(1850);
- _field412 = 1850;
+ _sceneMode = 1850;
} else {
R2_GLOBALS.clearFlag(31);
_palette1.loadPalette(1851);
- _field412 = 1851;
+ _sceneMode = 1851;
}
- _field418 = 1;
+ _shadeChanging = true;
if (R2_GLOBALS.getFlag(30)) {
- _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
} else if (R2_GLOBALS.getFlag(34)) {
if (R2_GLOBALS.getFlag(62)) {
R2_GLOBALS.clearFlag(62);
- _actor8.setAction(&_sequenceManager2, this, 1851, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1851, &_displayScreen, NULL);
} else {
R2_GLOBALS.setFlag(62);
- _actor8.setAction(&_sequenceManager2, this, 1850, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1850, &_displayScreen, NULL);
}
} else if (R2_GLOBALS.getFlag(33)) {
R2_GLOBALS.setFlag(62);
R2_GLOBALS.setFlag(34);
- R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(2);
- _actor2.postInit();
- _actor2.setDetails(1850, 6, -1, -1, 5, &_actor5);
+ _airbag.postInit();
+ _airbag.setDetails(1850, 6, -1, -1, 5, &_robot);
_sceneMode = 1879;
- _actor8.setAction(&_sequenceManager2, this, 1879, &_actor5, &_actor8, &_actor2, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1879, &_robot,
+ &_displayScreen, &_airbag, NULL);
} else {
- _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
}
if (R2_GLOBALS.getFlag(34))
@@ -11530,12 +12279,12 @@ void Scene1850::signal() {
else
R2_GLOBALS._scenePalette.addFader(_palette1._palette, 256, 5, this);
- if (_field412 == 1851)
- _field416 = -20;
+ if (_sceneMode == 1851)
+ _shadeDirection = -20;
else
- _field416 = 20;
+ _shadeDirection = 20;
- _field414 = 20;
+ _shadeCountdown = 20;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (_sceneMode == 1879)
@@ -11571,7 +12320,7 @@ void Scene1850::signal() {
case 1858:
R2_GLOBALS._player.disableControl();
_sceneMode = 1859;
- setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_robot, NULL);
R2_GLOBALS.clearFlag(30);
break;
case 1859:
@@ -11581,16 +12330,16 @@ void Scene1850::signal() {
_stripManager.start(575, this);
break;
case 1860:
- if (_field41A.x != 0) {
+ if (_playerDest.x != 0) {
R2_GLOBALS._player.enableControl();
PlayerMover *mover = new PlayerMover();
- R2_GLOBALS._player.addMover(mover, &_field41A, this);
+ R2_GLOBALS._player.addMover(mover, &_playerDest, this);
- _field41A = Common::Point(0, 0);
+ _playerDest = Common::Point(0, 0);
}
- switch (_field41E) {
+ switch (_seqNumber) {
case 1:
_sceneMode = 1853;
if (R2_GLOBALS.getFlag(32)) {
@@ -11601,24 +12350,23 @@ void Scene1850::signal() {
break;
case 2:
_sceneMode = 11;
- setAction(&_sequenceManager1, this, 1865, &R2_GLOBALS._player, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1865, &R2_GLOBALS._player, &_leftDoor, NULL);
break;
case 3:
- warning("_field41E == 3");
_sceneMode = 11;
- setAction(&_sequenceManager1, this, 1866, &R2_GLOBALS._player, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1866, &R2_GLOBALS._player, &_rightDoor, NULL);
break;
default:
break;
}
- _field41E = 0;
+ _seqNumber = 0;
break;
case 1870:
- R2_GLOBALS._walkRegions.enableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(5);
R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
R2_GLOBALS.setFlag(32);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 1875:
R2_INVENTORY.setObjectScene(R2_AIRBAG, 1850);
@@ -11627,41 +12375,41 @@ void Scene1850::signal() {
_stripManager.start(561, this);
break;
case 1877:
- _actor3.postInit();
- _actor3._effect = 6;
+ _screen.postInit();
+ _screen._effect = EFFECT_SHADED2;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ _screen.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
} else {
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *)NULL);
+ _screen.setDetails(1850, 30, -1, -1, 2, (SceneItem *)NULL);
}
- _actor4.postInit();
- _actor4._effect = 6;
+ _helmet.postInit();
+ _helmet._effect = EFFECT_SHADED2;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *)NULL);
+ _helmet.setDetails(1850, 29, -1, -1, 2, (SceneItem *)NULL);
} else {
- _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ _helmet.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
}
if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- _actor3._shade = 6;
- _actor4._shade = 6;
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
R2_GLOBALS.clearFlag(30);
_sceneMode = 15;
- setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_actor3, NULL);
- setAction(&_sequenceManager2, this, 1868, &_actor1, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_screen, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1868, &_companion, &_helmet, NULL);
break;
case 1878:
R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1850);
R2_GLOBALS.setFlag(33);
- R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._player.enableControl();
break;
case 1879:
@@ -11681,17 +12429,17 @@ void Scene1850::signal() {
}
void Scene1850::process(Event &event) {
- if ( (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW)
- && (R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
- _field41A = event.mousePos;
+ if ( (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_WALK)
+ && (R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
+ _playerDest = event.mousePos;
R2_GLOBALS._player.disableControl();
_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32)) {
- setAction(&_sequenceManager1, this, 1860, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1860, &R2_GLOBALS._player, &_robot, NULL);
} else {
- setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_robot, NULL);
}
- R2_GLOBALS.clearFlag(32);
+ R2_GLOBALS.clearFlag(30);
event.handled = true;
}
@@ -11699,119 +12447,120 @@ void Scene1850::process(Event &event) {
}
void Scene1850::dispatch() {
- if (_field418 != 0) {
- _field414--;
- if (_field414 == 0)
- _field418 = 0;
+ if (_shadeChanging) {
+ _shadeCountdown--;
+ if (_shadeCountdown == 0)
+ _shadeChanging = false;
- if (_field416 >= 0) {
- R2_GLOBALS._player._shade = (_field414 * 6) / _field416;
+ if (_shadeDirection >= 0) {
+ R2_GLOBALS._player._shade = (_shadeCountdown * 6) / _shadeDirection;
} else {
- R2_GLOBALS._player._shade = ((_field414 * 6) / _field416) + 6;
+ R2_GLOBALS._player._shade = ((_shadeCountdown * 6) / _shadeDirection) + 6;
}
R2_GLOBALS._player._flags |= OBJFLAG_PANES;
- _actor1._shade = R2_GLOBALS._player._shade;
- _actor1._flags |= OBJFLAG_PANES;
+ _companion._shade = R2_GLOBALS._player._shade;
+ _companion._flags |= OBJFLAG_PANES;
- _actor3._shade = R2_GLOBALS._player._shade;
- _actor3._flags |= OBJFLAG_PANES;
+ _screen._shade = R2_GLOBALS._player._shade;
+ _screen._flags |= OBJFLAG_PANES;
- _actor4._shade = R2_GLOBALS._player._shade;
- _actor4._flags |= OBJFLAG_PANES;
+ _helmet._shade = R2_GLOBALS._player._shade;
+ _helmet._flags |= OBJFLAG_PANES;
}
if (R2_GLOBALS.getFlag(32)) {
- _actor3.setPosition(Common::Point(_actor8._position.x - 37, _actor8._position.y - 71));
- _actor4.setPosition(Common::Point(_actor8._position.x - 20, _actor8._position.y - 73));
+ _screen.setPosition(Common::Point(_displayScreen._position.x - 37, _displayScreen._position.y - 71));
+ _helmet.setPosition(Common::Point(_displayScreen._position.x - 20, _displayScreen._position.y - 73));
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
- _actor2.setPosition(Common::Point(_actor8._position.x + 20, _actor8._position.y - 71));
+ _airbag.setPosition(Common::Point(_displayScreen._position.x + 20, _displayScreen._position.y - 71));
}
Scene::dispatch();
}
/*--------------------------------------------------------------------------
- * Scene 1875 -
+ * Scene 1875 - Rim Lift Computer
*
*--------------------------------------------------------------------------*/
-Scene1875::Actor1875::Actor1875() {
- _fieldA4 = 0;
- _fieldA6 = 0;
+
+Scene1875::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
}
-void Scene1875::Actor1875::synchronize(Serializer &s) {
+void Scene1875::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_buttonDown);
}
-void Scene1875::Actor1875::subB84AB() {
+void Scene1875::Button::doButtonPress() {
Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._sound1.play(227);
int newFrameNumber;
- switch (_fieldA4) {
+ switch (_buttonId) {
case 3:
- if ((scene->_actor1._frame == 1) && (scene->_actor4._strip == 2)) {
+ if ((scene->_map._frame == 1) && (scene->_button1._strip == 2)) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
scene->_sceneMode = 10;
- scene->_stripManager.start(576, this);
+ scene->_stripManager.start(576, scene);
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1890;
- scene->_actor2.postInit();
- scene->setAction(&scene->_sequenceManager, scene, 1890, &scene->_actor2, NULL);
+ scene->_rimPosition.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1890, &scene->_rimPosition, NULL);
}
break;
case 4:
- newFrameNumber = scene->_actor1._frame + 1;
+ newFrameNumber = scene->_map._frame + 1;
if (newFrameNumber > 6)
newFrameNumber = 1;
- scene->_actor1.setFrame(newFrameNumber);
+ scene->_map.setFrame(newFrameNumber);
break;
case 5:
- newFrameNumber = scene->_actor1._frame - 1;
+ newFrameNumber = scene->_map._frame - 1;
if (newFrameNumber < 1)
newFrameNumber = 6;
- scene->_actor1.setFrame(newFrameNumber);
+ scene->_map.setFrame(newFrameNumber);
break;
default:
break;
}
}
-void Scene1875::Actor1875::subB8271(int indx) {
+void Scene1875::Button::initButton(int buttonId) {
postInit();
- _fieldA4 = indx;
- _fieldA6 = 0;
+ _buttonId = buttonId;
+ _buttonDown = false;
setVisage(1855);
- if (_fieldA4 == 1)
+ if (_buttonId == 1)
setStrip(2);
else
setStrip(1);
- setFrame(_fieldA4);
- switch (_fieldA4 - 1) {
- case 0:
+ setFrame(_buttonId);
+ switch (_buttonId) {
+ case 1:
setPosition(Common::Point(20, 144));
break;
- case 1:
+ case 2:
setPosition(Common::Point(82, 144));
break;
- case 2:
+ case 3:
setPosition(Common::Point(136, 144));
break;
- case 3:
+ case 4:
setPosition(Common::Point(237, 144));
break;
- case 4:
+ case 5:
setPosition(Common::Point(299, 144));
break;
default:
@@ -11821,36 +12570,37 @@ void Scene1875::Actor1875::subB8271(int indx) {
setDetails(1875, 6, 1, -1, 2, (SceneItem *) NULL);
}
-void Scene1875::Actor1875::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) || (event.handled))
+void Scene1875::Button::process(Event &event) {
+ if (!R2_GLOBALS._player._uiEnabled || event.handled)
return;
Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_STEPPING_DISKS) && (_bounds.contains(event.mousePos)) && (_fieldA6 == 0)) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ && (_bounds.contains(event.mousePos)) && !_buttonDown) {
setStrip(2);
- switch (_fieldA4) {
+ switch (_buttonId) {
case 1:
R2_GLOBALS._sound2.play(227);
- scene->_actor5.setStrip(1);
+ scene->_button2.setStrip(1);
break;
case 2:
R2_GLOBALS._sound2.play(227);
- scene->_actor4.setStrip(1);
+ scene->_button1.setStrip(1);
break;
default:
break;
}
- _fieldA6 = 1;
+ _buttonDown = true;
event.handled = true;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldA6 != 0)) {
- if ((_fieldA4 == 3) || (_fieldA4 == 4) || (_fieldA4 == 5)) {
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ if ((_buttonId == 3) || (_buttonId == 4) || (_buttonId == 5)) {
setStrip(1);
- subB84AB();
+ doButtonPress();
}
- _fieldA6 = 0;
+ _buttonDown = false;
event.handled = true;
}
}
@@ -11859,43 +12609,47 @@ void Scene1875::postInit(SceneObjectList *OwnerList) {
loadScene(1875);
SceneExt::postInit();
- R2_GLOBALS._player._characterScene[1] = 1875;
- R2_GLOBALS._player._characterScene[2] = 1875;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1875;
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _actor4.subB8271(1);
- _actor5.subB8271(2);
- _actor6.subB8271(3);
- _actor7.subB8271(4);
- _actor8.subB8271(5);
+ _button1.initButton(1);
+ _button2.initButton(2);
+ _button3.initButton(3);
+ _button4.initButton(4);
+ _button5.initButton(5);
- _actor1.postInit();
- _actor1.setup(1855, 4, 1);
- _actor1.setPosition(Common::Point(160, 116));
+ _map.postInit();
+ _map.setup(1855, 4, 1);
+ _map.setPosition(Common::Point(160, 116));
R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+
if (R2_GLOBALS._sceneManager._previousScene == 1625) {
R2_GLOBALS._sound1.play(122);
R2_GLOBALS._player.disableControl();
_sceneMode = 11;
- _actor2.postInit();
- setAction(&_sequenceManager, this, 1892, &_actor2, NULL);
- } else if (R2_GLOBALS._sceneManager._previousScene == 3150) {
- R2_GLOBALS._sound1.play(116);
+ _rimPosition.postInit();
+ setAction(&_sequenceManager, this, 1892, &_rimPosition, NULL);
} else {
+ if (R2_GLOBALS._sceneManager._previousScene == 3150) {
+ R2_GLOBALS._sound1.play(116);
+ }
+
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
- _item2.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
+ _screen.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
- R2_GLOBALS._player._characterScene[1] = 1875;
- R2_GLOBALS._player._characterScene[2] = 1875;
- R2_GLOBALS._player._oldCharacterScene[1] = 1875;
- R2_GLOBALS._player._oldCharacterScene[2] = 1875;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1875;
}
void Scene1875::signal() {
@@ -11903,8 +12657,8 @@ void Scene1875::signal() {
case 10:
R2_GLOBALS._player.disableControl();
_sceneMode = 1891;
- _actor2.postInit();
- setAction(&_sequenceManager, this, 1891, &_actor2, NULL);
+ _rimPosition.postInit();
+ setAction(&_sequenceManager, this, 1891, &_rimPosition, NULL);
break;
case 11:
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -11912,7 +12666,7 @@ void Scene1875::signal() {
_stripManager.start(577, this);
break;
case 1890:
- _actor2.remove();
+ _rimPosition.remove();
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
break;
@@ -11934,20 +12688,19 @@ void Scene1875::signal() {
void Scene1875::process(Event &event) {
Scene::process(event);
- _actor4.process(event);
- _actor5.process(event);
- _actor6.process(event);
- _actor7.process(event);
- _actor8.process(event);
+ _button1.process(event);
+ _button2.process(event);
+ _button3.process(event);
+ _button4.process(event);
+ _button5.process(event);
}
/*--------------------------------------------------------------------------
- * Scene 1900 -
+ * Scene 1900 - Spill Mountains Elevator Exit
*
*--------------------------------------------------------------------------*/
-bool Scene1900::Actor2::startAction(CursorType action, Event &event) {
- Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+bool Scene1900::LiftDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -11958,24 +12711,26 @@ bool Scene1900::Actor2::startAction(CursorType action, Event &event) {
return true;
}
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.enableControl(CURSOR_USE);
if (_position.x >= 160) {
scene->_sceneMode = 1905;
- scene->setAction(&scene->_sequenceManager1, scene, 1905, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1905, &R2_GLOBALS._player, &scene->_rightDoor, NULL);
} else {
R2_GLOBALS.setFlag(29);
scene->_sceneMode = 1904;
- scene->setAction(&scene->_sequenceManager1, scene, 1904, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1904, &R2_GLOBALS._player, &scene->_leftDoor, NULL);
}
return true;
}
-void Scene1900::Exit1::changeScene() {
+void Scene1900::WestExit::changeScene() {
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 10;
Common::Point pt(-10, 135);
@@ -11983,10 +12738,10 @@ void Scene1900::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1900::Exit2::changeScene() {
+void Scene1900::EastExit::changeScene() {
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 11;
Common::Point pt(330, 135);
@@ -12003,7 +12758,7 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS._sceneManager._previousScene = 1925;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
- R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1925;
}
if (R2_GLOBALS._sceneManager._previousScene != 1875)
@@ -12013,11 +12768,11 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
_stripManager.setFontNumber(3);
_stripManager.addSpeaker(&_seekerSpeaker);
- _exit1.setDetails(Rect(0, 105, 14, 145), R2_COM_SCANNER, 2000);
- _exit1.setDest(Common::Point(14, 135));
+ _westExit.setDetails(Rect(0, 105, 14, 145), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 135));
- _exit2.setDetails(Rect(305, 105, 320, 145), R2_SPENT_POWER_CAPSULE, 2000);
- _exit2.setDest(Common::Point(315, 135));
+ _eastExit.setDetails(Rect(305, 105, 320, 145), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 135));
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -12034,83 +12789,85 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene != 1925)
R2_GLOBALS.clearFlag(29);
- _actor2.postInit();
- _actor2.setup(1901, 1, 1);
- _actor2.setPosition(Common::Point(95, 109));
- _actor2.fixPriority(100);
+ _leftDoor.postInit();
+ _leftDoor.setup(1901, 1, 1);
+ _leftDoor.setPosition(Common::Point(95, 109));
+ _leftDoor.fixPriority(100);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor2.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ _leftDoor.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
else
- _actor2.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+ _leftDoor.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
- _actor3.postInit();
- _actor3.setup(1901, 2, 1);
- _actor3.setPosition(Common::Point(225, 109));
- _actor3.fixPriority(100);
+ _rightDoor.postInit();
+ _rightDoor.setup(1901, 2, 1);
+ _rightDoor.setPosition(Common::Point(225, 109));
+ _rightDoor.fixPriority(100);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor3.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ _rightDoor.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
else
- _actor3.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+ _rightDoor.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
if (R2_GLOBALS._sceneManager._previousScene != 1875) {
- _object1.postInit();
- _object1.setup(1945, 6, 1);
- _object1.setPosition(Common::Point(96, 109));
- _object1.fixPriority(80);
+ _leftDoorFrame.postInit();
+ _leftDoorFrame.setup(1945, 6, 1);
+ _leftDoorFrame.setPosition(Common::Point(96, 109));
+ _leftDoorFrame.fixPriority(80);
- _object2.postInit();
- _object2.setup(1945, 6, 2);
- _object2.setPosition(Common::Point(223, 109));
- _object2.fixPriority(80);
+ _rightDoorFrame.postInit();
+ _rightDoorFrame.setup(1945, 6, 2);
+ _rightDoorFrame.setPosition(Common::Point(223, 109));
+ _rightDoorFrame.fixPriority(80);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1875) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
- _actor1.postInit();
+ _companion.postInit();
_sceneMode = 20;
- R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_actor2, NULL);
- _actor1.setAction(&_sequenceManager2, this, 1900, &_actor1, &_actor3, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_leftDoor, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1900, &_companion, &_rightDoor, NULL);
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1925) {
if (R2_GLOBALS.getFlag(29)) {
R2_GLOBALS.clearFlag(29);
- _actor2.hide();
+ _leftDoor.hide();
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.setPosition(Common::Point(90, 106));
_sceneMode = 1906;
- setAction(&_sequenceManager1, this, 1906, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, 1906, &R2_GLOBALS._player, &_leftDoor, NULL);
} else {
- _actor3.hide();
+ _rightDoor.hide();
R2_GLOBALS._player.setStrip(5);
R2_GLOBALS._player.setPosition(Common::Point(230, 106));
_sceneMode = 1907;
- setAction(&_sequenceManager1, this, 1907, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager1, this, 1907, &R2_GLOBALS._player, &_rightDoor, NULL);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- _actor1.setPosition(Common::Point(30, 110));
- R2_GLOBALS._walkRegions.enableRegion(1);
- _actor1.setup(2008, 3, 1);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ _companion.setPosition(Common::Point(30, 110));
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ _companion.setup(2008, 3, 1);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
- } else if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- _actor1.setPosition(Common::Point(30, 110));
- R2_GLOBALS._walkRegions.enableRegion(1);
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 3, 1);
- _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
- } else {
- _actor1.setup(2008, 3, 1);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ _companion.setPosition(Common::Point(30, 110));
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _companion.setup(2008, 3, 1);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ }
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS._v56605[1] == 5) {
+ if (R2_GLOBALS._spillLocation[R2_QUINN] == 5) {
_sceneMode = 1902;
setAction(&_sequenceManager1, this, 1902, &R2_GLOBALS._player, NULL);
} else {
@@ -12118,7 +12875,7 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1903, &R2_GLOBALS._player, NULL);
}
} else {
- if (R2_GLOBALS._v56605[2] == 5) {
+ if (R2_GLOBALS._spillLocation[R2_SEEKER] == 5) {
_sceneMode = 1908;
setAction(&_sequenceManager1, this, 1908, &R2_GLOBALS._player, NULL);
} else {
@@ -12133,8 +12890,8 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
}
- _item2.setDetails(Rect(77, 2, 240, 103), 1900, 6, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1900, 3, -1, -1, 1, NULL);
+ _elevator.setDetails(Rect(77, 2, 240, 103), 1900, 6, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1900, 3, -1, -1, 1, NULL);
}
void Scene1900::remove() {
@@ -12145,16 +12902,16 @@ void Scene1900::remove() {
void Scene1900::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 5;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 5;
R2_GLOBALS._sceneManager.changeScene(2000);
break;
case 11:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 6;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 6;
R2_GLOBALS._sceneManager.changeScene(2000);
break;
case 20:
++_sceneMode;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(1300, this);
break;
case 21:
@@ -12167,20 +12924,20 @@ void Scene1900::signal() {
break;
case 22:
_sceneMode = 1910;
- _actor1.setAction(&_sequenceManager2, this, 1910, &_actor1, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1910, &_companion, NULL);
break;
case 1904:
R2_GLOBALS._scene1925CurrLevel = -3;
// No break on purpose
case 1905:
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
R2_GLOBALS._sceneManager.changeScene(1925);
break;
case 1910:
- R2_INVENTORY.setObjectScene(22, 2535);
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._player._oldCharacterScene[1] = 1900;
- R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1900;
R2_GLOBALS._sceneManager.changeScene(2450);
break;
case 1906:
@@ -12193,11 +12950,12 @@ void Scene1900::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1925 -
+ * Scene 1925 - Spill Mountains Elevator Shaft
*
*--------------------------------------------------------------------------*/
+
Scene1925::Scene1925() {
- _field9B8 = 0;
+ _newSceneMode = 0;
for (int i = 0; i < 5; i++)
_levelResNum[i] = 0;
}
@@ -12205,20 +12963,20 @@ Scene1925::Scene1925() {
void Scene1925::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field9B8);
+ s.syncAsSint16LE(_newSceneMode);
for (int i = 0; i < 5; i++)
s.syncAsSint16LE(_levelResNum[i]);
}
-bool Scene1925::Hotspot2::startAction(CursorType action, Event &event) {
- Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1925::Button::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100))
return SceneHotspot::startAction(action, event);
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 20))
scene->_sceneMode = 1928;
else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 200))
@@ -12226,12 +12984,13 @@ bool Scene1925::Hotspot2::startAction(CursorType action, Event &event) {
else
scene->_sceneMode = 1930;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_door, NULL);
return true;
}
-bool Scene1925::Hotspot3::startAction(CursorType action, Event &event) {
+bool Scene1925::Ladder::startAction(CursorType action, Event &event) {
if ((!R2_GLOBALS.getFlag(29)) || (action != CURSOR_USE))
return SceneHotspot::startAction(action, event);
@@ -12241,9 +13000,10 @@ bool Scene1925::Hotspot3::startAction(CursorType action, Event &event) {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
+ scene->_westExit._enabled = false;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
@@ -12278,10 +13038,11 @@ void Scene1925::ExitUp::changeScene() {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
- scene->_field9B8 = 1927;
+ scene->_westExit._enabled = false;
+ scene->_newSceneMode = 1927;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return;
}
@@ -12300,7 +13061,7 @@ void Scene1925::ExitUp::changeScene() {
}
}
-void Scene1925::Exit2::changeScene() {
+void Scene1925::ExitDown::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
@@ -12308,10 +13069,11 @@ void Scene1925::Exit2::changeScene() {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
- scene->_field9B8 = 1926;
+ scene->_westExit._enabled = false;
+ scene->_newSceneMode = 1926;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return;
}
@@ -12329,20 +13091,20 @@ void Scene1925::Exit2::changeScene() {
scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
}
-void Scene1925::Exit3::changeScene() {
+void Scene1925::WestExit::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 1921;
scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
}
-void Scene1925::Exit4::changeScene() {
+void Scene1925::EastExit::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 1920;
scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
}
@@ -12368,18 +13130,18 @@ void Scene1925::changeLevel(bool upFlag) {
break;
case 3:
loadScene(_levelResNum[4]);
- _item2.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 2, NULL);
- _actor1.setDetails(1925, 0, 1, 2, 2, (SceneItem *) NULL);
- _actor1.show();
+ _button.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 2, NULL);
+ _door.setDetails(1925, 0, 1, 2, 2, (SceneItem *) NULL);
+ _door.show();
break;
case 512:
R2_GLOBALS._scene1925CurrLevel = 508;
// No break on purpose
default:
loadScene(_levelResNum[(R2_GLOBALS._scene1925CurrLevel % 4)]);
- R2_GLOBALS._sceneItems.remove(&_item2);
- R2_GLOBALS._sceneItems.remove(&_actor1);
- _actor1.hide();
+ R2_GLOBALS._sceneItems.remove(&_button);
+ R2_GLOBALS._sceneItems.remove(&_door);
+ _door.hide();
break;
}
@@ -12407,34 +13169,35 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(220);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player._characterScene[2] = 1925;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1925;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
+
switch (R2_GLOBALS._scene1925CurrLevel) {
case -2:
- _exit4.setDetails(Rect(203, 44, 247, 111), EXITCURSOR_E, 1925);
- _item3.setDetails(Rect(31, 3, 45, 167), 1925, 6, -1, 8, 1, NULL);
+ _eastExit.setDetails(Rect(203, 44, 247, 111), EXITCURSOR_E, 1925);
+ _ladder.setDetails(Rect(31, 3, 45, 167), 1925, 6, -1, 8, 1, NULL);
break;
case 3:
- _actor1.setDetails(1925, 0, 1, 2, 1, (SceneItem *) NULL);
- _item2.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 1, NULL);
+ _door.setDetails(1925, 0, 1, 2, 1, (SceneItem *) NULL);
+ _button.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 1, NULL);
// No break on purpose
case -3:
- _exit3.setDetails(Rect(83, 38, 128, 101), EXITCURSOR_W, 1925);
+ _westExit.setDetails(Rect(83, 38, 128, 101), EXITCURSOR_W, 1925);
// No break on purpose
default:
_exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1925);
- _exit2.setDetails(Rect(128, 160, 190, 167), EXITCURSOR_S, 1925);
- _item3.setDetails(Rect(141, 11, 167, 159), 1925, 6, -1, -1, 1, NULL);
+ _exitDown.setDetails(Rect(128, 160, 190, 167), EXITCURSOR_S, 1925);
+ _ladder.setDetails(Rect(141, 11, 167, 159), 1925, 6, -1, -1, 1, NULL);
break;
}
- _actor1.postInit();
- _actor1.setup(1925, 5, 1);
- _actor1.setPosition(Common::Point(128, 35));
- _actor1.hide();
+ _door.postInit();
+ _door.setup(1925, 5, 1);
+ _door.setPosition(Common::Point(128, 35));
+ _door.hide();
if (R2_GLOBALS._scene1925CurrLevel == 3)
- _actor1.show();
+ _door.show();
R2_GLOBALS._player.enableControl(CURSOR_USE);
switch (R2_GLOBALS._scene1925CurrLevel) {
@@ -12444,7 +13207,7 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(224, 109));
break;
case -3:
- _actor1.hide();
+ _door.hide();
R2_GLOBALS._player.setup(20, 5, 1);
R2_GLOBALS._player.setPosition(Common::Point(110, 100));
break;
@@ -12459,14 +13222,14 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player._canWalk = false;
- _field9B8 = 0;
+ _newSceneMode = 0;
R2_GLOBALS._sceneManager._previousScene = 1925;
- _item1.setDetails(Rect(27, 0, 292, 200), 1925, 9, -1, -1, 1, NULL);
+ _background.setDetails(Rect(27, 0, 292, 200), 1925, 9, -1, -1, 1, NULL);
}
void Scene1925::remove() {
R2_GLOBALS._sound1.fadeOut2(NULL);
- R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1925;
SceneExt::remove();
}
@@ -12497,10 +13260,10 @@ void Scene1925::signal() {
changeLevel(true);
break;
case 1925:
- _exit3._enabled = false;
- if (_field9B8 != 0) {
- _sceneMode = _field9B8;
- _field9B8 = 0;
+ _westExit._enabled = false;
+ if (_newSceneMode != 0) {
+ _sceneMode = _newSceneMode;
+ _newSceneMode = 0;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
}
// No break on purpose
@@ -12513,24 +13276,25 @@ void Scene1925::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1945 -
+ * Scene 1945 - Spill Mountains Shaft Bottom
*
*--------------------------------------------------------------------------*/
+
Scene1945::Scene1945() {
- _fieldEAA = 0;
- _fieldEAC = 0;
- _fieldEAE = CURSOR_NONE;
+ _nextSceneMode1 = 0;
+ _nextSceneMode2 = 0;
+ _lampUsed = CURSOR_NONE;
}
void Scene1945::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_fieldEAA);
- s.syncAsSint16LE(_fieldEAC);
- s.syncAsSint16LE(_fieldEAE);
+ s.syncAsSint16LE(_nextSceneMode1);
+ s.syncAsSint16LE(_nextSceneMode2);
+ s.syncAsSint16LE(_lampUsed);
}
-bool Scene1945::Hotspot3::startAction(CursorType action, Event &event) {
+bool Scene1945::Ice::startAction(CursorType action, Event &event) {
Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -12541,10 +13305,10 @@ bool Scene1945::Hotspot3::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1942;
else {
scene->_sceneMode = 1940;
- scene->_fieldEAA = 1942;
+ scene->_nextSceneMode1 = 1942;
}
// At this point the original check if _sceneMode != 0. Skipped.
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_gunpowder, NULL);
return true;
break;
case CURSOR_USE:
@@ -12559,9 +13323,9 @@ bool Scene1945::Hotspot3::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
if (event.mousePos.x > 130)
- scene->_item3.setDetails(1945, 3, -1, -1, 3, (SceneItem *) NULL);
+ scene->_ice.setDetails(1945, 3, -1, -1, 3, (SceneItem *) NULL);
else
- scene->_item3.setDetails(1945, 3, -1, 5, 3, (SceneItem *) NULL);
+ scene->_ice.setDetails(1945, 3, -1, 5, 3, (SceneItem *) NULL);
}
// No break on purpose
default:
@@ -12570,22 +13334,23 @@ bool Scene1945::Hotspot3::startAction(CursorType action, Event &event) {
}
}
-bool Scene1945::Hotspot4::startAction(CursorType action, Event &event) {
- Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1945::Ladder::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl(CURSOR_USE);
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142)) {
scene->_sceneMode = 1949;
- scene->_fieldEAA = 1947;
+ scene->_nextSceneMode1 = 1947;
} else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
|| ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
scene->_sceneMode = 1947;
- } else if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142) && (event.mousePos.y >= 30)) {
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)
+ && (event.mousePos.y >= 30)) {
scene->_sceneMode = 1940;
} else {
R2_GLOBALS._player.enableControl(CURSOR_USE);
@@ -12598,23 +13363,23 @@ bool Scene1945::Hotspot4::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1945::Actor3::startAction(CursorType action, Event &event) {
- if ((action == R2_ALCOHOL_LAMP_3) && (action == R2_ALCOHOL_LAMP_2)) {
+bool Scene1945::Gunpowder::startAction(CursorType action, Event &event) {
+ if ((action == R2_ALCOHOL_LAMP_3) || (action == R2_ALCOHOL_LAMP_2)) {
Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
- scene->_fieldEAE = action;
+ scene->_lampUsed = action;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) {
scene->_sceneMode= 1947;
- scene->_fieldEAA = 1943;
+ scene->_nextSceneMode1 = 1943;
} else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)) {
scene->_sceneMode = 1940;
- scene->_fieldEAA = 1943;
+ scene->_nextSceneMode1 = 1943;
} else {
scene->_sceneMode = 1949;
- scene->_fieldEAA = 1947;
- scene->_fieldEAC = 1943;
+ scene->_nextSceneMode1 = 1947;
+ scene->_nextSceneMode2 = 1943;
}
// At this point the original check if _sceneMode != 0. Skipped.
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
@@ -12633,7 +13398,7 @@ void Scene1945::ExitUp::changeScene() {
if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142)) {
scene->_sceneMode = 1949;
- scene->_fieldEAA = 1947;
+ scene->_nextSceneMode1 = 1947;
} else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
|| ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
scene->_sceneMode = 1947;
@@ -12647,7 +13412,7 @@ void Scene1945::ExitUp::changeScene() {
}
}
-void Scene1945::Exit2::changeScene() {
+void Scene1945::CorridorExit::changeScene() {
Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
@@ -12656,7 +13421,7 @@ void Scene1945::Exit2::changeScene() {
if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)) {
scene->_sceneMode = 1940;
- scene->_fieldEAA = 1945;
+ scene->_nextSceneMode1 = 1945;
} else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
|| ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
scene->_sceneMode = 1945;
@@ -12674,36 +13439,36 @@ void Scene1945::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- R2_GLOBALS._player._characterScene[2] = 1945;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1945;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
_exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1945);
- _exit2.setDetails(Rect(238, 144, 274, 167), EXITCURSOR_E, 1945);
+ _corridorExit.setDetails(Rect(238, 144, 274, 167), EXITCURSOR_E, 1945);
- _item4.setDetails(Rect(141, 3, 167, 126), 1945, 9, -1, -1, 1, NULL);
+ _ladder.setDetails(Rect(141, 3, 167, 126), 1945, 9, -1, -1, 1, NULL);
if (!R2_GLOBALS.getFlag(43)) {
- _exit2._enabled = false;
- _actor3.postInit();
- _actor3.setup(1945, 4, 1);
- _actor3.setPosition(Common::Point(253, 169));
- _actor3.fixPriority(150);
+ _corridorExit._enabled = false;
+ _gunpowder.postInit();
+ _gunpowder.setup(1945, 4, 1);
+ _gunpowder.setPosition(Common::Point(253, 169));
+ _gunpowder.fixPriority(150);
if (R2_GLOBALS.getFlag(42))
- _actor3.setDetails(1945, 15, -1, -1, 1, (SceneItem *) NULL);
+ _gunpowder.setDetails(1945, 15, -1, -1, 1, (SceneItem *) NULL);
else
- _actor3.hide();
+ _gunpowder.hide();
- _actor1.postInit();
- _actor1.setup(1945, 8, 1);
- _actor1.setPosition(Common::Point(253, 169));
- _actor1.fixPriority(130);
+ _coveringIce.postInit();
+ _coveringIce.setup(1945, 8, 1);
+ _coveringIce.setPosition(Common::Point(253, 169));
+ _coveringIce.fixPriority(130);
- _actor2.postInit();
- _actor2.setup(1945, 3, 1);
- _actor2.hide();
+ _alcoholLamp.postInit();
+ _alcoholLamp.setup(1945, 3, 1);
+ _alcoholLamp.hide();
} else {
- _exit2._enabled = true;
+ _corridorExit._enabled = true;
}
switch (R2_GLOBALS._sceneManager._previousScene) {
@@ -12726,12 +13491,12 @@ void Scene1945::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player._canWalk = false;
- _fieldEAA = 0;
- _fieldEAC = 0;
+ _nextSceneMode1 = 0;
+ _nextSceneMode2 = 0;
- _item3.setDetails(11, 1945, 3, -1, 5);
- _item1.setDetails(Rect(238, 144, 274, 167), 1945, 0, -1, 2, 1, NULL);
- _item2.setDetails(Rect(27, 3, 292, 167), 1945, 3, -1, -1, 1, NULL);
+ _ice.setDetails(11, 1945, 3, -1, 5);
+ _hole.setDetails(Rect(238, 144, 274, 167), 1945, 0, -1, 2, 1, NULL);
+ _ice2.setDetails(Rect(27, 3, 292, 167), 1945, 3, -1, -1, 1, NULL);
}
void Scene1945::remove() {
@@ -12742,9 +13507,9 @@ void Scene1945::remove() {
void Scene1945::signal() {
switch (_sceneMode) {
case 1940:
- if (_fieldEAA == 1943) {
- _sceneMode = _fieldEAA;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ if (_nextSceneMode1 == 1943) {
+ _sceneMode = _nextSceneMode1;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
_sceneMode = 1946;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
@@ -12752,27 +13517,27 @@ void Scene1945::signal() {
return;
break;
case 1941:
- if (_fieldEAA == 0) {
+ if (_nextSceneMode1 == 0) {
R2_GLOBALS._scene1925CurrLevel = 0;
R2_GLOBALS.setFlag(29);
R2_GLOBALS._sceneManager.changeScene(1925);
} else {
- _sceneMode = _fieldEAA;
- _fieldEAA = 0;
+ _sceneMode = _nextSceneMode1;
+ _nextSceneMode1 = 0;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
}
return;
case 1942:
R2_INVENTORY.setObjectScene(R2_GUNPOWDER, 0);
- _actor3.setDetails(1945, 15, -1, -1, 2, (SceneItem *) NULL);
+ _gunpowder.setDetails(1945, 15, -1, -1, 2, (SceneItem *) NULL);
R2_GLOBALS.setFlag(42);
break;
case 1943:
R2_GLOBALS._sound1.fadeOut2(NULL);
- R2_INVENTORY.setObjectScene(_fieldEAE, 0);
+ R2_INVENTORY.setObjectScene(_lampUsed, 0);
_sceneMode = 1948;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor3, &_actor2, &_actor1, NULL);
- setAction(&_sequenceManager2, NULL, 1941, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_gunpowder, &_alcoholLamp, &_coveringIce, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager2, NULL, 1941, &R2_GLOBALS._player, NULL);
return;
case 1944:
break;
@@ -12780,18 +13545,19 @@ void Scene1945::signal() {
R2_GLOBALS._sceneManager.changeScene(1950);
return;
case 1946:
- if (_fieldEAA == 1942) {
- _sceneMode = _fieldEAA;
- _fieldEAA = 0;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor3, NULL);
+ if (_nextSceneMode1 == 1942) {
+ _sceneMode = _nextSceneMode1;
+ _nextSceneMode1 = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_gunpowder, NULL);
return;
}
+ _sceneMode = 0;
break;
case 1947:
- if (_fieldEAA == 1943) {
- _sceneMode = _fieldEAA;
- _fieldEAA = 1948;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ if (_nextSceneMode1 == 1943) {
+ _sceneMode = _nextSceneMode1;
+ _nextSceneMode1 = 1948;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
_sceneMode = 1941;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
@@ -12799,20 +13565,20 @@ void Scene1945::signal() {
return;
case 1948:
R2_GLOBALS._sound1.play(220);
- _exit2._enabled = true;
- R2_GLOBALS._sceneItems.remove(&_actor3);
+ _corridorExit._enabled = true;
+ R2_GLOBALS._sceneItems.remove(&_gunpowder);
R2_GLOBALS.clearFlag(42);
- R2_GLOBALS.clearFlag(43);
- _fieldEAA = 1940;
+ R2_GLOBALS.setFlag(43);
+ _nextSceneMode1 = 1940;
// No break on purpose
case 1949:
- _sceneMode = _fieldEAA;
- if (_fieldEAC == 1943) {
- _fieldEAA = _fieldEAC;
- _fieldEAC = 0;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ _sceneMode = _nextSceneMode1;
+ if (_nextSceneMode2 == 1943) {
+ _nextSceneMode1 = _nextSceneMode2;
+ _nextSceneMode2 = 0;
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
- _fieldEAA = 0;
+ _nextSceneMode1 = 0;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
}
return;
@@ -12825,115 +13591,91 @@ void Scene1945::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1950 -
+ * Scene 1950 - Flup Tube Corridor Maze
*
*--------------------------------------------------------------------------*/
-Scene1950::Area1::Area1() {
- _field20 = 0;
- _fieldB65 = 0;
-}
-void Scene1950::Area1::synchronize(Serializer &s) {
- SceneArea::synchronize(s);
-
- s.syncAsByte(_field20);
- s.syncAsSint16LE(_fieldB65);
-}
-Scene1950::Scene1950() {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = Common::Point(0, 0);
- _field41C = 0;
+Scene1950::KeypadWindow::KeypadWindow() {
+ _buttonIndex = 0;
}
-void Scene1950::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
+void Scene1950::KeypadWindow::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418.x);
- s.syncAsSint16LE(_field418.y);
- s.syncAsSint16LE(_field41C);
+ s.syncAsSint16LE(_buttonIndex);
}
-Scene1950::Area1::Actor10::Actor10() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
+Scene1950::KeypadWindow::KeypadButton::KeypadButton() {
+ _buttonIndex = 0;
+ _pressed = false;
+ _toggled = false;
}
-void Scene1950::Area1::Actor10::synchronize(Serializer &s) {
+void Scene1950::KeypadWindow::KeypadButton::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
+ s.syncAsSint16LE(_buttonIndex);
+ s.syncAsSint16LE(_pressed);
+ s.syncAsSint16LE(_toggled);
}
-void Scene1950::Area1::Actor10::init(int indx) {
-// Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
+void Scene1950::KeypadWindow::KeypadButton::init(int indx) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- _fieldA4 = indx;
- _fieldA6 = 0;
- _fieldA8 = 0;
+ _buttonIndex = indx;
+ _pressed = false;
+ _toggled = false;
postInit();
setup(1971, 2, 1);
fixPriority(249);
- setPosition(Common::Point(((_fieldA4 / 4) * 22) + 127, ((_fieldA4 / 4) * 19) + 71));
- warning("FIXME: invalid call to scene->_sceneAreas.push_front(this);");
+ setPosition(Common::Point(((_buttonIndex % 4) * 22) + 127, ((_buttonIndex / 4) * 19) + 71));
+ scene->_sceneAreas.push_front(this);
}
-void Scene1950::Area1::Actor10::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos)) && (_fieldA6 == 0)) {
+void Scene1950::KeypadWindow::KeypadButton::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ && (_bounds.contains(event.mousePos)) && !_pressed) {
R2_GLOBALS._sound2.play(227);
- if (_fieldA8 == 0) {
+ if (!_toggled) {
setFrame(2);
- _fieldA8 = 1;
+ _toggled = true;
} else {
setFrame(1);
- _fieldA8 = 0;
+ _toggled = false;
}
- _fieldA6 = 1;
+ _pressed = true;
event.handled = true;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldA6 != 0)) {
- _fieldA6 = 0;
+ if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
+ _pressed = false;
event.handled = true;
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- scene->subBF4B4(_fieldA4);
+ scene->doButtonPress(_buttonIndex);
}
}
-bool Scene1950::Area1::Actor10::startAction(CursorType action, Event &event) {
+bool Scene1950::KeypadWindow::KeypadButton::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return false;
return SceneActor::startAction(action, event);
}
-void Scene1950::Area1::remove() {
+void Scene1950::KeypadWindow::remove() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- for (_fieldB65 = 0; _fieldB65 < 16; ++_fieldB65) {
- warning("Unexpected _sceneAreas.remove() call");
- // R2_GLOBALS._sceneAreas.remove(&_arrActor1[_fieldB65]);
- _arrActor1[_fieldB65].remove();
+ for (_buttonIndex = 0; _buttonIndex < 16; ++_buttonIndex) {
+ scene->_sceneAreas.remove(&_buttons[_buttonIndex]);
+ _buttons[_buttonIndex].remove();
}
- // sub201EA
- R2_GLOBALS._sceneItems.remove((SceneItem *)this);
- _areaActor.remove();
- SceneArea::remove();
- R2_GLOBALS._insetUp--;
- //
+ ModalWindow::remove();
if (!R2_GLOBALS.getFlag(37))
R2_GLOBALS._sound2.play(278);
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->_exit3._enabled = true;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ scene->_eastExit._enabled = true;
if (!R2_GLOBALS.getFlag(37)) {
if (R2_GLOBALS.getFlag(36)) {
@@ -12946,65 +13688,31 @@ void Scene1950::Area1::remove() {
}
}
-void Scene1950::Area1::process(Event &event) {
-// This is a copy of Scene1200::Area1::process
- if (_field20 != R2_GLOBALS._insetUp)
- return;
-
- CursorType cursor = R2_GLOBALS._events.getCursor();
-
- if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
- if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
- }
- } 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);
- remove();
- }
- }
-}
-
-void Scene1950::Area1::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+void Scene1950::KeypadWindow::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._player._canWalk = false;
- // UnkArea1200::proc12();
- _areaActor.postInit();
- _areaActor.setup(visage, stripFrameNum, frameNum);
- _areaActor.setPosition(Common::Point(posX, posY));
- _areaActor.fixPriority(250);
- _cursorNum = CURSOR_INVALID;
- scene->_sceneAreas.push_front(this);
- ++R2_GLOBALS._insetUp;
- _field20 = R2_GLOBALS._insetUp;
- //
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
- _areaActor.fixPriority(248);
- scene->_exit3._enabled = false;
- proc13(1950, 27, 28, 27);
+ _object1.fixPriority(248);
+ scene->_eastExit._enabled = false;
+ setup3(1950, 27, 28, 27);
- for (_fieldB65 = 0; _fieldB65 < 16; _fieldB65++)
- _arrActor1[_fieldB65].init(_fieldB65);
+ for (_buttonIndex = 0; _buttonIndex < 16; _buttonIndex++)
+ _buttons[_buttonIndex].init(_buttonIndex);
}
-void Scene1950::Area1::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- // Copy of Scene1200::Area1::proc13()
+void Scene1950::KeypadWindow::setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ // Copy of Scene1200::LaserPanel::proc13()
_areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
}
-bool Scene1950::Hotspot2::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+bool Scene1950::Keypad::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(37)))
return SceneHotspot::startAction(action, event);
@@ -13021,21 +13729,21 @@ bool Scene1950::Hotspot2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1950::Actor2::startAction(CursorType action, Event &event) {
+bool Scene1950::Door::startAction(CursorType action, Event &event) {
if (action != R2_SCRITH_KEY)
return SceneActor::startAction(action, event);
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(31, 0);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
scene->_sceneMode = 1958;
- scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
-bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(35) != 1950))
+bool Scene1950::Scrolls::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
return SceneActor::startAction(action, event);
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
@@ -13047,7 +13755,7 @@ bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1950::Actor5::startAction(CursorType action, Event &event) {
+bool Scene1950::Gem::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (!R2_GLOBALS.getFlag(37)))
return SceneActor::startAction(action, event);
@@ -13060,85 +13768,84 @@ bool Scene1950::Actor5::startAction(CursorType action, Event &event) {
return true;
}
-Scene1950::Actor8::Actor8() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
- _fieldAA = 0;
- _fieldAC = 0;
- _fieldAE = 0;
- _fieldAF = 0;
+/*--------------------------------------------------------------------------*/
+
+Scene1950::Vampire::Vampire() {
+ _deadPosition = Common::Point(0, 0);
+ _deltaX = 0;
+ _deltaY = 0;
+ _vampireMode = 0;
}
-void Scene1950::Actor8::synchronize(Serializer &s) {
+void Scene1950::Vampire::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
- s.syncAsSint16LE(_fieldAC);
- s.syncAsByte(_fieldAE);
- s.syncAsByte(_fieldAF);
+ s.syncAsSint16LE(_deadPosition.x);
+ s.syncAsSint16LE(_deadPosition.y);
+ s.syncAsSint16LE(_deltaX);
+ s.syncAsSint16LE(_deltaY);
+ s.syncAsSint16LE(_vampireMode);
}
-void Scene1950::Actor8::signal() {
+void Scene1950::Vampire::signal() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- switch (_fieldAC) {
+ switch (_vampireMode) {
case 19: {
- _fieldAC = 0;
+ _vampireMode = 0;
setVisage(1960);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
setStrip(2);
else
setStrip(1);
NpcMover *mover = new NpcMover();
- R2_GLOBALS._player.addMover(mover, &scene->_field418, this);
+ addMover(mover, &scene->_vampireDestPos, scene);
}
break;
case 20: {
- _fieldAC = 19;
+ // Non fatal shot
+ _vampireMode = 19;
R2_GLOBALS._player.setVisage(22);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
R2_GLOBALS._player.setStrip(1);
else
R2_GLOBALS._player.setStrip(2);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1]--;
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
- if (R2_GLOBALS._v566A5 == 3)
- _fieldA4 = _position.x + 10;
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ _deadPosition.x = _position.x + 10;
else
- _fieldA4 = _position.x - 10;
+ _deadPosition.x = _position.x - 10;
+ _deadPosition.y = _position.y - 4;
- _fieldA6 = _position.y -4;
setVisage(1961);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
setStrip(2);
else
setStrip(1);
animate(ANIM_MODE_2, NULL);
- Common::Point pt(_fieldA4, _fieldA6);
+ Common::Point pt = _deadPosition;
PlayerMover *mover = new PlayerMover();
addMover(mover, &pt, this);
R2_GLOBALS._player.enableControl();
}
break;
- case 21:
+ case 21: {
+ // Fatal shot
R2_GLOBALS._player.setVisage(22);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
R2_GLOBALS._player.setStrip(1);
else
R2_GLOBALS._player.setStrip(2);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
setVisage(1961);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
setStrip(4);
else
setStrip(3);
@@ -13148,47 +13855,49 @@ void Scene1950::Actor8::signal() {
R2_GLOBALS._sound2.play(226);
animate(ANIM_MODE_5, NULL);
fixPriority(10);
- R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) ]--;
- R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1]--;
- R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 2] = _position.x;
- R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 3] = _position.y;
- _fieldA8 = (_position.x - R2_GLOBALS._player._position.x) / 2;
- _fieldAA = (_position.y - R2_GLOBALS._player._position.y) / 2;
-
- _fieldAE = 0;
- for (_fieldAF = 0; _fieldAF < 18; ++_fieldAF)
- if (R2_GLOBALS._v56613[4 * _fieldAF] == 0)
- ++_fieldAE;
-
- if (_fieldAE == 18) {
+
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive = false;
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
+ R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._position = _position;
+ _deltaX = (_position.x - R2_GLOBALS._player._position.x) / 2;
+ _deltaY = (_position.y - R2_GLOBALS._player._position.y) / 2;
+
+ byte vampireCount = 0;
+ for (byte i = 0; i < 18; ++i) {
+ if (!R2_GLOBALS._vampireData[i]._isAlive)
+ ++vampireCount;
+ }
+
+ if (vampireCount == 18) {
R2_GLOBALS.setFlag(36);
- _fieldAC = 23;
- Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ _vampireMode = 23;
+ Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if (_fieldAE == 1) {
- _fieldAC = 22;
- Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ } else if (vampireCount == 1) {
+ _vampireMode = 22;
+ Common::Point pt(R2_GLOBALS._player._position.x + _deltaX, R2_GLOBALS._player._position.y + _deltaY);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
} else {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
}
- if (R2_GLOBALS._v566A5 == 3)
- scene->_exit3._enabled = true;
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
+ scene->_eastExit._enabled = true;
else
- scene->_exit6._enabled = true;
+ scene->_westExit._enabled = true;
- scene->_field416 = 0;
+ scene->_vampireActive = false;
+ }
break;
case 22:
- SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 23:
- SceneItem::display(1950, 25, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- scene->_sceneMode = R2_GLOBALS._v566A5;
+ SceneItem::display(1950, 25, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ scene->_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
scene->setAction(&scene->_sequenceManager, scene, 1960, &R2_GLOBALS._player, NULL);
break;
default:
@@ -13196,21 +13905,22 @@ void Scene1950::Actor8::signal() {
}
}
-bool Scene1950::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1950::Vampire::startAction(CursorType action, Event &event) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- if ((R2_GLOBALS._v56613[(scene->_field41C - 1) * 4] == 0) || (action != R2_PHOTON_STUNNER))
+ if (!R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive ||
+ (action != R2_PHOTON_STUNNER))
return SceneActor::startAction(action, event);
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._v56613[((scene->_field41C - 1) * 4) + 1] <= 1)
- _fieldAC = 21;
+ if (R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired <= 1)
+ _vampireMode = 21;
else
- _fieldAC = 20;
+ _vampireMode = 20;
R2_GLOBALS._player.setVisage(25);
- if (R2_GLOBALS._v566A5 == 3)
+ if (R2_GLOBALS._flubMazeEntryDirection == 3)
R2_GLOBALS._player.setStrip(2);
else
R2_GLOBALS._player.setStrip(1);
@@ -13220,12 +13930,14 @@ bool Scene1950::Actor8::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1950::Exit1::changeScene() {
+/*--------------------------------------------------------------------------*/
+
+void Scene1950::NorthExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 1;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 1;
scene->_sceneMode = 11;
Common::Point pt(160, 127);
@@ -13233,15 +13945,15 @@ void Scene1950::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1950::Exit2::changeScene() {
+void Scene1950::UpExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 2;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 2;
scene->_sceneMode = 12;
- if (scene->_field412 == 0) {
+ if (!scene->_upExitStyle) {
if (R2_GLOBALS.getFlag(36))
scene->setAction(&scene->_sequenceManager, scene, 1953, &R2_GLOBALS._player, NULL);
else
@@ -13254,15 +13966,15 @@ void Scene1950::Exit2::changeScene() {
}
}
-void Scene1950::Exit3::changeScene() {
+void Scene1950::EastExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 3;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 3;
scene->_sceneMode = 13;
- if (scene->_field416 != 0)
+ if (scene->_vampireActive)
R2_GLOBALS._player.animate(ANIM_MODE_9);
Common::Point pt(340, 160);
@@ -13270,12 +13982,12 @@ void Scene1950::Exit3::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1950::Exit4::changeScene() {
+void Scene1950::DownExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 4;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 4;
scene->_sceneMode = 14;
if (R2_GLOBALS.getFlag(36))
@@ -13284,12 +13996,12 @@ void Scene1950::Exit4::changeScene() {
scene->setAction(&scene->_sequenceManager, scene, 1973, &R2_GLOBALS._player, NULL);
}
-void Scene1950::Exit5::changeScene() {
+void Scene1950::SouthExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 5;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 5;
scene->_sceneMode = 15;
Common::Point pt(160, 213);
@@ -13297,30 +14009,32 @@ void Scene1950::Exit5::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1950::Exit6::changeScene() {
+void Scene1950::WestExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- 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)) {
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 6;
+
+ if (R2_GLOBALS._flubMazeArea == 2) {
+ // In the very first corridor area after the Scrith Door
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
scene->_sceneMode = 1961;
Common::Point pt(-20, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, scene);
} else {
if (!R2_GLOBALS.getFlag(36))
- SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- if ((R2_INVENTORY.getObjectScene(34) == 1950) || (R2_INVENTORY.getObjectScene(35) == 1950))
- SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ if ((R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 1950))
+ SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
scene->_sceneMode = 0;
Common::Point pt(30, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
} else {
- if (scene->_field416 != 0)
+ if (scene->_vampireActive)
R2_GLOBALS._player.animate(ANIM_MODE_9);
scene->_sceneMode = 16;
@@ -13330,28 +14044,28 @@ void Scene1950::Exit6::changeScene() {
}
}
-void Scene1950::Exit7::changeScene() {
+void Scene1950::ShaftExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 0;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 0;
scene->_sceneMode = 1951;
scene->setAction(&scene->_sequenceManager, scene, 1951, &R2_GLOBALS._player, NULL);
}
-void Scene1950::Exit8::changeScene() {
+void Scene1950::DoorExit::changeScene() {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A5 = 3;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
+ R2_GLOBALS._flubMazeEntryDirection = 3;
if (R2_GLOBALS._player._visage == 22) {
scene->_sceneMode = 1975;
scene->setAction(&scene->_sequenceManager, scene, 1975, &R2_GLOBALS._player, NULL);
} else {
- SceneItem::display(1950, 22, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- R2_GLOBALS._v566A5 = 0;
+ SceneItem::display(1950, 22, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._flubMazeEntryDirection = 0;
scene->_sceneMode = 0;
Common::Point pt(250, 150);
NpcMover *mover = new NpcMover();
@@ -13360,33 +14074,55 @@ void Scene1950::Exit8::changeScene() {
}
}
-void Scene1950::subBDC1E() {
- _exit1._enabled = false;
- _exit2._enabled = false;
- _exit3._enabled = false;
- _exit4._enabled = false;
- _exit5._enabled = false;
- _exit6._enabled = false;
- _exit7._enabled = false;
- _exit8._enabled = false;
- _exit1._insideArea = false;
- _exit2._insideArea = false;
- _exit3._insideArea = false;
- _exit4._insideArea = false;
- _exit5._insideArea = false;
- _exit6._insideArea = false;
- _exit7._insideArea = false;
- _exit8._insideArea = false;
- _exit1._moving = false;
- _exit2._moving = false;
- _exit3._moving = false;
- _exit4._moving = false;
- _exit5._moving = false;
- _exit6._moving = false;
- _exit7._moving = false;
- _exit8._moving = false;
- _field412 = 0;
- switch (R2_GLOBALS._v566A4 - 1) {
+/*--------------------------------------------------------------------------*/
+
+Scene1950::Scene1950() {
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
+ _vampireDestPos = Common::Point(0, 0);
+ _vampireIndex = 0;
+}
+
+void Scene1950::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_upExitStyle);
+ s.syncAsSint16LE(_removeFlag);
+ s.syncAsSint16LE(_vampireActive);
+ s.syncAsSint16LE(_vampireDestPos.x);
+ s.syncAsSint16LE(_vampireDestPos.y);
+ s.syncAsSint16LE(_vampireIndex);
+}
+
+void Scene1950::initArea() {
+ _northExit._enabled = false;
+ _upExit._enabled = false;
+ _eastExit._enabled = false;
+ _downExit._enabled = false;
+ _southExit._enabled = false;
+ _westExit._enabled = false;
+ _shaftExit._enabled = false;
+ _doorExit._enabled = false;
+ _northExit._insideArea = false;
+ _upExit._insideArea = false;
+ _eastExit._insideArea = false;
+ _downExit._insideArea = false;
+ _southExit._insideArea = false;
+ _westExit._insideArea = false;
+ _shaftExit._insideArea = false;
+ _doorExit._insideArea = false;
+ _northExit._moving = false;
+ _upExit._moving = false;
+ _eastExit._moving = false;
+ _downExit._moving = false;
+ _southExit._moving = false;
+ _westExit._moving = false;
+ _shaftExit._moving = false;
+ _doorExit._moving = false;
+ _upExitStyle = false;
+
+ switch (R2_GLOBALS._flubMazeArea - 1) {
case 0:
loadScene(1948);
break;
@@ -13611,25 +14347,25 @@ void Scene1950::subBDC1E() {
// No break on purpose
case 67:
loadScene(1985);
- _field412 = 1;
+ _upExitStyle = true;
break;
default:
break;
}
- if (R2_GLOBALS._v566A4 != 1)
+ if (R2_GLOBALS._flubMazeArea != 1)
R2_GLOBALS._walkRegions.load(1950);
- switch (R2_GLOBALS._v566A4 - 1) {
+ switch (R2_GLOBALS._flubMazeArea - 1) {
case 0:
- _exit7._enabled = true;
- if ((R2_INVENTORY.getObjectScene(31) == 0) && (R2_INVENTORY.getObjectScene(34) == 1950))
- _exit8._enabled = true;
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(4);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
+ _shaftExit._enabled = true;
+ if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
+ _doorExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
break;
case 1:
// No break on purpose
@@ -13694,8 +14430,8 @@ void Scene1950::subBDC1E() {
case 102:
// No break on purpose
case 103:
- _exit3._enabled = true;
- _exit6._enabled = true;
+ _eastExit._enabled = true;
+ _westExit._enabled = true;
break;
case 4:
// No break on purpose
@@ -13746,9 +14482,9 @@ void Scene1950::subBDC1E() {
case 100:
// No break on purpose
case 104:
- _exit6._enabled = true;
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(9);
+ _westExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(9);
break;
case 5:
// No break on purpose
@@ -13797,25 +14533,25 @@ void Scene1950::subBDC1E() {
case 99:
// No break on purpose
case 101:
- _exit3._enabled = true;
- R2_GLOBALS._walkRegions.enableRegion(1);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._walkRegions.enableRegion(13);
+ _eastExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(13);
break;
default:
- R2_GLOBALS._walkRegions.enableRegion(1);
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._walkRegions.enableRegion(9);
- R2_GLOBALS._walkRegions.enableRegion(13);
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ R2_GLOBALS._walkRegions.disableRegion(13);
break;
}
- _object1.remove();
- _object1.removeObject();
- _actor1.remove();
+ _northDoorway.remove();
+ _northDoorway.removeObject();
+ _southDoorway.remove();
- switch (R2_GLOBALS._v566A4 - 4) {
+ switch (R2_GLOBALS._flubMazeArea - 4) {
case 0:
// No break on purpose
case 3:
@@ -13853,17 +14589,17 @@ void Scene1950::subBDC1E() {
case 82:
// No break on purpose
case 90:
- _exit1._enabled = true;
- _object1.setup2(1950, (R2_GLOBALS._v566A4 % 2) + 1, 1, 160, 237, 25, 0);
-
- _actor1.postInit();
- _actor1.setVisage(1950);
- _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
- _actor1.setFrame(2);
- _actor1.setPosition(Common::Point(160, 167));
- _actor1.fixPriority(220);
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(4);
+ _northExit._enabled = true;
+ _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
+ //visage,strip,frame,px,py,priority,effect
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(2);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
break;
case 7:
// No break on purpose
@@ -13902,44 +14638,45 @@ void Scene1950::subBDC1E() {
case 89:
// No break on purpose
case 97:
- _exit5._enabled = true;
- _actor1.postInit();
- _actor1.setVisage(1950);
- _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
- _actor1.setFrame(3);
- _actor1.setPosition(Common::Point(160, 167));
- _actor1.fixPriority(220);
+ _southExit._enabled = true;
+
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(3);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
break;
case 58:
// No break on purpose
case 74:
// No break on purpose
case 80:
- _exit1._enabled = true;
- _exit5._enabled = true;
+ _northExit._enabled = true;
+ _southExit._enabled = true;
- _object1.setup(1950, (R2_GLOBALS._v566A4 % 2) + 1, 1, 160, 137, 25);
+ _northDoorway.setup(1950, (R2_GLOBALS._flubMazeArea % 2) + 1, 1, 160, 137, 25);
- _actor1.postInit();
- _actor1.setVisage(1950);
- _actor1.setStrip((((R2_GLOBALS._v566A4 - 1) / 35) % 2) + 1);
- _actor1.setFrame(3);
- _actor1.setPosition(Common::Point(160, 167));
- _actor1.fixPriority(220);
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(4);
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip((((R2_GLOBALS._flubMazeArea - 1) / 35) % 2) + 1);
+ _southDoorway.setFrame(3);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
break;
default:
- _actor1.postInit();
- _actor1.setVisage(1950);
- _actor1.setStrip(((R2_GLOBALS._v566A4 - 1) % 35) + 1);
- _actor1.setFrame(2);
- _actor1.setPosition(Common::Point(160, 167));
- _actor1.fixPriority(220);
+ _southDoorway.postInit();
+ _southDoorway.setVisage(1950);
+ _southDoorway.setStrip(((R2_GLOBALS._flubMazeArea - 1) / 35) % 2 + 1);
+ _southDoorway.setFrame(2);
+ _southDoorway.setPosition(Common::Point(160, 167));
+ _southDoorway.fixPriority(220);
break;
}
- switch (R2_GLOBALS._v566A4 - 3) {
+ switch (R2_GLOBALS._flubMazeArea - 3) {
case 0:
// No break on purpose
case 3:
@@ -13983,7 +14720,8 @@ void Scene1950::subBDC1E() {
case 60:
// No break on purpose
case 63:
- _exit2._enabled = true;
+ _upExit._enabled = true;
+ break;
case 54:
// No break on purpose
case 61:
@@ -13991,7 +14729,7 @@ void Scene1950::subBDC1E() {
case 62:
// No break on purpose
case 65:
- _exit2._enabled = true;
+ _upExit._enabled = true;
// No break on purpose
case 35:
// No break on purpose
@@ -14036,206 +14774,214 @@ void Scene1950::subBDC1E() {
case 98:
// No break on purpose
case 100:
- _exit4._enabled = true;
- R2_GLOBALS._walkRegions.enableRegion(4);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(10);
- R2_GLOBALS._walkRegions.enableRegion(11);
+ _downExit._enabled = true;
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(10);
+ R2_GLOBALS._walkRegions.disableRegion(11);
default:
break;
}
R2_GLOBALS._uiElements.draw();
}
-void Scene1950::subBE59B() {
+void Scene1950::enterArea() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- _actor8.remove();
- _actor2.remove();
- _actor3.remove();
+ _vampire.remove();
+ _door.remove();
+ _scrolls.remove();
- _field416 = 0;
- _field41C = 0;
+ _vampireActive = false;
+ _vampireIndex = 0;
- switch (R2_GLOBALS._v566A4) {
+ // Certain areas have a vampire in them
+ switch (R2_GLOBALS._flubMazeArea) {
case 10:
- _field41C = 1;
+ _vampireIndex = 1;
break;
case 13:
- _field41C = 2;
+ _vampireIndex = 2;
break;
case 16:
- _field41C = 3;
+ _vampireIndex = 3;
break;
case 17:
- _field41C = 4;
+ _vampireIndex = 4;
break;
case 24:
- _field41C = 5;
+ _vampireIndex = 5;
break;
case 25:
- _field41C = 6;
+ _vampireIndex = 6;
break;
case 31:
- _field41C = 7;
+ _vampireIndex = 7;
break;
case 40:
- _field41C = 8;
+ _vampireIndex = 8;
break;
case 45:
- _field41C = 9;
+ _vampireIndex = 9;
break;
case 46:
- _field41C = 10;
+ _vampireIndex = 10;
break;
case 73:
- _field41C = 11;
+ _vampireIndex = 11;
break;
case 75:
- _field41C = 12;
+ _vampireIndex = 12;
break;
case 80:
- _field41C = 13;
+ _vampireIndex = 13;
break;
case 87:
- _field41C = 14;
+ _vampireIndex = 14;
break;
case 88:
- _field41C = 15;
+ _vampireIndex = 15;
break;
case 96:
- _field41C = 16;
+ _vampireIndex = 16;
break;
case 97:
- _field41C = 17;
+ _vampireIndex = 17;
break;
case 104:
- _field41C = 18;
+ _vampireIndex = 18;
break;
default:
break;
}
- if (_field41C != 0) {
- _actor8.postInit();
- _actor8._numFrames = 6;
- _actor8._moveRate = 6;
- _actor8._moveDiff = Common::Point(3, 2);
- _actor8._effect = 1;
- if (R2_GLOBALS._v56613[(_field41C - 1) * 4] == 0) {
- _actor8.setPosition(Common::Point(R2_GLOBALS._v56613[((_field41C - 1) * 4) + 2], R2_GLOBALS._v56613[((_field41C - 1) * 4) + 3]));
- _actor8.animate(ANIM_MODE_NONE, NULL);
- _actor8.addMover(NULL);
- _actor8.setVisage(1961);
- _actor8.setStrip(4);
- _actor8.setFrame(10);
- _actor8.fixPriority(10);
- _actor8.setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
+ if (_vampireIndex != 0) {
+ _vampire.postInit();
+ _vampire._numFrames = 6;
+ _vampire._moveRate = 6;
+ _vampire._moveDiff = Common::Point(3, 2);
+ _vampire._effect = EFFECT_SHADED;
+
+ if (!R2_GLOBALS._vampireData[_vampireIndex - 1]._isAlive) {
+ // Show vampire ashes
+ _vampire.setPosition(Common::Point(R2_GLOBALS._vampireData[_vampireIndex - 1]._position));
+ _vampire.animate(ANIM_MODE_NONE, NULL);
+ _vampire.addMover(NULL);
+ _vampire.setVisage(1961);
+ _vampire.setStrip(4);
+ _vampire.setFrame(10);
+ _vampire.fixPriority(10);
+ _vampire.setDetails(1950, 15, -1, 17, 2, (SceneItem *) NULL);
} else {
- _actor8.setVisage(1960);
- _actor8.setPosition(Common::Point(160, 130));
- _actor8.animate(ANIM_MODE_2, NULL);
- _actor8.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
- _field416 = 1;
+ // Start the vampire
+ _vampire.setVisage(1960);
+ _vampire.setPosition(Common::Point(160, 130));
+ _vampire.animate(ANIM_MODE_2, NULL);
+ _vampire.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
+ _vampireActive = true;
}
}
- if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(31) != 0)) {
- _actor2.postInit();
- _actor2.setVisage(1948);
- _actor2.setStrip(3);
- _actor2.setPosition(Common::Point(278, 155));
- _actor2.fixPriority(100);
- _actor2.setDetails(1950, 19, 20, 23, 2, (SceneItem *) NULL);
+ if ((R2_GLOBALS._flubMazeArea == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
+ // Show doorway at the right hand side of the very first flub corridor
+ _door.postInit();
+ _door.setVisage(1948);
+ _door.setStrip(3);
+ _door.setPosition(Common::Point(278, 155));
+ _door.fixPriority(100);
+ _door.setDetails(1950, 19, 20, 23, 2, (SceneItem *) NULL);
}
- if (R2_GLOBALS._v566A4 == 102) {
+ if (R2_GLOBALS._flubMazeArea == 102) {
R2_GLOBALS._walkRegions.load(1951);
- R2_GLOBALS._walkRegions.enableRegion(1);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(7);
-
- _actor6.postInit();
- _actor6.setVisage(1970);
- _actor6.setStrip(1);
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+
+ _cube.postInit();
+ _cube.setVisage(1970);
+ _cube.setStrip(1);
if (R2_GLOBALS.getFlag(37))
- _actor6.setFrame(3);
+ _cube.setFrame(3);
else
- _actor6.setFrame(1);
- _actor6.setPosition(Common::Point(193, 158));
- _actor6.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
+ _cube.setFrame(1);
+ _cube.setPosition(Common::Point(193, 158));
+ _cube.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
- _actor7.postInit();
- _actor7.setVisage(1970);
- _actor7.setStrip(3);
- _actor7.animate(ANIM_MODE_2, NULL);
- _actor7._numFrames = 6;
- _actor7.setPosition(Common::Point(194, 158));
- _actor7.fixPriority(159);
+ _pulsingLights.postInit();
+ _pulsingLights.setVisage(1970);
+ _pulsingLights.setStrip(3);
+ _pulsingLights.animate(ANIM_MODE_2, NULL);
+ _pulsingLights._numFrames = 6;
+ _pulsingLights.setPosition(Common::Point(194, 158));
+ _pulsingLights.fixPriority(159);
- _item2.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
+ _keypad.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
- if (R2_INVENTORY.getObjectScene(34) == 1950) {
- _actor5.postInit();
- _actor5.setVisage(1970);
- _actor5.setStrip(1);
- _actor5.setFrame(2);
- _actor5.fixPriority(160);
+ if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
+ _gem.postInit();
+ _gem.setVisage(1970);
+ _gem.setStrip(1);
+ _gem.setFrame(2);
+ _gem.fixPriority(160);
}
if (R2_GLOBALS.getFlag(37)) {
- _actor5.setPosition(Common::Point(192, 118));
- _actor5.setDetails(1950, 9, 4, -1, 2, (SceneItem *) NULL);
+ _gem.setPosition(Common::Point(192, 118));
+ _gem.setDetails(1950, 9, 4, -1, 2, (SceneItem *) NULL);
} else {
- _actor4.postInit();
- _actor4.setVisage(1970);
- _actor4.setStrip(4);
- _actor4._numFrames = 4;
- _actor4.animate(ANIM_MODE_8, NULL);
- _actor4.setPosition(Common::Point(192, 121));
- _actor4.fixPriority(159);
- _actor4.setDetails(1950, 6, 7, 8, 2, (SceneItem *) NULL);
-
- _actor5.setPosition(Common::Point(192, 109));
- _actor5.setDetails(1950, 9, 7, 8, 2, (SceneItem *) NULL);
- }
-
- _actor3.postInit();
- _actor3.setVisage(1972);
- _actor3.setStrip(1);
- _actor3.setPosition(Common::Point(76, 94));
- _actor3.fixPriority(25);
- _actor3.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(35) == 2)
- _actor3.setFrame(2);
+ _containmentField.postInit();
+ _containmentField.setVisage(1970);
+ _containmentField.setStrip(4);
+ _containmentField._numFrames = 4;
+ _containmentField.animate(ANIM_MODE_8, 0, NULL);
+ _containmentField.setPosition(Common::Point(192, 121));
+ _containmentField.fixPriority(159);
+ _containmentField.setDetails(1950, 6, 7, 8, 2, (SceneItem *) NULL);
+
+ _gem.setPosition(Common::Point(192, 109));
+ _gem.setDetails(1950, 9, 7, 8, 2, (SceneItem *) NULL);
+ }
+
+ _scrolls.postInit();
+ _scrolls.setVisage(1972);
+ _scrolls.setStrip(1);
+ _scrolls.setPosition(Common::Point(76, 94));
+ _scrolls.fixPriority(25);
+ _scrolls.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
+ _scrolls.setFrame(2);
else
- _actor3.setFrame(1);
+ _scrolls.setFrame(1);
- _field414 = 1;
- } else if (_field414 != 0) {
- _actor6.remove();
- _actor4.remove();
- _actor5.remove();
- _actor7.remove();
- _actor3.remove();
+ _removeFlag = true;
+ } else if (_removeFlag) {
+ _cube.remove();
+ _containmentField.remove();
+ _gem.remove();
+ _pulsingLights.remove();
+ _scrolls.remove();
- _item1.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 2, NULL);
+ R2_GLOBALS._sceneItems.remove(&_background);
+ _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 2, NULL);
+
+ _removeFlag = false;
}
- switch (R2_GLOBALS._v566A5) {
+ switch (R2_GLOBALS._flubMazeEntryDirection) {
case 0:
_sceneMode = 1950;
- if (R2_INVENTORY.getObjectScene(31) == 0) {
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- } else {
+ if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)
+ // The original uses CURSOR_ARROW. CURSOR_WALK is much more coherent
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ else
setAction(&_sequenceManager, this, 1950, &R2_GLOBALS._player, NULL);
- }
+
break;
case 1: {
- _sceneMode = R2_GLOBALS._v566A5;
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
R2_GLOBALS._player.setPosition(Common::Point(160, 213));
Common::Point pt(160, 160);
NpcMover *mover = new NpcMover();
@@ -14243,30 +14989,30 @@ void Scene1950::subBE59B() {
}
break;
case 2:
- _sceneMode = R2_GLOBALS._v566A5;
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
if (R2_GLOBALS.getFlag(36))
setAction(&_sequenceManager, this, 1957, &R2_GLOBALS._player, NULL);
else
setAction(&_sequenceManager, this, 1974, &R2_GLOBALS._player, NULL);
break;
case 3:
- if (_field416 == 0) {
- _sceneMode = R2_GLOBALS._v566A5;
+ // Entering from the left
+ if (!_vampireActive) {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
Common::Point pt(30, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
} else {
_sceneMode = 18;
- _exit3._enabled = false;
- _field418 = Common::Point(60, 152);
- R2_GLOBALS._v56AAB = 0;
+ _eastExit._enabled = false;
+ _vampireDestPos = Common::Point(60, 152);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _actor8.setStrip(2);
+ _vampire.setStrip(2);
NpcMover *mover = new NpcMover();
- _actor8.addMover(mover, &_field418, this);
+ _vampire.addMover(mover, &_vampireDestPos, this);
R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
Common::Point pt2(30, 160);
@@ -14275,8 +15021,8 @@ void Scene1950::subBE59B() {
}
break;
case 4:
- _sceneMode = R2_GLOBALS._v566A5;
- if (_field412 == 0) {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ if (!_upExitStyle) {
if (R2_GLOBALS.getFlag(36))
setAction(&_sequenceManager, this, 1955, &R2_GLOBALS._player, NULL);
else
@@ -14289,7 +15035,7 @@ void Scene1950::subBE59B() {
}
break;
case 5: {
- _sceneMode = R2_GLOBALS._v566A5;
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
R2_GLOBALS._player.setPosition(Common::Point(160, 127));
Common::Point pt(160, 160);
NpcMover *mover = new NpcMover();
@@ -14297,9 +15043,10 @@ void Scene1950::subBE59B() {
}
break;
case 6:
- if (_field416 == 0) {
- _sceneMode = R2_GLOBALS._v566A5;
- if (R2_GLOBALS._v566A4 == 1) {
+ // Entering from the right
+ if (!_vampireActive) {
+ _sceneMode = R2_GLOBALS._flubMazeEntryDirection;
+ if (R2_GLOBALS._flubMazeArea == 1) {
setAction(&_sequenceManager, this, 1961, &R2_GLOBALS._player, NULL);
} else {
R2_GLOBALS._player.setPosition(Common::Point(340, 160));
@@ -14309,16 +15056,15 @@ void Scene1950::subBE59B() {
}
} else {
_sceneMode = 17;
- _exit6._enabled = false;
- _field418 = Common::Point(259, 152);
+ _westExit._enabled = false;
+ _vampireDestPos = Common::Point(259, 152);
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _actor8.setStrip(1);
+ _vampire.setStrip(1);
NpcMover *mover = new NpcMover();
- _actor8.addMover(mover, &_field418, this);
+ _vampire.addMover(mover, &_vampireDestPos, this);
R2_GLOBALS._player.setPosition(Common::Point(340, 160));
Common::Point pt2(289, 160);
@@ -14331,65 +15077,74 @@ void Scene1950::subBE59B() {
}
}
-void Scene1950::subBF4B4(int indx) {
+void Scene1950::doButtonPress(int indx) {
+ Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- int si = indx - 1;
- if ((indx / 4) == (si / 4)) {
- if (si < 0)
- si = 3;
- } else
- si = 4;
- if (_area1._arrActor1[si]._fieldA8 == 0) {
- _area1._arrActor1[si].setFrame(2);
- _area1._arrActor1[si]._fieldA8 = 1;
+ int prevIndex = indx - 1;
+ if ((indx / 4) == (prevIndex / 4)) {
+ if (prevIndex < 0)
+ prevIndex = 3;
} else {
- _area1._arrActor1[si].setFrame(1);
- _area1._arrActor1[si]._fieldA8 = 0;
+ prevIndex += 4;
}
- si = indx + 1;
- if ((indx / 4) == (si / 4)) {
- if (si > 15)
- si = 12;
- } else
- si -= 4;
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
- if (_area1._arrActor1[si]._fieldA8 == 0) {
- _area1._arrActor1[si].setFrame(2);
- _area1._arrActor1[si]._fieldA8 = 1;
+ prevIndex = indx + 1;
+ if ((indx / 4) == (prevIndex / 4)) {
+ if (prevIndex > 15)
+ prevIndex = 12;
} else {
- _area1._arrActor1[si].setFrame(1);
- _area1._arrActor1[si]._fieldA8 = 0;
+ prevIndex -= 4;
}
- si = indx - 4;
- if (si < 0)
- si += 16;
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
+ } else {
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
+ }
+
+ prevIndex = indx - 4;
+ if (prevIndex < 0)
+ prevIndex += 16;
- if (_area1._arrActor1[si]._fieldA8 == 0) {
- _area1._arrActor1[si].setFrame(2);
- _area1._arrActor1[si]._fieldA8 = 1;
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
} else {
- _area1._arrActor1[si].setFrame(1);
- _area1._arrActor1[si]._fieldA8 = 0;
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
}
- si = indx + 4;
- if (si > 15)
- si -= 16;
+ prevIndex = indx + 4;
+ if (prevIndex > 15)
+ prevIndex -= 16;
- if (_area1._arrActor1[si]._fieldA8 == 0) {
- _area1._arrActor1[si].setFrame(2);
- _area1._arrActor1[si]._fieldA8 = 1;
+ assert(prevIndex >= 0 && prevIndex < 16);
+ if (!_KeypadWindow._buttons[prevIndex]._toggled) {
+ _KeypadWindow._buttons[prevIndex].setFrame(2);
+ _KeypadWindow._buttons[prevIndex]._toggled = true;
} else {
- _area1._arrActor1[si].setFrame(1);
- _area1._arrActor1[si]._fieldA8 = 0;
+ _KeypadWindow._buttons[prevIndex].setFrame(1);
+ _KeypadWindow._buttons[prevIndex]._toggled = false;
}
+ // Check whether all the buttons are highlighted
int cpt = 0;
- for (si = 0; si < 16; si++) {
- if (_area1._arrActor1[si]._fieldA8 != 0)
+ for (prevIndex = 0; prevIndex < 16; prevIndex++) {
+ if (_KeypadWindow._buttons[prevIndex]._toggled)
++cpt;
}
@@ -14399,59 +15154,57 @@ void Scene1950::subBF4B4(int indx) {
} else {
R2_GLOBALS.setFlag(37);
_sceneMode = 24;
- // TODO: check if correct. The original doesn't countain a sceneActor in
- // this call, but it's extremely unusual
- setAction(&_sequenceManager, this, 1976, NULL);
+ setAction(&_sequenceManager, scene, 1976, NULL);
}
}
void Scene1950::postInit(SceneObjectList *OwnerList) {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field41C = 0;
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
+ _vampireIndex = 0;
if (R2_GLOBALS._sceneManager._previousScene == 300)
- R2_GLOBALS._v566A4 = 103;
+ R2_GLOBALS._flubMazeArea = 103;
- subBDC1E();
+ initArea();
SceneExt::postInit();
R2_GLOBALS._sound1.play(105);
- _exit1.setDetails(Rect(130, 46, 189, 135), SHADECURSOR_UP, 1950);
- _exit1.setDest(Common::Point(160, 145));
+ _northExit.setDetails(Rect(130, 46, 189, 135), SHADECURSOR_UP, 1950);
+ _northExit.setDest(Common::Point(160, 145));
- _exit2.setDetails(Rect(208, 0, 255, 73), EXITCURSOR_N, 1950);
- _exit2.setDest(Common::Point(200, 151));
+ _upExit.setDetails(Rect(208, 0, 255, 73), EXITCURSOR_N, 1950);
+ _upExit.setDest(Common::Point(200, 151));
- _exit3.setDetails(Rect(305, 95, 320, 147), EXITCURSOR_E, 1950);
- _exit3.setDest(Common::Point(312, 160));
+ _eastExit.setDetails(Rect(305, 95, 320, 147), EXITCURSOR_E, 1950);
+ _eastExit.setDest(Common::Point(312, 160));
- _exit4.setDetails(Rect(208, 99, 255, 143), EXITCURSOR_S, 1950);
- _exit4.setDest(Common::Point(200, 151));
+ _downExit.setDetails(Rect(208, 99, 255, 143), EXITCURSOR_S, 1950);
+ _downExit.setDest(Common::Point(200, 151));
- _exit5.setDetails(Rect(113, 154, 206, 168), SHADECURSOR_DOWN, 1950);
- _exit5.setDest(Common::Point(160, 165));
+ _southExit.setDetails(Rect(113, 154, 206, 168), SHADECURSOR_DOWN, 1950);
+ _southExit.setDest(Common::Point(160, 165));
- _exit6.setDetails(Rect(0, 95, 14, 147), EXITCURSOR_W, 1950);
- _exit6.setDest(Common::Point(7, 160));
+ _westExit.setDetails(Rect(0, 95, 14, 147), EXITCURSOR_W, 1950);
+ _westExit.setDest(Common::Point(7, 160));
- _exit7.setDetails(Rect(72, 54, 120, 128), EXITCURSOR_NW, 1950);
- _exit7.setDest(Common::Point(120, 140));
+ _shaftExit.setDetails(Rect(72, 54, 120, 128), EXITCURSOR_NW, 1950);
+ _shaftExit.setDest(Common::Point(120, 140));
- _exit8.setDetails(Rect(258, 60, 300, 145), EXITCURSOR_NE, 1950);
- _exit8.setDest(Common::Point(268, 149));
+ _doorExit.setDetails(Rect(258, 60, 300, 145), EXITCURSOR_NE, 1950);
+ _doorExit.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);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- _item1.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1950, 0, 1, 2, 1, NULL);
- subBE59B();
+ enterArea();
}
void Scene1950::remove() {
@@ -14463,45 +15216,50 @@ void Scene1950::remove() {
void Scene1950::signal() {
switch (_sceneMode) {
case 11:
- R2_GLOBALS._v566A4 += 7;
- subBDC1E();
- subBE59B();
+ R2_GLOBALS._flubMazeArea += 7;
+ initArea();
+ enterArea();
break;
case 12:
- R2_GLOBALS._v566A4 += 35;
- subBDC1E();
- subBE59B();
+ // Moving up a ladder within the Flub maze
+ R2_GLOBALS._flubMazeArea += 35;
+ initArea();
+ enterArea();
break;
case 1975:
- SceneItem::display(1950, 21, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1950, 21, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1,
+ SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
// No break on purpose
case 13:
- ++R2_GLOBALS._v566A4;
- subBDC1E();
- subBE59B();
+ // Moving east within the Flub maze
+ ++R2_GLOBALS._flubMazeArea;
+ initArea();
+ enterArea();
break;
case 14:
- R2_GLOBALS._v566A4 += 221;
- subBDC1E();
- subBE59B();
+ // Moving down a ladder within the Flub maze
+ R2_GLOBALS._flubMazeArea -= 35;
+ initArea();
+ enterArea();
break;
case 15:
- R2_GLOBALS._v566A4 += 249;
- subBDC1E();
- subBE59B();
+ R2_GLOBALS._flubMazeArea -= 7;
+ initArea();
+ enterArea();
break;
case 16:
+ // Moving west within the Flub maze
// No break on purpose
case 1961:
- --R2_GLOBALS._v566A4;
- subBDC1E();
- subBE59B();
+ --R2_GLOBALS._flubMazeArea;
+ initArea();
+ enterArea();
break;
case 17: {
_sceneMode = 13;
- R2_GLOBALS._v566A5 = 3;
- _field416 = 0;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._flubMazeEntryDirection = 3;
+ _vampireActive = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
R2_GLOBALS._player._canWalk = true;
R2_GLOBALS._player.setVisage(22);
R2_GLOBALS._player.animate(ANIM_MODE_9, NULL);
@@ -14510,14 +15268,14 @@ void Scene1950::signal() {
R2_GLOBALS._player.addMover(mover, &pt, this);
Common::Point pt2(289, 160);
NpcMover *mover2 = new NpcMover();
- _actor8.addMover(mover2, &pt2, NULL);
+ _vampire.addMover(mover2, &pt2, NULL);
}
break;
case 18: {
_sceneMode = 16;
- R2_GLOBALS._v566A5 = 6;
- _field416 = 0;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._flubMazeEntryDirection = 6;
+ _vampireActive = false;
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
R2_GLOBALS._player._canWalk = true;
R2_GLOBALS._player.setVisage(22);
R2_GLOBALS._player.animate(ANIM_MODE_9, NULL);
@@ -14526,47 +15284,45 @@ void Scene1950::signal() {
R2_GLOBALS._player.addMover(mover, &pt, this);
Common::Point pt2(30, 160);
NpcMover *mover2 = new NpcMover();
- _actor8.addMover(mover2, &pt2, NULL);
+ _vampire.addMover(mover2, &pt2, NULL);
}
break;
case 24:
- _area1.remove();
+ _KeypadWindow.remove();
_sceneMode = 1966;
- _actor6.setFrame(3);
- setAction(&_sequenceManager, this, 1966, &_actor4, &_actor5, NULL);
+ _cube.setFrame(3);
+ setAction(&_sequenceManager, this, 1966, &_containmentField, &_gem, NULL);
break;
case 1951:
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._sceneManager.changeScene(1945);
break;
case 1958:
- SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _exit8._enabled = true;
+ SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ _doorExit._enabled = true;
break;
case 1959:
- R2_INVENTORY.setObjectScene(46, 0);
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _exit8._enabled = true;
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ _doorExit._enabled = true;
break;
case 1962:
// No break on purpose
case 1963:
R2_GLOBALS._player.enableControl();
- _area1.proc12(1971, 1, 1, 160, 135);
+ _KeypadWindow.setup2(1971, 1, 1, 160, 135);
break;
case 1964:
// No break on purpose
case 1965:
- if (!R2_GLOBALS.getFlag(37)) {
- SceneItem::display(1950, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- R2_GLOBALS._player.enableControl();
- }
+ if (!R2_GLOBALS.getFlag(37))
+ SceneItem::display(1950, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
+
+ R2_GLOBALS._player.enableControl();
break;
case 1966:
- _actor4.remove();
+ _containmentField.remove();
if (R2_GLOBALS.getFlag(36)) {
_sceneMode = 1964;
setAction(&_sequenceManager, this, 1964, &R2_GLOBALS._player, NULL);
@@ -14574,26 +15330,28 @@ void Scene1950::signal() {
_sceneMode = 1965;
setAction(&_sequenceManager, this, 1965, &R2_GLOBALS._player, NULL);
}
- _actor5.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
+ _gem.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
+ break;
case 1967: {
_sceneMode = 0;
- R2_INVENTORY.setObjectScene(34, 2);
- _actor5.remove();
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
+ _gem.remove();
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
else
R2_GLOBALS._player.setVisage(22);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- Common::Point pt(218, 165);
+ // This is a hack to work around a pathfinding issue. original destination is (218, 165)
+ Common::Point pt(128, 165);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 1968:
- R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(35, 2);
- _actor3.setFrame(2);
+ R2_GLOBALS._player.enableControl();
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
+ _scrolls.setFrame(2);
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
else
@@ -14601,25 +15359,25 @@ void Scene1950::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
break;
default:
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
void Scene1950::process(Event &event) {
if ( (event.eventType == EVENT_BUTTON_DOWN)
- && (R2_GLOBALS._player._uiEnabled)
- && (R2_GLOBALS._events.getCursor() == R2_LIGHT_BULB)
- && (R2_GLOBALS._player._bounds.contains(event.mousePos))
- && (R2_INVENTORY.getObjectScene(31) == 0)) {
+ && (R2_GLOBALS._player._uiEnabled)
+ && (R2_GLOBALS._events.getCursor() == R2_SOAKED_FACEMASK)
+ && (R2_GLOBALS._player._bounds.contains(event.mousePos))
+ && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
event.handled = true;
R2_GLOBALS._player.disableControl();
- _exit7._enabled = false;
- _exit8._enabled = false;
+ _shaftExit._enabled = false;
+ _doorExit._enabled = false;
_sceneMode = 1959;
setAction(&_sequenceManager, this, 1959, &R2_GLOBALS._player, NULL);
}
+
Scene::process(event);
}
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index f65a89972d..28b82b4045 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,52 +75,52 @@ 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;
ScenePalette _palette1;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- 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;
- BackgroundSceneObject _object2;
- Actor16 _actor16;
- Actor17 _actor17;
- Actor18 _actor18;
+ NamedHotspot _background;
+ NamedHotspot _sky;
+ NamedHotspot _fuana1;
+ NamedHotspot _fauna2;
+ NamedHotspot _bouldersBlockingCave;
+ NamedHotspot _boulders;
+ NamedHotspot _trail;
+ SceneActor _ship;
+ SceneActor _cloud;
+ SceneActor _shipFormation;
+ SceneActor _shipFormationShadow;
+ SceneActor _shotImpact1;
+ SceneActor _shotImpact2;
+ SceneActor _shotImpact3;
+ SceneActor _shotImpact4;
+ SceneActor _shotImpact5;
+ SceneActor _laserShot;
+ SceneActor _animation; // Used for cliff collapse and ship theft
+ SceneActor _leftImpacts;
+ SceneActor _runningGuy1;
+ SceneActor _runningGuy2;
+ SceneActor _runningGuy3;
+ BackgroundSceneObject _rightLandslide;
+ BackgroundSceneObject _purplePlant;
+ Seeker _seeker;
+ Trooper _trooper;
+ Chief _chief;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
@@ -118,49 +136,44 @@ public:
};
class Scene1200 : public SceneExt {
- class Area1: public SceneArea {
+ enum CrawlDirection { CRAWL_EAST = 1, CRAWL_WEST = 2, CRAWL_SOUTH = 3, CRAWL_NORTH = 4 };
+
+ class LaserPanel: public ModalWindow {
public:
- class Actor3 : public SceneActorExt {
+ class Jumper : public SceneActorExt {
public:
void init(int state);
virtual bool startAction(CursorType action, Event &event);
};
- SceneActor _actor2;
- Actor3 _actor3;
- Actor3 _actor4;
- Actor3 _actor5;
-
- byte _field20;
+ Jumper _jumper1;
+ Jumper _jumper2;
+ Jumper _jumper3;
- Area1();
- void synchronize(Serializer &s);
+ LaserPanel();
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:
NamedHotspot _item1;
SceneActor _actor1;
- Area1 _area1;
- UnkObject1200 _object1;
+ LaserPanel _laserPanel;
+ MazeUI _mazeUI;
SequenceManager _sequenceManager;
- int _field412;
+ int _nextCrawlDirection;
int _field414;
int _field416;
int _field418;
int _field41A;
- int _field41C;
+ bool _fixupMaze;
Scene1200();
void synchronize(Serializer &s);
- void sub9DAD6(int indx);
+ void startCrawling(CrawlDirection dir);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -172,10 +185,10 @@ public:
class Scene1337 : public SceneExt {
class unkObj1337sub1: public SceneHotspot {
public:
- SceneObject _object1;
+ SceneObject _card;
- int _field34;
- Common::Point _field36;
+ int _cardId;
+ Common::Point _stationPos;
unkObj1337sub1();
void synchronize(Serializer &s);
@@ -183,9 +196,9 @@ class Scene1337 : public SceneExt {
class unkObj1337_1: public SceneHotspot {
public:
- unkObj1337sub1 _arr1[4];
- unkObj1337sub1 _arr2[8];
- unkObj1337sub1 _arr3[1];
+ unkObj1337sub1 _handCard[4];
+ unkObj1337sub1 _outpostStation[8];
+ unkObj1337sub1 _delayPile[1];
unkObj1337sub1 _arr4[1];
Common::Point _fieldB94;
@@ -200,8 +213,7 @@ class Scene1337 : public SceneExt {
class Action1337: public Action {
public:
- void subD18B5(int resNum, int stripNum, int frameNum);
- void skipFrames(int32 skipCount);
+ void waitFrames(int32 frameCount);
};
class Action1: public Action1337 {
@@ -264,9 +276,9 @@ public:
ASound _aSound2;
BackgroundSceneObject _background1;
bool _autoplay;
- unkObj1337_1 _arrunkObj1337[4];
+ unkObj1337_1 _gameBoardSide[4];
SceneItem _item1;
- SceneObject _object1;
+ SceneObject _currentPlayerArrow;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -280,33 +292,33 @@ public:
Action11 _action11;
Action12 _action12;
Action13 _action13;
- unkObj1337sub1 _item2;
- unkObj1337sub1 _item3;
+ unkObj1337sub1 _animatedCard;
+ unkObj1337sub1 _shuffleAnimation;
unkObj1337sub1 _item4;
BackgroundSceneObject _background2;
- int _field3E24;
+ int _cardsAvailableNumb;
int _field3E26;
- int _field3E28[100];
+ int _availableCardsPile[100];
unkObj1337sub1 *_field3EF0;
unkObj1337sub1 *_field3EF4;
unkObj1337sub1 *_field3EF8;
unkObj1337sub1 _item5;
unkObj1337sub1 _item6;
- unkObj1337sub1 _item7;
+ unkObj1337sub1 _discardPile;
unkObj1337sub1 _item8;
- int _field423C;
- int _field423E;
+ bool _shuffleEndedFl;
+ int _currentPlayerNumb;
int _field4240;
int _field4242;
- int _field4244;
- int _field4246;
+ bool _field4244;
+ bool _field4246;
int _field4248;
int _field424A;
- int _field424C;
- int _field424E;
+ int _instructionsDisplayedFl;
+ int _instructionsWaitCount;
- SceneObject _arrObject1[8];
- SceneObject _arrObject2[8];
+ SceneObject _upperDisplayCard[8];
+ SceneObject _lowerDisplayCard[8];
Scene1337();
virtual void synchronize(Serializer &s);
@@ -345,10 +357,10 @@ public:
void subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
void displayDialog(int dialogNumb);
void subPostInit();
- void subCB59B();
+ void displayInstructions();
void suggestInstructions();
void shuffleCards();
- void subCCF26();
+ void firstShuffle();
void subCD193();
void subCDB90(int arg1, Common::Point pt);
void subCF31D();
@@ -357,10 +369,10 @@ public:
void subD0281();
void subD02CA();
void subD183F(int arg1, int arg2);
- void subD18B5(int resNum, int rlbNum, int arg3);
- int subD18F5();
- int subD1917();
- int subD1940(bool flag);
+ void setCursorData(int resNum, int rlbNum, int frameNum);
+ void subD18F5();
+ void subD1917();
+ void subD1940(bool flag);
void subD195F(int arg1, int arg2);
void subD1975(int arg1, int arg2);
void subD1A48(int arg1);
@@ -373,10 +385,10 @@ public:
class Scene1500 : public SceneExt {
public:
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
+ SceneActor _starship;
+ SceneActor _starshipShadow;
+ SceneActor _smallShip;
+ SceneActor _smallShipShadow;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -397,9 +409,9 @@ class Scene1530 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _seeker;
+ SceneActor _leftReactor;
+ SceneActor _rightReactor;
SequenceManager _sequenceManager;
@@ -409,151 +421,136 @@ public:
};
class Scene1550 : public SceneExt {
- class SceneActor1550 : public SceneActor {
+ class Wall : public SceneActor {
public:
- void subA4D14(int frameNumber, int strip);
+ void setupWall(int frameNumber, int strip);
};
- class 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 {
- public:
- int _fieldA4;
-
- UnkObj15503();
- void synchronize(Serializer &s);
+ class DishControlsWindow : public ModalWindow {
+ class DishControl : public SceneActor {
+ public:
+ int _controlId;
- virtual bool startAction(CursorType action, Event &event);
- };
+ DishControl();
+ void synchronize(Serializer &s);
- class UnkArea1550 : public SceneArea {
+ virtual bool startAction(CursorType action, Event &event);
+ };
public:
byte _field20;
SceneActor _areaActor;
- UnkObj15503 _unkObj155031;
- UnkObj15503 _unkObj155032;
+ DishControl _button;
+ DishControl _lever;
virtual void remove();
- virtual void process(Event &event);
- virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
- };
-
- class Hotspot1 : public NamedHotspot {
- public:
- virtual bool startAction(CursorType action, Event &event);
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
};
- class Hotspot3 : public NamedHotspot {
+ class WorkingShip : public NamedHotspot {
public:
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);
};
- class Actor8 : public SceneActor {
+ class AirBag : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor9 : public SceneActor {
+ class Joystick : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor10 : public SceneActor {
+ class Gyroscope : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor11 : public SceneActor {
+ class DiagnosticsDisplay : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor12 : public SceneActor {
+ class DishTower : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor13 : public SceneActor {
+ class Dish : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor14 : public SceneActor1550 {
- // Nothing specific found in the original
- // TODO: check if it's an useless class
- };
-
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot1 _item2;
- Hotspot3 _item3;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- 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];
- UnkArea1550 _unkArea1;
+ WorkingShip _intactHull1, _intactHull2;
+ SceneHotspot _background;
+ SceneActor _wreckage2; // also used for Lance of Truth landing strut
+ SceneActor _wreckage3;
+ SceneActor _wreckage4;
+ SceneActor _walkway;
+ SceneActor _dishTowerShadow;
+ Wreckage _wreckage;
+ Companion _companion;
+ AirBag _airbag;
+ Joystick _joystick;
+ Gyroscope _gyroscope;
+ DiagnosticsDisplay _diagnosticsDisplay;
+ DishTower _dishTower;
+ Dish _dish;
+ Junk _junk[8];
+ Wall _wallCorner1;
+ Wall _northWall; // Is also reused for landing strip
+ Wall _wallCorner2;
+ Wall _westWall; // Is also reused for left hand space
+ Wall _eastWall;
+ Wall _southWall;
+ ShipComponent _shipComponents[8];
+ DishControlsWindow _dishControlsWindow;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
- int _field412;
- byte _field414;
- int _field415;
- int _field417;
- int _field419;
+ bool _dontExit;
+ int _wallType;
+ int _dishMode;
+ int _sceneResourceId;
+ int _walkRegionsId;
Scene1550();
void synchronize(Serializer &s);
- void subA2B2F();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -563,14 +560,14 @@ public:
};
class Scene1575 : public SceneExt {
- class Hotspot1 : public NamedHotspot {
+ class Button : public NamedHotspot {
public:
- int _field34;
- int _field36;
+ int _buttonId;
+ bool _pressed;
- Hotspot1();
+ Button();
void synchronize(Serializer &s);
- void subA910D(int indx);
+ void initButton(int buttonId);
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
@@ -581,12 +578,12 @@ public:
int _field416;
int _field418;
int _field41A;
- Hotspot1 _item1;
- Hotspot1 _item2;
- Hotspot1 _item3;
- Hotspot1 _item4;
- Hotspot1 _item5;
- Hotspot1 _item6;
+ Button _button1;
+ Button _button2;
+ Button _button3;
+ Button _button4;
+ Button _button5;
+ Button _button6;
SceneActor _actor1;
SceneActor _actor2;
SceneActor _actor3;
@@ -616,54 +613,53 @@ public:
};
class Scene1580 : public SceneExt {
- class Hotspot1 : public NamedHotspot {
+ class JoystickPlug : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Hotspot2 : public NamedHotspot {
+ class ScreenSlot : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Joystick : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Screen : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class StorageCompartment : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class HatchButton : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class ThrusterValve : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Ignitor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot2 _item2;
- NamedHotspot _item3;
- SceneActor _actor1;
+ JoystickPlug _joystickPlug;
+ ScreenSlot _screenSlot;
+ NamedHotspot _background;
+ SceneActor _screenDisplay;
SceneActor _arrActor[8];
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
+ Joystick _joystick;
+ Screen _screen;
+ StorageCompartment _storageCompartment;
+ HatchButton _hatchButton;
+ ThrusterValve _thrusterValve;
+ Ignitor _ignitor;
SequenceManager _sequenceManager;
Scene1580();
@@ -674,23 +670,22 @@ public:
};
class Scene1625 : public SceneExt {
- class Actor7 : public SceneActor {
+ class Wire : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
SpeakerMiranda1625 _mirandaSpeaker;
SpeakerTeal1625 _tealSpeaker;
SpeakerSoldier1625 _soldierSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- Actor7 _actor7;
+ NamedHotspot _background;
+ SceneActor _teal;
+ SceneActor _tealHead;
+ SceneActor _mirandaMouth;
+ SceneActor _glass;
+ SceneActor _wristRestraints;
+ SceneActor _tealRightArm;
+ Wire _wire;
SequenceManager _sequenceManager;
Scene1625();
@@ -703,60 +698,54 @@ public:
};
class Scene1700 : public SceneExt {
- class Item2 : public NamedHotspot {
+ class RimTransport : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
-
- class Actor11 : public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
- class Actor12 : public SceneActor {
+ class Companion : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- 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();
};
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- Item2 _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- Actor11 _actor11;
- Actor12 _actor12;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
+ NamedHotspot _surface;
+ NamedHotspot _background;
+ SceneActor _playerShadow;
+ SceneActor _companionShadow;
+ SceneActor _slabWest;
+ SceneActor _slabEast;
+ SceneActor _slabShadowWest;
+ SceneActor _slabShadowEast;
+ SceneActor _westPlatform;
+ SceneActor _rimTransportDoor;
+ SceneActor _ledgeHopper;
+ SceneActor _hatch;
+ RimTransport _rimTransport;
+ Companion _companion;
+ NorthExit _northExit;
+ SouthExit _southExit;
+ WestExit _westExit;
SequenceManager _sequenceManager;
- int _field77A;
- int _field77C;
+ bool _walkFlag;
Scene1700();
void synchronize(Serializer &s);
- void subAF3F8();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -764,58 +753,57 @@ 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;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor5 _actor6;
- Actor5 _actor7;
+ NamedHotspot _background;
+ NamedHotspot _redLightsDescr;
+ NamedHotspot _greenLights;
+ NamedHotspot _frontView;
+ NamedHotspot _rearView;
+ SceneActor _scannerIcon;
+ SceneActor _redLights;
+ SceneActor _radarSweep;
+ SpeedSlider _speedSlider;
+ Button _forwardButton;
+ Button _backwardButton;
+ Button _exitButton;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
- int _field412;
- int _field413;
- int _field415;
- int _field417;
- int _field419;
- int _field41B;
- int _field41D;
+ int _direction;
+ int _speedCurrent;
+ int _speed;
+ int _speedDelta;
+ int _rotationSegment;
+ int _rotationSegCurrent;
+ int _newRotation;
Scene1750();
virtual void synchronize(Serializer &s);
@@ -828,47 +816,47 @@ 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);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- int _field412;
+ int _locationMode;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Hotspot5 _item5;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- Actor8 _actor9;
- Exit1 _exit1;
+ NamedHotspot _elevator;
+ NamedHotspot _elevatorContents;
+ NamedHotspot _surface;
+ NamedHotspot _secBackground;
+ Background _background;
+ SceneActor _playerShadow;
+ SceneActor _companion;
+ SceneActor _companionShadow;
+ SceneActor _leftStaircase;
+ SceneActor _rightStaircase;
+ Lever _lever;
+ Doors _doors;
+ PassengerDoor _leftDoor;
+ PassengerDoor _rightDoor;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
Scene1800();
@@ -880,44 +868,44 @@ public:
};
class Scene1850 : public SceneExt {
- class Hotspot2 : public NamedHotspot {
+ class Button : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Robot : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Door : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class DisplayScreen : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
- int _field414;
- int _field416;
- int _field418;
- Common::Point _field41A;
- int _field41E;
+ int _sceneMode;
+ int _shadeCountdown;
+ int _shadeDirection;
+ bool _shadeChanging;
+ Common::Point _playerDest;
+ int _seqNumber;
ScenePalette _palette1;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- Hotspot2 _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor6 _actor7;
- Actor8 _actor8;
+ NamedHotspot _background;
+ Button _button;
+ SceneActor _companion;
+ SceneActor _airbag;
+ SceneActor _screen;
+ SceneActor _helmet;
+ Robot _robot;
+ Door _leftDoor;
+ Door _rightDoor;
+ DisplayScreen _displayScreen;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -932,31 +920,31 @@ public:
};
class Scene1875 : public SceneExt {
- class Actor1875 : public SceneActor {
+ class Button : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
+ int _buttonId;
+ bool _buttonDown;
- Actor1875();
- void subB84AB();
- void subB8271(int indx);
+ Button();
+ void doButtonPress();
+ void initButton(int buttonId);
+ virtual Common::String getClassName() { return "Scene1875_Button"; }
void synchronize(Serializer &s);
virtual void process(Event &event);
};
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor1875 _actor4;
- Actor1875 _actor5;
- Actor1875 _actor6;
- Actor1875 _actor7;
- Actor1875 _actor8;
+ NamedHotspot _background;
+ NamedHotspot _screen;
+ SceneActor _map;
+ SceneActor _rimPosition;
+ Button _button1;
+ Button _button2;
+ Button _button3;
+ Button _button4;
+ Button _button5;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -965,30 +953,29 @@ public:
};
class Scene1900 : public SceneExt {
- class Actor2 : public SceneActor {
+ class LiftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
SpeakerSeeker1900 _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- SceneActor _actor1;
- BackgroundSceneObject _object1;
- BackgroundSceneObject _object2;
- Actor2 _actor2;
- Actor2 _actor3;
- Exit1 _exit1;
- Exit2 _exit2;
+ NamedHotspot _background;
+ NamedHotspot _elevator;
+ SceneActor _companion;
+ BackgroundSceneObject _leftDoorFrame;
+ BackgroundSceneObject _rightDoorFrame;
+ LiftDoor _leftDoor, _rightDoor;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -998,11 +985,11 @@ public:
};
class Scene1925 : public SceneExt {
- class Hotspot2 : public NamedHotspot {
+ class Button : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Hotspot3 : public NamedHotspot {
+ class Ladder : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -1011,30 +998,30 @@ class Scene1925 : public SceneExt {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class ExitDown : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- Hotspot2 _item2;
- Hotspot3 _item3;
- SceneActor _actor1;
+ NamedHotspot _background;
+ Button _button;
+ Ladder _ladder;
+ SceneActor _door;
ExitUp _exitUp;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
+ ExitDown _exitDown;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager;
- int _field9B8;
+ int _newSceneMode;
int _levelResNum[5];
Scene1925();
@@ -1047,16 +1034,16 @@ public:
};
class Scene1945 : public SceneExt {
- class Hotspot3 : public NamedHotspot {
+ class Ice : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Hotspot4 : public NamedHotspot {
+ class Ladder : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Gunpowder : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -1065,26 +1052,26 @@ class Scene1945 : public SceneExt {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class CorridorExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- Hotspot3 _item3;
- Hotspot4 _item4;
- SceneActor _actor1;
- SceneActor _actor2;
- Actor3 _actor3;
+ NamedHotspot _hole;
+ NamedHotspot _ice2;
+ Ice _ice;
+ Ladder _ladder;
+ SceneActor _coveringIce;
+ SceneActor _alcoholLamp;
+ Gunpowder _gunpowder;
ExitUp _exitUp;
- Exit2 _exit2;
+ CorridorExit _corridorExit;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
- int _fieldEAA;
- int _fieldEAC;
- CursorType _fieldEAE;
+ int _nextSceneMode1;
+ int _nextSceneMode2;
+ CursorType _lampUsed;
Scene1945();
void synchronize(Serializer &s);
@@ -1095,15 +1082,16 @@ public:
};
class Scene1950 : public SceneExt {
- class Area1: public SceneArea {
+ /* Windows */
+ class KeypadWindow: public ModalWindow {
public:
- class Actor10 : public SceneActor {
+ class KeypadButton : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
+ int _buttonIndex;
+ bool _pressed;
+ bool _toggled;
- Actor10();
+ KeypadButton();
void synchronize(Serializer &s);
void init(int indx);
@@ -1112,130 +1100,124 @@ class Scene1950 : public SceneExt {
};
SceneActor _areaActor;
- Actor10 _arrActor1[16];
+ KeypadButton _buttons[16];
- byte _field20;
- int _fieldB65;
-
- Area1();
- void synchronize(Serializer &s);
+ int _buttonIndex;
+ KeypadWindow();
+ virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void process(Event &event);
- virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
- class Hotspot2 : public NamedHotspot {
+ class Keypad : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ /* Actors */
+ class Door : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Scrolls : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Gem : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Vampire : public SceneActor {
public:
- virtual bool startAction(CursorType action, Event &event);
- };
- class Actor8 : public SceneActor {
- public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
- int _fieldAA;
- int _fieldAC;
- byte _fieldAE;
- byte _fieldAF;
+ Common::Point _deadPosition;
+ int _deltaX;
+ int _deltaY;
+ int _vampireMode;
- Actor8();
+ Vampire();
void synchronize(Serializer &s);
virtual void signal();
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ /* Exits */
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class UpExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class DownExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit5 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit6 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit7 : public SceneExit {
+ class ShaftExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit8 : public SceneExit {
+ class DoorExit : public SceneExit {
public:
virtual void changeScene();
};
+private:
+ void initArea();
+ void enterArea();
+ void doButtonPress(int indx);
public:
- NamedHotspot _item1;
- Hotspot2 _item2;
- SceneActor _actor1;
- BackgroundSceneObject _object1;
- Actor2 _actor2;
- Actor3 _actor3;
- SceneActor _actor4;
- Actor5 _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- Actor8 _actor8;
- Area1 _area1;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
- Exit5 _exit5;
- Exit6 _exit6;
- Exit7 _exit7;
- Exit8 _exit8;
+ NamedHotspot _background;
+ Keypad _keypad;
+ SceneActor _southDoorway;
+ SceneObject _northDoorway;
+ Door _door;
+ Scrolls _scrolls;
+ SceneActor _containmentField;
+ Gem _gem;
+ SceneActor _cube;
+ SceneActor _pulsingLights;
+ Vampire _vampire;
+ KeypadWindow _KeypadWindow;
+ NorthExit _northExit;
+ UpExit _upExit;
+ EastExit _eastExit;
+ DownExit _downExit;
+ SouthExit _southExit;
+ WestExit _westExit;
+ ShaftExit _shaftExit;
+ DoorExit _doorExit;
SequenceManager _sequenceManager;
- int _field412;
- int _field414;
- int _field416;
- Common::Point _field418;
- int _field41C;
+ bool _upExitStyle;
+ bool _removeFlag;
+ bool _vampireActive;
+ Common::Point _vampireDestPos;
+ int _vampireIndex;
Scene1950();
void synchronize(Serializer &s);
- void subBDC1E();
- void subBE59B();
- void subBF4B4(int indx);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
virtual void process(Event &event);
};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index 6a030e5b44..f928f3635c 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -30,17 +30,19 @@ namespace TsAGE {
namespace Ringworld2 {
/*--------------------------------------------------------------------------
- * Scene 2000 - Ice Maze
+ * Scene 2000 - Spill Mountains
*
*--------------------------------------------------------------------------*/
+
void Scene2000::initPlayer() {
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
switch (_mazePlayerMode) {
case 0:
R2_GLOBALS._player.setStrip(5);
- if (_exit1._enabled) {
- if (_exit2._enabled)
+ if (_westExit._enabled) {
+ if (_eastExit._enabled)
R2_GLOBALS._player.setPosition(Common::Point(140, 129));
else
R2_GLOBALS._player.setPosition(Common::Point(20, 129));
@@ -49,77 +51,77 @@ void Scene2000::initPlayer() {
R2_GLOBALS._player.enableControl();
break;
case 1:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2001;
else
_sceneMode = 2021;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 2:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2002;
else
_sceneMode = 2022;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 3:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2000;
else
_sceneMode = 2020;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 4:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2005;
else
_sceneMode = 2025;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 5:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2004;
else
_sceneMode = 2024;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 6:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2009;
else
_sceneMode = 2029;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 7:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2008;
else
_sceneMode = 2028;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 8:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2013;
else
_sceneMode = 2033;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 9:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2012;
else
_sceneMode = 2032;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 10:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2016;
else
_sceneMode = 2036;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
break;
case 11:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2038;
else
_sceneMode = 2040;
@@ -129,77 +131,80 @@ void Scene2000::initPlayer() {
break;
}
for (int i = 0; i < 11; i++) {
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._v56605[3 + i])
- _objList1[i].show();
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._spillLocation[3 + i])
+ _persons[i].show();
}
- if ((R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) && (R2_GLOBALS._v56605[1] == R2_GLOBALS._v56605[2])) {
- _object1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _object1.setup(20, 5, 1);
- _object1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER])
+ && (R2_GLOBALS._spillLocation[R2_QUINN] == R2_GLOBALS._spillLocation[R2_SEEKER])) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // Seeker is in room with Quinn
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _object1.setup(2008, 5, 1);
- _object1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ // Quinn is in room with Seeker
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- if (_exit1._enabled) {
- if (_exit2._enabled)
- _object1.setPosition(Common::Point(180, 128));
+ if (_westExit._enabled) {
+ if (_eastExit._enabled)
+ _companion.setPosition(Common::Point(180, 128));
else
- _object1.setPosition(Common::Point(75, 128));
+ _companion.setPosition(Common::Point(75, 128));
} else
- _object1.setPosition(Common::Point(300, 128));
+ _companion.setPosition(Common::Point(300, 128));
}
}
void Scene2000::initExits() {
- _exit1._enabled = true;
- _exit2._enabled = true;
- _exit3._enabled = false;
- _exit4._enabled = false;
- _exit5._enabled = false;
-
- _exit1._insideArea = false;
- _exit2._insideArea = false;
- _exit3._insideArea = false;
- _exit4._insideArea = false;
- _exit5._insideArea = false;
-
- _exit1._moving = false;
- _exit2._moving = false;
- _exit3._moving = false;
- _exit4._moving = false;
- _exit5._moving = false;
+ _westExit._enabled = true;
+ _eastExit._enabled = true;
+ _southExit._enabled = false;
+ _northExit._enabled = false;
+ _doorExit._enabled = false;
+
+ _westExit._insideArea = false;
+ _eastExit._insideArea = false;
+ _southExit._insideArea = false;
+ _northExit._insideArea = false;
+ _doorExit._insideArea = false;
+
+ _westExit._moving = false;
+ _eastExit._moving = false;
+ _southExit._moving = false;
+ _northExit._moving = false;
+ _doorExit._moving = false;
for (int i = 0; i < 11; i++)
- _objList1[i].hide();
+ _persons[i].hide();
- _object1.remove();
+ _companion.remove();
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 3:
case 10:
case 16:
case 21:
- _exit5._enabled = true;
- _exit5._bounds.set(61, 68, 90, 125);
- _exit5.setDest(Common::Point(92, 129));
- _exit5._cursorNum = EXITCURSOR_W;
+ _doorExit._enabled = true;
+ _doorExit._bounds.set(61, 68, 90, 125);
+ _doorExit.setDest(Common::Point(92, 129));
+ _doorExit._cursorNum = EXITCURSOR_W;
break;
case 4:
case 12:
case 25:
case 34:
- _exit5._enabled = true;
- _exit5._bounds.set(230, 68, 259, 125);
- _exit5.setDest(Common::Point(244, 129));
- _exit5._cursorNum = EXITCURSOR_E;
+ _doorExit._enabled = true;
+ _doorExit._bounds.set(230, 68, 259, 125);
+ _doorExit.setDest(Common::Point(244, 129));
+ _doorExit._cursorNum = EXITCURSOR_E;
break;
default:
break;
}
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] - 1) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
case 6:
case 13:
@@ -207,7 +212,7 @@ void Scene2000::initExits() {
case 22:
case 27:
case 30:
- _exit1._enabled = false;
+ _westExit._enabled = false;
loadScene(2225);
R2_GLOBALS._walkRegions.load(2225);
if (!_exitingFlag)
@@ -216,10 +221,10 @@ void Scene2000::initExits() {
break;
case 1:
case 19:
- _exit3._enabled = true;
- _exit3._bounds.set(71, 130, 154, 168);
- _exit3.setDest(Common::Point(94, 129));
- _exit3._cursorNum = EXITCURSOR_SE;
+ _southExit._enabled = true;
+ _southExit._bounds.set(71, 130, 154, 168);
+ _southExit.setDest(Common::Point(94, 129));
+ _southExit._cursorNum = EXITCURSOR_SE;
loadScene(2300);
if (!_exitingFlag)
_mazePlayerMode = 0;
@@ -283,8 +288,8 @@ void Scene2000::initExits() {
case 21:
case 26:
loadScene(2200);
- R2_GLOBALS._walkRegions.load(2000);
- _exit2._enabled = false;
+ R2_GLOBALS._walkRegions.load(2200);
+ _eastExit._enabled = false;
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1900)
_mazePlayerMode = 2;
else if (!_exitingFlag)
@@ -294,10 +299,10 @@ void Scene2000::initExits() {
break;
case 7:
case 29:
- _exit4._enabled = true;
- _exit4._bounds.set(138, 83, 211, 125);
- _exit4.setDest(Common::Point(129, 188));
- _exit4._cursorNum = EXITCURSOR_NW;
+ _northExit._enabled = true;
+ _northExit._bounds.set(138, 83, 211, 125);
+ _northExit.setDest(Common::Point(188, 129));
+ _northExit._cursorNum = EXITCURSOR_NW;
loadScene(2250);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2500)
@@ -309,10 +314,10 @@ void Scene2000::initExits() {
break;
case 10:
case 25:
- _exit3._enabled = true;
- _exit3._bounds.set(78, 130, 148, 168);
- _exit3.setDest(Common::Point(100, 129));
- _exit3._cursorNum = EXITCURSOR_SE;
+ _southExit._enabled = true;
+ _southExit._bounds.set(78, 130, 148, 168);
+ _southExit.setDest(Common::Point(100, 129));
+ _southExit._cursorNum = EXITCURSOR_SE;
loadScene(2075);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -320,10 +325,10 @@ void Scene2000::initExits() {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
break;
case 14:
- _exit3._enabled = true;
- _exit3._bounds.set(160, 130, 248, 168);
- _exit3.setDest(Common::Point(225, 129));
- _exit3._cursorNum = EXITCURSOR_SW;
+ _southExit._enabled = true;
+ _southExit._bounds.set(160, 130, 248, 168);
+ _southExit.setDest(Common::Point(225, 129));
+ _southExit._cursorNum = EXITCURSOR_SW;
loadScene(2325);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -332,10 +337,10 @@ void Scene2000::initExits() {
break;
case 16:
case 31:
- _exit4._enabled = true;
- _exit4._bounds.set(122, 83, 207, 125);
- _exit4.setDest(Common::Point(210, 129));
- _exit4._cursorNum = EXITCURSOR_NW;
+ _northExit._enabled = true;
+ _northExit._bounds.set(122, 83, 207, 125);
+ _northExit.setDest(Common::Point(210, 129));
+ _northExit._cursorNum = EXITCURSOR_NW;
loadScene(2125);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2400)
@@ -346,10 +351,10 @@ void Scene2000::initExits() {
R2_GLOBALS._sceneManager._previousScene = 2000;
break;
case 23:
- _exit4._enabled = true;
- _exit4._bounds.set(108, 83, 128, 184);
- _exit4.setDest(Common::Point(135, 129));
- _exit4._cursorNum = CURSOR_INVALID;
+ _northExit._enabled = true;
+ _northExit._bounds.set(108, 83, 184, 125);
+ _northExit.setDest(Common::Point(135, 129));
+ _northExit._cursorNum = EXITCURSOR_NE;
loadScene(2275);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -357,10 +362,10 @@ void Scene2000::initExits() {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
break;
case 28:
- _exit3._enabled = true;
- _exit3._bounds.set(171, 130, 241, 168);
- _exit3.setDest(Common::Point(218, 129));
- _exit3._cursorNum = EXITCURSOR_SW;
+ _southExit._enabled = true;
+ _southExit._bounds.set(171, 130, 241, 168);
+ _southExit.setDest(Common::Point(218, 129));
+ _southExit._cursorNum = EXITCURSOR_SW;
loadScene(2050);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2350)
@@ -391,42 +396,42 @@ void Scene2000::Action1::signal() {
_actionIndex = 1;
Common::Point pt(-20, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, scene);
+ scene->_persons[_state].addMover(mover, &pt, scene);
break;
}
case 1:
- scene->_objList1[_state].setPosition(Common::Point(340, 127));
- --R2_GLOBALS._v56605[4 + _state];
+ scene->_persons[_state].setPosition(Common::Point(340, 127));
+ --R2_GLOBALS._spillLocation[4 + _state];
_actionIndex = 0;
switch (_state - 1) {
case 0:
- if (R2_GLOBALS._v56605[4] == 1)
+ if (R2_GLOBALS._spillLocation[4] == 1)
_actionIndex = 10;
break;
case 2:
- if (R2_GLOBALS._v56605[6] == 7)
+ if (R2_GLOBALS._spillLocation[6] == 7)
_actionIndex = 10;
break;
case 4:
- if (R2_GLOBALS._v56605[8] == 14)
+ if (R2_GLOBALS._spillLocation[8] == 14)
_actionIndex = 10;
break;
case 6:
- if (R2_GLOBALS._v56605[10] == 19)
+ if (R2_GLOBALS._spillLocation[10] == 19)
_actionIndex = 10;
break;
case 7:
- if (R2_GLOBALS._v56605[11] == 23)
+ if (R2_GLOBALS._spillLocation[11] == 23)
_actionIndex = 10;
break;
default:
break;
}
- if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
- scene->_objList1[_state].show();
+ if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
+ scene->_persons[_state].show();
else
- scene->_objList1[_state].hide();
+ scene->_persons[_state].hide();
signal();
break;
@@ -434,96 +439,96 @@ void Scene2000::Action1::signal() {
_actionIndex = 6;
Common::Point pt(340, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
break;
}
case 6:
- scene->_objList1[_state].setPosition(Common::Point(-20, 127));
- ++R2_GLOBALS._v56605[3 + _state];
+ scene->_persons[_state].setPosition(Common::Point(-20, 127));
+ ++R2_GLOBALS._spillLocation[3 + _state];
_actionIndex = 5;
switch (_state - 1) {
case 0:
- if (R2_GLOBALS._v56605[4] == 5)
+ if (R2_GLOBALS._spillLocation[4] == 5)
_actionIndex = 15;
break;
case 2:
- if (R2_GLOBALS._v56605[6] == 13)
+ if (R2_GLOBALS._spillLocation[6] == 13)
_actionIndex = 15;
break;
case 4:
- if (R2_GLOBALS._v56605[8] == 16)
+ if (R2_GLOBALS._spillLocation[8] == 16)
_actionIndex = 15;
break;
case 6:
- if (R2_GLOBALS._v56605[10] == 22)
+ if (R2_GLOBALS._spillLocation[10] == 22)
_actionIndex = 15;
break;
case 7:
- if (R2_GLOBALS._v56605[11] == 27)
+ if (R2_GLOBALS._spillLocation[11] == 27)
_actionIndex = 15;
break;
default:
break;
}
- if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
- scene->_objList1[_state].show();
+ if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
+ scene->_persons[_state].show();
else
- scene->_objList1[_state].hide();
+ scene->_persons[_state].hide();
signal();
break;
case 10: {
Common::Point pt(290, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 11;
break;
}
case 11:
if (_state == 1)
- scene->_objList1[0].setStrip(1);
+ scene->_persons[0].setStrip(1);
else if (_state == 5)
- scene->_objList1[4].setStrip(1);
+ scene->_persons[4].setStrip(1);
setDelay(600);
_actionIndex = 12;
break;
case 12:
if (_state == 1)
- scene->_objList1[0].setStrip(2);
+ scene->_persons[0].setStrip(2);
else if (_state == 5)
- scene->_objList1[4].setStrip(2);
- scene->_objList1[_state].setStrip(1);
+ scene->_persons[4].setStrip(2);
+ scene->_persons[_state].setStrip(1);
_actionIndex = 5;
signal();
break;
case 15:
- if ((R2_GLOBALS._v56605[3 + _state] == 13) || (R2_GLOBALS._v56605[3 + _state] == 22) || (R2_GLOBALS._v56605[3 + _state] == 27)) {
+ if ((R2_GLOBALS._spillLocation[3 + _state] == 13) || (R2_GLOBALS._spillLocation[3 + _state] == 22) || (R2_GLOBALS._spillLocation[3 + _state] == 27)) {
Common::Point pt(30, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 16;
} else {
Common::Point pt(120, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 16;
}
break;
case 16:
if (_state == 1)
- scene->_objList1[2].setStrip(2);
+ scene->_persons[2].setStrip(2);
else if (_state == 8)
- scene->_objList1[9].setStrip(2);
+ scene->_persons[9].setStrip(2);
setDelay(600);
_actionIndex = 17;
break;
case 17:
if (_state == 1)
- scene->_objList1[2].setStrip(1);
+ scene->_persons[2].setStrip(1);
else if (_state == 8)
- scene->_objList1[9].setStrip(1);
- scene->_objList1[_state].setStrip(2);
+ scene->_persons[9].setStrip(1);
+ scene->_persons[_state].setStrip(2);
_actionIndex = 0;
break;
case 99:
@@ -534,26 +539,24 @@ void Scene2000::Action1::signal() {
}
}
-void Scene2000::Exit1::changeScene() {
+void Scene2000::WestExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 10;
Common::Point pt(-10, 129);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, scene);
-
- scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
}
-void Scene2000::Exit2::changeScene() {
+void Scene2000::EastExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 11;
@@ -562,38 +565,38 @@ void Scene2000::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene2000::Exit3::changeScene() {
+void Scene2000::SouthExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 12;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 2:
scene->_mazePlayerMode = 4;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 8;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 8;
break;
case 11:
scene->_mazePlayerMode = 6;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 17;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 17;
break;
case 15:
scene->_mazePlayerMode = 8;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 24;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 24;
break;
case 20:
scene->_mazePlayerMode = 4;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 30;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 30;
break;
case 26:
scene->_mazePlayerMode = 6;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 32;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 32;
break;
case 29:
scene->_mazePlayerMode = 11;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 29;
break;
default:
break;
@@ -601,25 +604,25 @@ void Scene2000::Exit3::changeScene() {
switch (scene->_mazePlayerMode) {
case 4:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2003, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2023, &R2_GLOBALS._player, NULL);
break;
case 6:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2007, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2027, &R2_GLOBALS._player, NULL);
break;
case 8:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2011, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2031, &R2_GLOBALS._player, NULL);
break;
case 11:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 2039;
else
scene->_sceneMode = 2041;
@@ -630,34 +633,35 @@ void Scene2000::Exit3::changeScene() {
break;
}
}
-void Scene2000::Exit4::changeScene() {
+
+void Scene2000::NorthExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 13;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 8:
scene->_mazePlayerMode = 5;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 2;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 2;
break;
case 17:
scene->_mazePlayerMode = 7;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 11;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 11;
break;
case 24:
scene->_mazePlayerMode = 9;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 15;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 15;
break;
case 30:
scene->_mazePlayerMode = 5;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 20;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 20;
break;
case 32:
scene->_mazePlayerMode = 7;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 26;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 26;
break;
default:
break;
@@ -665,19 +669,19 @@ void Scene2000::Exit4::changeScene() {
switch (scene->_mazePlayerMode) {
case 5:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2006, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2026, &R2_GLOBALS._player, NULL);
break;
case 7:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2010, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2030, &R2_GLOBALS._player, NULL);
break;
case 9:
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2014, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2034, &R2_GLOBALS._player, NULL);
@@ -687,66 +691,66 @@ void Scene2000::Exit4::changeScene() {
}
}
-void Scene2000::Exit5::changeScene() {
+void Scene2000::DoorExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 14;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 3:
scene->_mazePlayerMode = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
break;
case 4:
scene->_mazePlayerMode = 7;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
break;
case 10:
scene->_mazePlayerMode = 8;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
break;
case 12:
scene->_mazePlayerMode = 3;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
break;
case 16:
scene->_mazePlayerMode = 4;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
break;
case 21:
scene->_mazePlayerMode = 5;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2015, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2035, &R2_GLOBALS._player, NULL);
break;
case 25:
scene->_mazePlayerMode = 2;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
break;
case 34:
scene->_mazePlayerMode = 6;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2017, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2037, &R2_GLOBALS._player, NULL);
@@ -756,29 +760,32 @@ void Scene2000::Exit5::changeScene() {
}
}
-void Scene2000::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
- loadScene(2000);
-
- if (R2_GLOBALS._sceneManager._previousScene != -1) {
- R2_GLOBALS._v56605[1] = 21;
- R2_GLOBALS._v56605[2] = 21;
+Scene2000::Scene2000(): SceneExt() {
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._spillLocation[R2_QUINN] = 21;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 21;
}
- 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)) {
+ 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;
+}
- _exit1.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(14, 129));
- _exit2.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000);
- _exit2.setDest(Common::Point(315, 129));
- _exit3.setDetails(Rect(71, 130, 154, 168), EXITCURSOR_S, 2000);
- _exit3.setDest(Common::Point(94, 129));
- _exit4.setDetails(Rect(138, 83, 211, 125), EXITCURSOR_N, 2000);
- _exit4.setDest(Common::Point(188, 128));
- _exit5.setDetails(Rect(61, 68, 90, 125), EXITCURSOR_W, 2000);
- _exit5.setDest(Common::Point(92, 129));
+void Scene2000::postInit(SceneObjectList *OwnerList) {
+ _westExit.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 129));
+ _eastExit.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 129));
+ _southExit.setDetails(Rect(71, 130, 154, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(94, 129));
+ _northExit.setDetails(Rect(138, 83, 211, 125), EXITCURSOR_N, 2000);
+ _northExit.setDest(Common::Point(188, 129));
+ _doorExit.setDetails(Rect(61, 68, 90, 125), EXITCURSOR_W, 2000);
+ _doorExit.setDest(Common::Point(92, 129));
R2_GLOBALS._sound1.play(200);
initExits();
@@ -787,7 +794,7 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(2008, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -802,92 +809,92 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
_action5._state = 3;
for (int i = 0; i < 11; i++)
- _objList1[i].postInit();
+ _persons[i].postInit();
- _objList1[0].setVisage(2000);
- _objList1[0].setStrip(2);
- _objList1[0].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[0].setVisage(2000);
+ _persons[0].setStrip(2);
+ _persons[0].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[1].setVisage(2001);
- _objList1[1].setStrip(2);
- _objList1[1].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[1].setVisage(2001);
+ _persons[1].setStrip(2);
+ _persons[1].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[2].setVisage(2003);
- _objList1[2].setStrip(1);
- _objList1[2].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[2].setVisage(2003);
+ _persons[2].setStrip(1);
+ _persons[2].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[3].setVisage(2007);
- _objList1[3].setStrip(2);
- _objList1[3].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+ _persons[3].setVisage(2007);
+ _persons[3].setStrip(2);
+ _persons[3].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
- _objList1[4].setVisage(2004);
- _objList1[4].setStrip(2);
- _objList1[4].setDetails(2001, 19, -1, -1, 1, (SceneItem *)NULL);
+ _persons[4].setVisage(2004);
+ _persons[4].setStrip(2);
+ _persons[4].setDetails(2001, 19, -1, -1, 1, (SceneItem *)NULL);
- _objList1[5].setVisage(2003);
- _objList1[5].setStrip(2);
- _objList1[5].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[5].setVisage(2003);
+ _persons[5].setStrip(2);
+ _persons[5].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[6].setVisage(2000);
- _objList1[6].setStrip(1);
- _objList1[6].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[6].setVisage(2000);
+ _persons[6].setStrip(1);
+ _persons[6].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[7].setVisage(2000);
- _objList1[7].setStrip(2);
- _objList1[7].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[7].setVisage(2000);
+ _persons[7].setStrip(2);
+ _persons[7].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[8].setVisage(2000);
- _objList1[8].setStrip(2);
- _objList1[8].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[8].setVisage(2000);
+ _persons[8].setStrip(2);
+ _persons[8].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[9].setVisage(2006);
- _objList1[9].setStrip(1);
- _objList1[9].setDetails(2001, 6, -1, -1, 1, (SceneItem *)NULL);
+ _persons[9].setVisage(2006);
+ _persons[9].setStrip(1);
+ _persons[9].setDetails(2001, 6, -1, -1, 1, (SceneItem *)NULL);
- _objList1[10].setVisage(2007);
- _objList1[10].setStrip(1);
- _objList1[10].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+ _persons[10].setVisage(2007);
+ _persons[10].setStrip(1);
+ _persons[10].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
for (int i = 0; i < 11; i++) {
- _objList1[i].animate(ANIM_MODE_1, NULL);
- _objList1[i]._moveDiff.x = 3;
- _objList1[i]._moveRate = 8;
- _objList1[i].hide();
+ _persons[i].animate(ANIM_MODE_1, NULL);
+ _persons[i]._moveDiff.x = 3;
+ _persons[i]._moveRate = 8;
+ _persons[i].hide();
switch (i - 1) {
case 0:
- if (R2_GLOBALS._v56605[3 + i] == 1)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 5)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 1)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 5)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 2:
- if (R2_GLOBALS._v56605[3 + i] == 7)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 13)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 7)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 13)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 4:
- if (R2_GLOBALS._v56605[3 + i] == 14)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 16)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 14)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 16)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 6:
- if (R2_GLOBALS._v56605[3 + i] == 19)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 22)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 19)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 22)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 8:
- if (R2_GLOBALS._v56605[3 + i] == 23)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 27)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 23)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 27)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
default:
break;
}
- switch (R2_GLOBALS._v56605[3 + i] - 1) {
+ switch (R2_GLOBALS._spillLocation[3 + i] - 1) {
case 0:
case 6:
case 13:
@@ -895,31 +902,34 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
case 22:
case 27:
case 30:
- _objList1[i].setPosition(Common::Point(265, 127));
+ _persons[i].setPosition(Common::Point(265, 127));
break;
case 5:
case 12:
case 17:
case 21:
case 26:
- _objList1[i].setPosition(Common::Point(55, 127));
+ _persons[i].setPosition(Common::Point(55, 127));
break;
default:
- _objList1[i].setPosition(Common::Point(160, 127));
+ _persons[i].setPosition(Common::Point(160, 127));
break;
}
}
- _objList1[1].setAction(&_action2);
- _objList1[3].setAction(&_action5);
- _objList1[5].setAction(&_action4);
- _objList1[8].setAction(&_action1);
+ _persons[1].setAction(&_action2);
+ _persons[3].setAction(&_action5);
+ _persons[5].setAction(&_action4);
+ _persons[8].setAction(&_action1);
initPlayer();
- _item1.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL);
+
+ SceneExt::postInit();
}
void Scene2000::remove() {
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._sound1.fadeOut(NULL);
SceneExt::remove();
}
@@ -927,17 +937,19 @@ void Scene2000::remove() {
void Scene2000::signal() {
switch (_sceneMode) {
case 10:
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 6)
+ // Leaving left-hand side of scene
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == 6)
g_globals->_sceneManager.changeScene(1900);
else {
_mazePlayerMode = 1;
- --R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ --R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex];
initExits();
initPlayer();
}
break;
case 11:
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ // Leaving right-hand side of scene
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 5:
g_globals->_sceneManager.changeScene(1900);
break;
@@ -949,7 +961,7 @@ void Scene2000::signal() {
break;
default:
_mazePlayerMode = 2;
- ++R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex];
initExits();
initPlayer();
break;
@@ -957,6 +969,7 @@ void Scene2000::signal() {
break;
case 12:
case 13:
+ // Top/bottom scene exits
initExits();
initPlayer();
break;
@@ -987,9 +1000,7 @@ void Scene2000::signal() {
g_globals->_sceneManager.changeScene(2535);
break;
default:
- if (R2_GLOBALS._v56AAB != 0)
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
break;
@@ -998,6 +1009,7 @@ void Scene2000::signal() {
g_globals->_sceneManager.changeScene(2350);
break;
default:
+ R2_GLOBALS._player.enableControl();
break;
}
}
@@ -1026,20 +1038,21 @@ void Scene2000::synchronize(Serializer &s) {
* Scene 2350 - Balloon Launch Platform
*
*--------------------------------------------------------------------------*/
-bool Scene2350::Actor2::startAction(CursorType action, Event &event) {
+
+bool Scene2350::Companion::startAction(CursorType action, Event &event) {
if (action != R2_SENSOR_PROBE)
return(SceneActor::startAction(action, event));
return true;
}
-bool Scene2350::Actor3::startAction(CursorType action, Event &event) {
- Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2350::Balloon::startAction(CursorType action, Event &event) {
if ((action == R2_REBREATHER_TANK) && (R2_GLOBALS.getFlag(74))) {
+ Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
+ scene->_person.postInit();
scene->_sceneMode = 2355;
- scene->setAction(&scene->_sequenceManager, scene, 2355, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2355, &R2_GLOBALS._player, &scene->_person, NULL);
return true;
}
@@ -1048,10 +1061,11 @@ bool Scene2350::Actor3::startAction(CursorType action, Event &event) {
void Scene2350::ExitUp::changeScene() {
Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+ _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 12;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2350, &R2_GLOBALS._player, NULL);
else
scene->setAction(&scene->_sequenceManager, scene, 2352, &R2_GLOBALS._player, NULL);
@@ -1077,7 +1091,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS._player._characterScene[2] = 2350;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2350;
_exitUp.setDetails(Rect(25, 83, 93, 125), EXITCURSOR_NW, 2350);
_exitUp.setDest(Common::Point(80, 129));
@@ -1087,7 +1101,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(2008, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -1095,39 +1109,39 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor2.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor2.setup(20, 5, 1);
- _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor2.setup(2008, 5, 1);
- _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor2.setPosition(Common::Point(135, 128));
+ _companion.setPosition(Common::Point(135, 128));
}
- _actor3.postInit();
- _actor4.postInit();
+ _balloon.postInit();
+ _harness.postInit();
- if (R2_INVENTORY.getObjectScene(20) == 2350) {
- _actor3.hide();
- _actor4.hide();
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2350) {
+ _balloon.hide();
+ _harness.hide();
} else {
- _actor3.setup(2350, 0, 1);
- _actor3.setPosition(Common::Point(197, 101));
- _actor3.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
- _actor3.fixPriority(10);
- _actor4.setup(2350, 1, 2);
- _actor4.setPosition(Common::Point(199, 129));
- _actor4.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
- _actor4.fixPriority(10);
- }
- _item1.setDetails(Rect(0, 0, 320, 200), 2000, 9, -1, -1, 1, NULL);
+ _balloon.setup(2350, 0, 1);
+ _balloon.setPosition(Common::Point(197, 101));
+ _balloon.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _balloon.fixPriority(10);
+ _harness.setup(2350, 1, 2);
+ _harness.setPosition(Common::Point(199, 129));
+ _harness.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _harness.fixPriority(10);
+ }
+ _background.setDetails(Rect(0, 0, 320, 200), 2000, 9, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 34) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] != 34) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2351;
else
_sceneMode = 2353;
@@ -1156,11 +1170,11 @@ void Scene2350::remove() {
void Scene2350::signal() {
switch (_sceneMode) {
case 11:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 34;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 34;
g_globals->_sceneManager.changeScene(2000);
break;
case 12:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 29;
g_globals->_sceneManager.changeScene(2000);
break;
case 20:
@@ -1169,12 +1183,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:
@@ -1188,22 +1202,12 @@ void Scene2350::signal() {
}
}
-void Scene2350::process(Event &event) {
- if ((R2_GLOBALS._player._canWalk) && (event.eventType != EVENT_BUTTON_DOWN) &&
- (R2_GLOBALS._events.getCursor() == CURSOR_CROSSHAIRS)){
- Common::Point pt(event.mousePos.x, 129);
- PlayerMover *mover = new PlayerMover();
- R2_GLOBALS._player.addMover(mover, &pt);
- event.handled = true;
- }
- Scene::process(event);
-}
-
/*--------------------------------------------------------------------------
- * Scene 2400 - Ice Maze: Large empty room
+ * Scene 2400 - Spill Mountains: Large empty room
*
*--------------------------------------------------------------------------*/
-void Scene2400::Exit1::changeScene() {
+
+void Scene2400::WestExit::changeScene() {
Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -1215,7 +1219,7 @@ void Scene2400::Exit1::changeScene() {
}
-void Scene2400::Exit2::changeScene() {
+void Scene2400::EastExit::changeScene() {
Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -1229,14 +1233,14 @@ void Scene2400::Exit2::changeScene() {
void Scene2400::postInit(SceneObjectList *OwnerList) {
loadScene(2400);
SceneExt::postInit();
- _exit1.setDetails(Rect(0, 125, 14, 165), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(14, 150));
- _exit2.setDetails(Rect(305, 125, 320, 165), EXITCURSOR_E, 2000);
- _exit2.setDest(Common::Point(315, 150));
+ _westExit.setDetails(Rect(0, 125, 14, 165), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 150));
+ _eastExit.setDetails(Rect(305, 125, 320, 165), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 150));
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._v56605[1] == 16) {
+ if (R2_GLOBALS._spillLocation[R2_QUINN] == 16) {
_sceneMode = 2400;
setAction(&_sequenceManager, this, 2400, &R2_GLOBALS._player, NULL);
} else {
@@ -1248,11 +1252,11 @@ void Scene2400::postInit(SceneObjectList *OwnerList) {
void Scene2400::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._v56605[1] = 16;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 16;
g_globals->_sceneManager.changeScene(2000);
break;
case 11:
- R2_GLOBALS._v56605[1] = 17;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 17;
g_globals->_sceneManager.changeScene(2000);
break;
default:
@@ -1262,102 +1266,102 @@ void Scene2400::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2425 - Ice Maze:
+ * Scene 2425 - Spill Mountains: The Hall Of Records
*
*--------------------------------------------------------------------------*/
-bool Scene2425::Item1::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2425::RopeDest1::startAction(CursorType action, Event &event) {
+ if ((action == R2_CURSOR_ROPE) && (!R2_GLOBALS.getFlag(84))) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
- if ((action == R2_GUNPOWDER) && (!R2_GLOBALS.getFlag(84))) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2426;
- scene->setAction(&scene->_sequenceManager, scene, 2426, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2426, &R2_GLOBALS._player, &scene->_rope, NULL);
R2_GLOBALS.setFlag(84);
return true;
- } else if (action == R2_GUNPOWDER) {
- R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
- R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
- return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ } else if (action == R2_CURSOR_ROPE) {
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ return NamedHotspot::startAction(CURSOR_USE, event);
} else
return NamedHotspot::startAction(action, event);
}
-bool Scene2425::Item2::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2425::RopeDest2::startAction(CursorType action, Event &event) {
+ if ((action == R2_CURSOR_ROPE) && (R2_GLOBALS.getFlag(84))) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
- if ((action == R2_GUNPOWDER) && (R2_GLOBALS.getFlag(84))) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2427;
- scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_rope, NULL);
R2_GLOBALS.clearFlag(84);
return true;
- } else if (action == R2_GUNPOWDER) {
- R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
- R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
- return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ } else if (action == R2_CURSOR_ROPE) {
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ return NamedHotspot::startAction(CURSOR_USE, event);
} else
return NamedHotspot::startAction(action, event);
}
-bool Scene2425::Item3::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
-
- if (action != R2_GUNPOWDER)
+bool Scene2425::Crevasse::startAction(CursorType action, Event &event) {
+ if (action != R2_CURSOR_ROPE)
return NamedHotspot::startAction(action, event);
else {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(84)) {
scene->_sceneMode = 20;
- scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_rope, NULL);
R2_GLOBALS.clearFlag(84);
} else {
scene->_sceneMode = 2425;
- scene->setAction(&scene->_sequenceManager, scene, 2425, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2425, &R2_GLOBALS._player, &scene->_rope, NULL);
}
return true;
}
}
-bool Scene2425::Item4::startAction(CursorType action, Event &event) {
- if (action != R2_GUNPOWDER)
+bool Scene2425::Background::startAction(CursorType action, Event &event) {
+ if (action != R2_CURSOR_ROPE)
return NamedHotspot::startAction(action, event);
else {
- R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
- R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
- return NamedHotspot::startAction(R2_STEPPING_DISKS, event);
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ return NamedHotspot::startAction(CURSOR_USE, event);
}
}
-bool Scene2425::Actor1::startAction(CursorType action, Event &event) {
- if (action == R2_STEPPING_DISKS) {
- if (R2_GLOBALS._player._characterIndex == 2) {
- R2_GLOBALS._events.setCursor(R2_GUNPOWDER);
+bool Scene2425::Rope::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ R2_GLOBALS._events.setCursor(R2_CURSOR_ROPE);
return true;
} else {
return SceneActor::startAction(action, event);
}
- } else if (R2_GLOBALS._events.getCursor() == R2_GUNPOWDER)
+ } else if (R2_GLOBALS._events.getCursor() == R2_CURSOR_ROPE)
return false;
else
return SceneActor::startAction(action, event);
}
-bool Scene2425::Actor2::startAction(CursorType action, Event &event) {
- if (action != R2_GUNPOWDER)
+bool Scene2425::Pictographs::startAction(CursorType action, Event &event) {
+ if (action != R2_CURSOR_ROPE)
return SceneActor::startAction(action, event);
else {
- R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
- R2_GLOBALS._player.enableControl(R2_STEPPING_DISKS);
- return SceneActor::startAction(R2_STEPPING_DISKS, event);
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ return SceneActor::startAction(CURSOR_USE, event);
}
}
-void Scene2425::Exit1::changeScene() {
+void Scene2425::SouthEastExit::changeScene() {
Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
@@ -1376,11 +1380,11 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._sound1.play(200);
- _exit1.setDetails(Rect(270, 136, 319, 168), EXITCURSOR_SE, 2000);
+ _southEastExit.setDetails(Rect(270, 136, 319, 168), EXITCURSOR_SE, 2000);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -1388,41 +1392,39 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor2.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor2.setup(20, 5, 1);
- _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _pictographs1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _pictographs1.setup(20, 5, 1);
+ _pictographs1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor2.setup(2008, 5, 1);
- _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _pictographs1.setup(2008, 5, 1);
+ _pictographs1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor2.setPosition(Common::Point(250, 185));
+ _pictographs1.setPosition(Common::Point(250, 185));
}
- _actor1.postInit();
+ _rope.postInit();
if (R2_GLOBALS._sceneManager._previousScene == 2455)
- _actor1.setup(2426, 1, 1);
+ _rope.setup(2426, 1, 1);
else
- _actor1.setup(2426, 1, 2);
-
- _actor1.setPosition(Common::Point(290, 9));
- _actor1.fixPriority(20);
- _actor1.setDetails(2455, 12, -1, -1, 1, (SceneItem *)NULL);
- _item1.setDetails(Rect(225, 52, 248, 65), 2425, -1, -1, -1, 1, NULL);
- _item2.setDetails(Rect(292, 81, 316, 94), 2425, -1, -1, -1, 1, NULL);
-
-// CHECKME: SceneActor using a SceneItem function??
-// _actor3.setDetails(11, 2425, 3, -1, 6);
- _actor3._sceneRegionId = 11;
- _actor3._resNum = 2425;
- _actor3._lookLineNum = 3;
- _actor3._talkLineNum = -1;
- _actor3._useLineNum = 6;
- g_globals->_sceneItems.push_back(&_actor3);
-
- _item3.setDetails(12, 2425, 7, -1, 9);
- _item4.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL);
+ _rope.setup(2426, 1, 2);
+
+ _rope.setPosition(Common::Point(290, 9));
+ _rope.fixPriority(20);
+ _rope.setDetails(2455, 12, -1, -1, 1, (SceneItem *)NULL);
+ _ropeDest1.setDetails(Rect(225, 52, 248, 65), 2425, -1, -1, -1, 1, NULL);
+ _ropeDest2.setDetails(Rect(292, 81, 316, 94), 2425, -1, -1, -1, 1, NULL);
+
+ _pictographs2._sceneRegionId = 11;
+ _pictographs2._resNum = 2425;
+ _pictographs2._lookLineNum = 3;
+ _pictographs2._talkLineNum = -1;
+ _pictographs2._useLineNum = 6;
+ g_globals->_sceneItems.push_back(&_pictographs2);
+
+ _crevasse.setDetails(12, 2425, 7, -1, 9);
+ _background.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
@@ -1442,7 +1444,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
break;
case 2455:
_sceneMode = 2428;
- setAction(&_sequenceManager, this, 2428, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2428, &R2_GLOBALS._player, &_rope, NULL);
break;
default:
R2_GLOBALS._player.setPosition(Common::Point(280, 150));
@@ -1465,7 +1467,7 @@ void Scene2425::signal() {
break;
case 20:
_sceneMode = 2425;
- setAction(&_sequenceManager, this, 2425, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2425, &R2_GLOBALS._player, &_rope, NULL);
break;
case 2425:
g_globals->_sceneManager.changeScene(2455);
@@ -1477,43 +1479,43 @@ void Scene2425::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2430 - Ice Maze: Bedroom
+ * Scene 2430 - Spill Mountains: Bedroom
*
*--------------------------------------------------------------------------*/
-bool Scene2430::Actor1::startAction(CursorType action, Event &event) {
+bool Scene2430::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2430::Actor2::startAction(CursorType action, Event &event) {
- Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
-
- if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2))
+bool Scene2430::GunPowder::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_GLOBALS._player._characterIndex != 2))
return SceneActor::startAction(action, event);
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2430;
- scene->setAction(&scene->_sequenceManager, scene, 2430, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2430, &R2_GLOBALS._player, &scene->_gunPowder, NULL);
return true;
}
-bool Scene2430::Actor3::startAction(CursorType action, Event &event) {
- Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
-
- if ((action != R2_STEPPING_DISKS) || (R2_GLOBALS._player._characterIndex != 2))
+bool Scene2430::OilLamp::startAction(CursorType action, Event &event) {
+ if ((action != CURSOR_USE) || (R2_GLOBALS._player._characterIndex != 2))
return SceneActor::startAction(action, event);
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2435;
- scene->setAction(&scene->_sequenceManager, scene, 2435, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2435, &R2_GLOBALS._player, &scene->_oilLamp, NULL);
return true;
}
-void Scene2430::Exit1::changeScene() {
+void Scene2430::SouthExit::changeScene() {
Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 0;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
Common::Point pt(108, 200);
@@ -1524,27 +1526,27 @@ void Scene2430::Exit1::changeScene() {
void Scene2430::postInit(SceneObjectList *OwnerList) {
loadScene(2430);
SceneExt::postInit();
- _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(108, 160));
-
- if (R2_INVENTORY.getObjectScene(37) == 2430) {
- _actor2.postInit();
- _actor2.setup(2435, 1, 5);
- _actor2.setPosition(Common::Point(205, 119));
- _actor2.fixPriority(152);
- _actor2.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
+ _southExit.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(108, 160));
+
+ if (R2_INVENTORY.getObjectScene(R2_GUNPOWDER) == 2430) {
+ _gunPowder.postInit();
+ _gunPowder.setup(2435, 1, 5);
+ _gunPowder.setPosition(Common::Point(205, 119));
+ _gunPowder.fixPriority(152);
+ _gunPowder.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(50) == 2435) {
- _actor3.postInit();
- _actor3.setup(2435, 1, 1);
- _actor3.setPosition(Common::Point(31, 65));
- _actor3.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2435) {
+ _oilLamp.postInit();
+ _oilLamp.setup(2435, 1, 1);
+ _oilLamp.setPosition(Common::Point(31, 65));
+ _oilLamp.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -1553,34 +1555,32 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(189, 137));
- R2_GLOBALS._walkRegions.enableRegion(4);
- }
-
- _item2.setDetails(Rect(11, 30, 37, 45), 2430, 3, -1, 5, 1, NULL);
- _item3.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL);
- _item4.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL);
- _item5.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL);
- _item6.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL);
- _item10.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL);
- _item7.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL);
- _item8.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL);
- _item9.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL);
- // CHECKME: initialized for the 2nd time??
- _item2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL);
- _item11.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL);
- _item12.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL);
- _item13.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _companion.setPosition(Common::Point(189, 137));
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ }
+
+ _furnishings.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL);
+ _rug1.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL);
+ _mirror.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL);
+ _garments.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL);
+ _post.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL);
+ _bed.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL);
+ _towel.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL);
+ _bottles1.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL);
+ _bottles2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL);
+ _clothesPile1.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL);
+ _clothesPile2.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL);
+ _rug2.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2430;
@@ -1600,12 +1600,12 @@ void Scene2430::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2430:
- _actor2.remove();
+ _gunPowder.remove();
R2_INVENTORY.setObjectScene(R2_GUNPOWDER, 2);
R2_GLOBALS._player.enableControl();
break;
case 2435:
- _actor3.remove();
+ _oilLamp.remove();
R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2);
R2_GLOBALS._player.enableControl();
break;
@@ -1616,14 +1616,15 @@ void Scene2430::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2435 - Ice Maze: Throne room
+ * Scene 2435 - Spill Mountains: Throne room
*
*--------------------------------------------------------------------------*/
-bool Scene2435::Actor1::startAction(CursorType action, Event &event) {
+
+bool Scene2435::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2435::Actor2::startAction(CursorType action, Event &event) {
+bool Scene2435::Astor::startAction(CursorType action, Event &event) {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -1644,7 +1645,7 @@ bool Scene2435::Actor2::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 20;
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
- if ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS.getFlag(82))) {
+ if ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS.getFlag(82))) {
scene->_stripManager.start(605, scene);
return true;
} else if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2) {
@@ -1660,11 +1661,11 @@ bool Scene2435::Actor2::startAction(CursorType action, Event &event) {
}
}
-void Scene2435::Exit1::changeScene() {
+void Scene2435::SouthExit::changeScene() {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
Common::Point pt(175, 200);
@@ -1680,38 +1681,40 @@ void Scene2435::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_pharishaSpeaker);
- _exit1.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(175, 160));
- _actor2.postInit();
- _actor2.setup(2005, 3, 1);
- _actor2.setPosition(Common::Point(219, 106));
- _actor2.setDetails(2001, 25, 26, -1, 1, (SceneItem *)NULL);
+ _southExit.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(175, 160));
+ _astor.postInit();
+ _astor.setup(2005, 3, 1);
+ _astor.setPosition(Common::Point(219, 106));
+ _astor.setDetails(2001, 25, 26, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
R2_GLOBALS._player.setVisage(20);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- R2_GLOBALS._player.setPosition(Common::Point(715, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(175, 200));
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(107, 145));
- R2_GLOBALS._walkRegions.enableRegion(2);
+ _companion.setPosition(Common::Point(107, 145));
+ R2_GLOBALS._walkRegions.disableRegion(2);
}
- _item2.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL);
- _item3.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _leftWindow.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL);
+ _rightWindow.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
_sceneMode = 10;
@@ -1729,7 +1732,7 @@ void Scene2435::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
}
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2435;
- R2_GLOBALS._v56605[1 + R2_GLOBALS._player._characterIndex] = 12;
+ R2_GLOBALS._spillLocation[1 + R2_GLOBALS._player._characterIndex] = 12;
}
void Scene2435::remove() {
@@ -1746,27 +1749,28 @@ void Scene2435::signal() {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
case 30:
- R2_GLOBALS._player._characterScene[1] = 2435;
- R2_GLOBALS._player._characterScene[2] = 2435;
- R2_GLOBALS._player._oldCharacterScene[1] = 2435;
- R2_GLOBALS._player._oldCharacterScene[2] = 2435;
- R2_GLOBALS._v56605[1] = 12;
- R2_GLOBALS._v56605[2] = 12;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 2435;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2435;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 12;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 12;
R2_GLOBALS.setFlag(81);
_sceneMode = 2436;
R2_GLOBALS._player.setStrip(7);
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor1.setVisage(20);
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(20);
else
- _actor1.setVisage(2008);
- setAction(&_sequenceManager, this, 2436, &_actor1, NULL);
+ _companion.setVisage(2008);
+ setAction(&_sequenceManager, this, 2436, &_companion, NULL);
break;
case 2436:
- R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(2);
_sceneMode = 20;
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(709, this);
+ break;
default:
R2_GLOBALS._player.enableControl();
break;
@@ -1774,28 +1778,28 @@ void Scene2435::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2440 - Ice Maze: Another bedroom
+ * Scene 2440 - Spill Mountains: Another bedroom
*
*--------------------------------------------------------------------------*/
-bool Scene2440::Actor1::startAction(CursorType action, Event &event) {
+bool Scene2440::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2440::Actor2::startAction(CursorType action, Event &event) {
- Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2440::OilLamp::startAction(CursorType action, Event &event) {
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_SEEKER)) {
+ Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 2)){
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2440;
- scene->setAction(&scene->_sequenceManager, scene, 2440, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2440, &R2_GLOBALS._player, &scene->_oilLamp, NULL);
return true;
}
return SceneActor::startAction(action, event);
}
-void Scene2440::Exit1::changeScene() {
+void Scene2440::SouthEastExit::changeScene() {
Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -1811,20 +1815,20 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
R2_GLOBALS._sound1.play(200);
// Fix exit cursor, the original was using NW
- _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
- _exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(49) == 2440) {
- _actor2.postInit();
- _actor2.setup(2435, 1, 1);
- _actor2.setPosition(Common::Point(94, 80));
- _actor2.fixPriority(106);
- _actor2.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
+ _southEastExit.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
+ _southEastExit.setDest(Common::Point(210, 160));
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2440) {
+ _oilLamp.postInit();
+ _oilLamp.setup(2435, 1, 1);
+ _oilLamp.setPosition(Common::Point(94, 80));
+ _oilLamp.fixPriority(106);
+ _oilLamp.setDetails(2430, 48, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -1832,25 +1836,25 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
R2_GLOBALS._player.setPosition(Common::Point(210, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9002, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9002, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(38, 119));
+ _companion.setPosition(Common::Point(38, 119));
}
- _item2.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL);
- _item3.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL);
- _item4.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL);
- _item5.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL);
- _item6.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL);
- _item7.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _garments.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL);
+ _bedspread.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL);
+ _post.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL);
+ _rug.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL);
+ _furnishings.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL);
+ _bottles.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
@@ -1877,8 +1881,8 @@ void Scene2440::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2440:
- _actor2.remove();
- R2_INVENTORY.setObjectScene(49, 2);
+ _oilLamp.remove();
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2);
// No break on purpose
default:
R2_GLOBALS._player.enableControl();
@@ -1887,9 +1891,10 @@ void Scene2440::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2445 - Ice Maze:
+ * Scene 2445 - Spill Mountains:
*
*--------------------------------------------------------------------------*/
+
void Scene2445::postInit(SceneObjectList *OwnerList) {
loadScene(2445);
SceneExt::postInit();
@@ -1905,45 +1910,46 @@ void Scene2445::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2450 - Ice Maze: Another bedroom
+ * Scene 2450 - Spill Mountains: Another bedroom
*
*--------------------------------------------------------------------------*/
-bool Scene2450::Actor2::startAction(CursorType action, Event &event) {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2450::Parker::startAction(CursorType action, Event &event) {
+ if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 1)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2452;
- scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_parker, NULL);
return true;
}
return SceneActor::startAction(action, event);
}
-bool Scene2450::Actor3::startAction(CursorType action, Event &event) {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2450::CareTaker::startAction(CursorType action, Event &event) {
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._v565AE < 3) {
- ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._stripModifier < 3) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
+ ++R2_GLOBALS._stripModifier;
scene->_sceneMode = 20;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
- scene->_stripManager.start(699 + (R2_GLOBALS._v565AE * 2), scene);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ scene->_stripManager.start(699 + (R2_GLOBALS._stripModifier * 2), scene);
else
- scene->_stripManager.start(700 + (R2_GLOBALS._v565AE * 2), scene);
+ scene->_stripManager.start(700 + (R2_GLOBALS._stripModifier * 2), scene);
}
- return true;} else {
+ return true;
+ } else {
return SceneActor::startAction(action, event);
}
}
-void Scene2450::Exit1::changeScene() {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+void Scene2450::SouthWestExit::changeScene() {
+ if ((R2_GLOBALS._player._characterIndex == R2_SEEKER) || (R2_GLOBALS.getFlag(61))) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
- if ((R2_GLOBALS._player._characterIndex == 2) || (R2_GLOBALS.getFlag(61))) {
_enabled = false;
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.disableControl();
@@ -1953,7 +1959,7 @@ void Scene2450::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
} else {
_moving = false;
- SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
Common::Point pt(60, 140);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, NULL);
@@ -1966,66 +1972,66 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(200);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS._sceneManager._previousScene = 1900;
- R2_GLOBALS._player._oldCharacterScene[1] = 1900;
- R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1900;
}
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_caretakerSpeaker);
if (R2_GLOBALS.getFlag(72)) {
- _exit1.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000);
- _exit1.setDest(Common::Point(10, 160));
+ _southWestExit.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000);
+ _southWestExit.setDest(Common::Point(10, 160));
}
if (!R2_GLOBALS.getFlag(61)) {
- _actor2.postInit();
- _actor2.setVisage(2009);
- _actor2.setPosition(Common::Point(190, 119));
- _actor2.fixPriority(50);
- _actor2.setDetails(2450, 0, -1, -1, 1, (SceneItem *)NULL);
+ _parker.postInit();
+ _parker.setVisage(2009);
+ _parker.setPosition(Common::Point(190, 119));
+ _parker.fixPriority(50);
+ _parker.setDetails(2450, 0, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
case 1900:
- R2_GLOBALS._v565AE = 0;
- R2_GLOBALS._player._characterScene[1] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2450;
- R2_GLOBALS._player._oldCharacterScene[1] = 2450;
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
+ R2_GLOBALS._stripModifier = 0;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
R2_GLOBALS._player.setup(2450, 1, 1);
R2_GLOBALS._player.setPosition(Common::Point(126, 101));
setAction(&_sequenceManager, this, 2450, &R2_GLOBALS._player, NULL);
break;
case 2000:
_sceneMode = 2451;
- if (R2_GLOBALS._player._characterIndex == 1) {
- if (R2_GLOBALS._player._characterScene[2] == 2450) {
- _actor1.postInit();
- _actor1.setup(20, 6, 1);
- _actor1.setPosition(Common::Point(240, 120));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 2450) {
+ _companion.postInit();
+ _companion.setup(20, 6, 1);
+ _companion.setPosition(Common::Point(240, 120));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
}
setAction(&_sequenceManager, this, 2451, &R2_GLOBALS._player, NULL);
} else {
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2450;
- if (R2_GLOBALS._player._characterScene[1] == 2450) {
- _actor1.postInit();
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2450;
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 2450) {
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61))
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
else
- _actor1.setup(10, 6, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
- _actor1.setPosition(Common::Point(106, 111));
+ _companion.setup(10, 6, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
}
setAction(&_sequenceManager, this, 2456, &R2_GLOBALS._player, NULL);
}
break;
case 2450:
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.postInit();
if (R2_GLOBALS.getFlag(61)) {
R2_GLOBALS._player.setup(2008, 6, 1);
@@ -2035,24 +2041,24 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(106, 111));
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
if (R2_GLOBALS.getFlag(72)) {
- if (R2_GLOBALS._player._characterScene[2] == 2450) {
- _actor1.postInit();
- _actor1.setup(20, 6, 1);
- _actor1.setPosition(Common::Point(240, 120));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 2450) {
+ _companion.postInit();
+ _companion.setup(20, 6, 1);
+ _companion.setPosition(Common::Point(240, 120));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
}
} else {
- _actor1.postInit();
- _actor1.setup(20, 8, 1);
- _actor1.setPosition(Common::Point(93, 158));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.postInit();
+ _companion.setup(20, 8, 1);
+ _companion.setPosition(Common::Point(93, 158));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setup(2001, 7, 1);
- _actor3.setPosition(Common::Point(34, 153));
- _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setup(2001, 7, 1);
+ _careTaker.setPosition(Common::Point(34, 153));
+ _careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
- _exit1._enabled = false;
+ _southWestExit._enabled = false;
}
} else {
R2_GLOBALS._player.postInit();
@@ -2060,32 +2066,32 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setPosition(Common::Point(93, 158));
if (R2_GLOBALS.getFlag(72)) {
- if (R2_GLOBALS._player._characterScene[1] == 2450) {
- _actor1.postInit();
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 2450) {
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61)) {
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
} else {
- _actor1.setup(10, 6, 1);
+ _companion.setup(10, 6, 1);
}
- _actor1.setPosition(Common::Point(106, 111));
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
} else {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61)) {
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
} else {
- _actor1.setup(10, 6, 1);
+ _companion.setup(10, 6, 1);
}
- _actor1.setPosition(Common::Point(106, 111));
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setup(2001, 7, 1);
- _actor3.setPosition(Common::Point(34, 153));
- _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setup(2001, 7, 1);
+ _careTaker.setPosition(Common::Point(34, 153));
+ _careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
- _exit1._enabled = false;
+ _southWestExit._enabled = false;
}
}
R2_GLOBALS._player.enableControl();
@@ -2095,7 +2101,7 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
break;
default:
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(61)) {
R2_GLOBALS._player.setup(2008, 3, 1);
} else {
@@ -2110,9 +2116,9 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
break;
}
- _item2.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL);
- _item3.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _post.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL);
+ _bedspread.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
}
void Scene2450::remove() {
@@ -2126,21 +2132,21 @@ void Scene2450::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 20:
- if (R2_GLOBALS._v565AE == 3) {
+ if (R2_GLOBALS._stripModifier == 3) {
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._v565AE = 4;
+ R2_GLOBALS._stripModifier = 4;
_sceneMode = 2454;
- setAction(&_sequenceManager, this, 2454, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 2454, &_careTaker, NULL);
} else {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
- if (R2_GLOBALS._v565AE < 4)
+ if (R2_GLOBALS._stripModifier < 4)
R2_GLOBALS._player._canWalk = false;
}
break;
case 30:
R2_GLOBALS._player.disableControl();
_sceneMode = 2455;
- setAction(&_sequenceManager, this, 2455, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2455, &_companion, NULL);
break;
case 31:
R2_GLOBALS.setFlag(61);
@@ -2151,7 +2157,7 @@ void Scene2450::signal() {
break;
case 2452:
R2_GLOBALS.setFlag(61);
- _actor2.remove();
+ _parker.remove();
R2_GLOBALS._player.enableControl();
if (!R2_GLOBALS.getFlag(72)) {
R2_GLOBALS._player.setStrip(6);
@@ -2164,55 +2170,55 @@ void Scene2450::signal() {
_stripManager.start(700, this);
break;
case 2454:
- _exit1._enabled = true;
+ _southWestExit._enabled = true;
R2_GLOBALS.setFlag(72);
- _actor3.remove();
+ _careTaker.remove();
if (R2_GLOBALS.getFlag(61)) {
g_globals->_sceneManager.changeScene(2435);
} else {
_sceneMode = 31;
- if (R2_GLOBALS._player._characterIndex == 1) {
- setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, &_parker, NULL);
} else {
- setAction(&_sequenceManager, this, 2452, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 2452, &_companion, &_parker, NULL);
}
}
break;
case 2455:
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2000;
- R2_GLOBALS._v56605[2] = 3;
- _actor1.remove();
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2000;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 3;
+ _companion.remove();
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
- _actor1.postInit();
- _actor1.setDetails(9002, 0, 4, 3, 2, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setDetails(2001, 40, -1, -1, 2, (SceneItem *)NULL);
+ _companion.postInit();
+ _companion.setDetails(9002, 0, 4, 3, 2, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setDetails(2001, 40, -1, -1, 2, (SceneItem *)NULL);
_sceneMode = 2453;
- setAction(&_sequenceManager, this, 2453, &_actor3, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2453, &_careTaker, &_companion, NULL);
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 2455 - Ice Maze: Inside crevasse
+ * Scene 2455 - Spill Mountains: Inside crevasse
*
*--------------------------------------------------------------------------*/
-bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
- Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2455::Lamp::startAction(CursorType action, Event &event) {
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)) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2458;
- scene->_actor2._lookLineNum = 9;
- scene->_actor1.remove();
- scene->_actor3.postInit();
- scene->_actor3.setDetails(2455, 16, 1, -1, 2, (SceneItem *)NULL);
- scene->setAction(&scene->_sequenceManager, scene, 2458, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor3, NULL);
+ scene->_pool._lookLineNum = 9;
+ scene->_lamp.remove();
+ scene->_scrithKey.postInit();
+ scene->_scrithKey.setDetails(2455, 16, 1, -1, 2, (SceneItem *)NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2458, &R2_GLOBALS._player, &scene->_pool, &scene->_scrithKey, NULL);
return true;
}
}
@@ -2220,31 +2226,31 @@ bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
+bool Scene2455::Pool::startAction(CursorType action, Event &event) {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
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);
- scene->_actor1.setPosition(Common::Point(162, 165));
- scene->_actor1.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
+ scene->_lamp.postInit();
+ scene->_lamp.setup(2456, 3, 3);
+ scene->_lamp.setPosition(Common::Point(162, 165));
+ scene->_lamp.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
scene->_sceneMode = 11;
- scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_pool, NULL);
return true;
}
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);
- scene->_actor1.setPosition(Common::Point(162, 165));
- scene->_actor1.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
+ scene->_lamp.postInit();
+ scene->_lamp.setup(2456, 3, 3);
+ scene->_lamp.setPosition(Common::Point(162, 165));
+ scene->_lamp.setDetails(2455, 15, 1, -1, 2, (SceneItem *)NULL);
scene->_sceneMode = 12;
- scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2457, &R2_GLOBALS._player, &scene->_pool, NULL);
return true;
}
break;
@@ -2255,20 +2261,20 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2455::Actor3::startAction(CursorType action, Event &event) {
- Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2455::ScrithKey::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2459;
- scene->setAction(&scene->_sequenceManager, scene, 2459, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2459, &R2_GLOBALS._player, &scene->_scrithKey, NULL);
return true;
}
return SceneActor::startAction(action, event);
}
-void Scene2455::Exit1::changeScene() {
+void Scene2455::NorthExit::changeScene() {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2283,45 +2289,44 @@ 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)) {
- _actor1.postInit();
- _actor1.setup(2456, 3, 3);
- _actor1.setPosition(Common::Point(162, 165));
- _actor1.setDetails(2455, 15, 1, -1, 1, (SceneItem *)NULL);
- }
- } else {
- _actor3.postInit();
- _actor3.setup(2456, 3, 1);
- _actor3.setPosition(Common::Point(176, 165));
- _actor3.setDetails(2455, 16, 1, -1, 1, (SceneItem *)NULL);
+ _northExit.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
+
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
+ _scrithKey.postInit();
+ _scrithKey.setup(2456, 3, 1);
+ _scrithKey.setPosition(Common::Point(176, 165));
+ _scrithKey.setDetails(2455, 16, 1, -1, 1, (SceneItem *)NULL);
+ } else if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) ||
+ (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455)) {
+ _lamp.postInit();
+ _lamp.setup(2456, 3, 3);
+ _lamp.setPosition(Common::Point(162, 165));
+ _lamp.setDetails(2455, 15, 1, -1, 1, (SceneItem *)NULL);
}
- _actor2.postInit();
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
- _actor2.setup(2456, 3, 2);
- _actor2.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
+ _pool.postInit();
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
+ _pool.setup(2456, 3, 2);
+ _pool.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
} else {
- if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455))
- _actor2.setup(2455, 1, 1);
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) && (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455))
+ _pool.setup(2455, 1, 1);
else
- _actor2.setup(2456, 1, 1);
- _actor2.setDetails(2455, 3, 1, -1, 1, (SceneItem *)NULL);
+ _pool.setup(2456, 1, 1);
+ _pool.setDetails(2455, 3, 1, -1, 1, (SceneItem *)NULL);
}
- _actor2.setPosition(Common::Point(162, 165));
- _actor2.fixPriority(20);
- if (R2_INVENTORY.getObjectScene(29) != 2455)
- _actor2.animate(ANIM_MODE_2, NULL);
+ _pool.setPosition(Common::Point(162, 165));
+ _pool.fixPriority(20);
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) != 2455)
+ _pool.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.postInit();
- _item1.setDetails(Rect(0, 0, 320, 200), 2455, 0, 1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2455, 0, 1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2425) {
@@ -2349,23 +2354,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);
+ _scrithKey.remove();
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 2);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
@@ -2377,11 +2382,11 @@ void Scene2455::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2500 - Ice Maze: Large Cave
+ * Scene 2500 - Spill Mountains: Large Ledge
*
*--------------------------------------------------------------------------*/
-void Scene2500::Exit1::changeScene() {
+void Scene2500::WestExit::changeScene() {
Scene2500 *scene = (Scene2500 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2409,12 +2414,12 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == -1)
R2_GLOBALS._sceneManager._previousScene = 2000;
- _exit1.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(84, 104));
+ _westExit.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(84, 104));
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(11);
R2_GLOBALS._player._moveDiff = Common::Point(2, 1);
} else {
@@ -2422,20 +2427,20 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(21, 3, 1);
- _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(21, 3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 3, 1);
- _actor1.changeZoom(50);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 3, 1);
+ _companion.changeZoom(50);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(141, 94));
+ _companion.setPosition(Common::Point(141, 94));
}
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
@@ -2446,9 +2451,9 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.addMover(mover, &pt, this);
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100) {
_sceneMode = 2500;
- _actor2.postInit();
- _actor3.postInit();
- setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ _quinn.postInit();
+ _ship.postInit();
+ setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_quinn, &_ship, NULL);
} else {
R2_GLOBALS._player.setPosition(Common::Point(160, 150));
R2_GLOBALS._player.setStrip(3);
@@ -2465,7 +2470,7 @@ void Scene2500::signal() {
case 20:
R2_GLOBALS._player.disableControl();
_sceneMode = 2501;
- setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_quinn, &_ship, NULL);
break;
case 2500:
_sceneMode = 20;
@@ -2485,10 +2490,11 @@ void Scene2500::signal() {
* Scene 2525 - Furnace room
*
*--------------------------------------------------------------------------*/
-bool Scene2525::Item5::startAction(CursorType action, Event &event) {
- Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2525::StopCock::startAction(CursorType action, Event &event) {
if ((action == R2_REBREATHER_TANK) && (!R2_GLOBALS.getFlag(74))) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2526;
scene->setAction(&scene->_sequenceManager, scene, 2526, &R2_GLOBALS._player, NULL);
@@ -2498,23 +2504,23 @@ bool Scene2525::Item5::startAction(CursorType action, Event &event) {
return SceneItem::startAction(action, event);
}
-bool Scene2525::Actor3::startAction(CursorType action, Event &event) {
- Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2525::GlassDome::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2525;
- scene->setAction(&scene->_sequenceManager, scene, 2525, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2525, &R2_GLOBALS._player, &scene->_glassDome, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-void Scene2525::Exit1::changeScene() {
+void Scene2525::SouthExit::changeScene() {
Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2533,26 +2539,26 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(200);
R2_GLOBALS._sound2.play(207);
- _exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
+ _southExit.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
- if (R2_INVENTORY.getObjectScene(29) == 2525) {
- _actor3.postInit();
- _actor3.setup(2435, 1, 2);
- _actor3.setPosition(Common::Point(78, 155));
- _actor3.fixPriority(155);
- _actor3.setDetails(2525, 27, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2525) {
+ _glassDome.postInit();
+ _glassDome.setup(2435, 1, 2);
+ _glassDome.setPosition(Common::Point(78, 155));
+ _glassDome.fixPriority(155);
+ _glassDome.setDetails(2525, 27, -1, -1, 1, (SceneItem *)NULL);
}
- _actor2.postInit();
- _actor2.setup(2525, 1, 1);
- _actor2.setPosition(Common::Point(183, 114));
- _actor2.setDetails(2525, 15, -1, -1, 1, (SceneItem *)NULL);
- _actor2.animate(ANIM_MODE_2, NULL);
- _actor2._numFrames = 3;
+ _compressor.postInit();
+ _compressor.setup(2525, 1, 1);
+ _compressor.setPosition(Common::Point(183, 114));
+ _compressor.setDetails(2525, 15, -1, -1, 1, (SceneItem *)NULL);
+ _compressor.animate(ANIM_MODE_2, NULL);
+ _compressor._numFrames = 3;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(2008, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -2560,25 +2566,25 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(209, 162));
+ _companion.setPosition(Common::Point(209, 162));
- R2_GLOBALS._walkRegions.enableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(4);
}
- _item5.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL);
- _item3.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL);
- _item4.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL);
- _item2.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL);
+ _stopcock.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL);
+ _pipes1.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL);
+ _pipes2.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL);
+ _machine.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
@@ -2607,8 +2613,8 @@ void Scene2525::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2525:
- _actor3.remove();
- R2_INVENTORY.setObjectScene(29, 2);
+ _glassDome.remove();
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
R2_GLOBALS._player.enableControl();
break;
case 2526:
@@ -2622,56 +2628,57 @@ void Scene2525::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2530 - Ice Maze: Well
+ * Scene 2530 - Spill Mountains: Well
*
*--------------------------------------------------------------------------*/
-bool Scene2530::Actor2::startAction(CursorType action, Event &event) {
- Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+bool Scene2530::Flask::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2530;
- scene->setAction(&scene->_sequenceManager, scene, 2530, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2530, &R2_GLOBALS._player, &scene->_flask, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-bool Scene2530::Actor3::startAction(CursorType action, Event &event) {
- Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2530::Crank::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(73))
- SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2532;
- scene->setAction(&scene->_sequenceManager, scene, 2532, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2532, &R2_GLOBALS._player, &scene->_crank, NULL);
}
} else {
if (R2_GLOBALS.getFlag(73)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2533;
- scene->setAction(&scene->_sequenceManager, scene, 2533, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2533, &R2_GLOBALS._player, &scene->_crank, NULL);
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2531;
- scene->setAction(&scene->_sequenceManager, scene, 2531, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2531, &R2_GLOBALS._player, &scene->_crank, NULL);
}
}
return true;
}
-void Scene2530::Exit1::changeScene() {
+void Scene2530::SouthExit::changeScene() {
Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2688,31 +2695,31 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
loadScene(2530);
SceneExt::postInit();
- _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(108, 160));
+ _southExit.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(33) == 2530) {
- _actor2.postInit();
- _actor2.setup(2435, 1, 3);
- _actor2.setPosition(Common::Point(299, 80));
- _actor2.fixPriority(80);
- _actor2.setDetails(2530, 28, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 2530) {
+ _flask.postInit();
+ _flask.setup(2435, 1, 3);
+ _flask.setPosition(Common::Point(299, 80));
+ _flask.fixPriority(80);
+ _flask.setDetails(2530, 28, -1, -1, 1, (SceneItem *)NULL);
}
- _actor3.postInit();
+ _crank.postInit();
if (R2_GLOBALS.getFlag(73)) {
- _actor3.setup(2531, 4, 2);
- _actor3.setPosition(Common::Point(154, 130));
+ _crank.setup(2531, 4, 2);
+ _crank.setPosition(Common::Point(154, 130));
} else {
- _actor3.setup(2531, 4, 1);
- _actor3.setPosition(Common::Point(173, 131));
+ _crank.setup(2531, 4, 1);
+ _crank.setPosition(Common::Point(173, 131));
}
- _actor3.setDetails(2530, 22, -1, -1, 1, (SceneItem *)NULL);
+ _crank.setDetails(2530, 22, -1, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -2721,23 +2728,23 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(20, 130));
- R2_GLOBALS._walkRegions.enableRegion(1);
+ _companion.setPosition(Common::Point(20, 130));
+ R2_GLOBALS._walkRegions.disableRegion(1);
}
- _item2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL);
- _item5.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL);
- _item3.setDetails(Rect(256, 64, 311, 85), 2530, 31, -1, 33, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2530, 0, 1, -1, 1, NULL);
+ _crank2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL);
+ _rope.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL);
+ _shelf.setDetails(Rect(256, 64, 311, 85), 2530, 31, -1, 33, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2530, 0, 1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
@@ -2759,8 +2766,9 @@ void Scene2530::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2530:
- R2_INVENTORY.setObjectScene(33, 2);
- _actor2.remove();
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 2);
+ _flask.remove();
+ R2_GLOBALS._player.enableControl();
break;
case 2531:
// No break on purpose
@@ -2779,50 +2787,47 @@ void Scene2530::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2535 - Ice Maze: Tannery
+ * Scene 2535 - Spill Mountains: Tannery
*
*--------------------------------------------------------------------------*/
-bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
- Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2535::RebreatherTank::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
- scene->_sceneMode = 2536;
- scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL);
- } else {
- scene->_sceneMode = 2537;
- scene->setAction(&scene->_sequenceManager, scene, 2537, &R2_GLOBALS._player, &scene->_actor3, NULL);
- }
+
+ scene->_sceneMode = (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) ? 2536 : 2537;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_rebreatherTank, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-bool Scene2535::Actor4::startAction(CursorType action, Event &event) {
- Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2535::TannerMask::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2535;
- scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_tannerMask, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-void Scene2535::Exit1::changeScene() {
+void Scene2535::SouthExit::changeScene() {
Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2839,45 +2844,45 @@ 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) {
- _actor4.postInit();
- _actor4.setup(2435, 1, 4);
- _actor4.setPosition(Common::Point(47, 74));
- _actor4.fixPriority(74);
- _actor4.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
+ _southExit.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(210, 160));
+
+ if (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 2535) {
+ _tannerMask.postInit();
+ _tannerMask.setup(2435, 1, 4);
+ _tannerMask.setPosition(Common::Point(47, 74));
+ _tannerMask.fixPriority(74);
+ _tannerMask.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
- _actor3.postInit();
- _actor3.setup(2535, 3, 1);
- _actor3.setPosition(Common::Point(203, 131));
- _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
- R2_GLOBALS._walkRegions.enableRegion(6);
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
+ _rebreatherTank.postInit();
+ _rebreatherTank.setup(2535, 3, 1);
+ _rebreatherTank.setPosition(Common::Point(203, 131));
+ _rebreatherTank.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ R2_GLOBALS._walkRegions.disableRegion(6);
}
- if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) {
- _actor3.postInit();
- _actor3.setup(2536, 1, 2);
- _actor3.setPosition(Common::Point(164, 133));
- _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 0) && (R2_GLOBALS.getFlag(73))) {
+ _rebreatherTank.postInit();
+ _rebreatherTank.setup(2536, 1, 2);
+ _rebreatherTank.setPosition(Common::Point(164, 133));
+ _rebreatherTank.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
}
if (R2_GLOBALS.getFlag(73)) {
- _actor2.postInit();
- _actor2.setup(2536, 1, 1);
- _actor2.setPosition(Common::Point(160, 130));
- _actor2.fixPriority(122);
- _actor2.setDetails(2535, 37, -1, -1, 1, (SceneItem *)NULL);
+ _rope.postInit();
+ _rope.setup(2536, 1, 1);
+ _rope.setPosition(Common::Point(160, 130));
+ _rope.fixPriority(122);
+ _rope.setDetails(2535, 37, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
@@ -2886,26 +2891,26 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(210, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(245, 115));
- R2_GLOBALS._walkRegions.enableRegion(2);
+ _companion.setPosition(Common::Point(245, 115));
+ R2_GLOBALS._walkRegions.disableRegion(2);
}
- _item2.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL);
- _item3.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL);
- _item4.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL);
- _item5.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL);
- _item6.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL);
- _item7.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL);
+ _roof.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL);
+ _skin1.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL);
+ _skin2.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL);
+ _skin3.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL);
+ _skin4.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL);
+ _depression.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
@@ -2926,32 +2931,31 @@ void Scene2535::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2535:
- R2_INVENTORY.setObjectScene(32, 2);
- _actor4.remove();
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, R2_SEEKER);
+ _tannerMask.remove();
R2_GLOBALS._player.enableControl();
break;
case 2536:
- R2_INVENTORY.setObjectScene(20, 0);
- R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 0);
+ R2_GLOBALS._walkRegions.enableRegion(6);
if (!R2_GLOBALS.getFlag(73)) {
- _actor3.remove();
+ _rebreatherTank.remove();
R2_GLOBALS._player.enableControl();
} else {
_sceneMode = 20;
- _actor3.show();
- _actor3.setup(2536, 1, 2);
- _actor3.setDetails(3, 20, -1, -1, 3, (SceneItem *)NULL);
- _actor3.setPosition(Common::Point(164, 150));
- _actor3.fixPriority(130);
- _actor3._moveDiff.y = 1;
- Common::Point pt(164, 133);
- PlayerMover *mover = new PlayerMover();
- _actor3.addMover(mover, &pt, this);
+ _rebreatherTank.show();
+ _rebreatherTank.setup(2536, 1, 2);
+ _rebreatherTank.setDetails(3, 20, -1, -1, 3, (SceneItem *)NULL);
+ _rebreatherTank.setPosition(Common::Point(164, 150));
+ _rebreatherTank.fixPriority(130);
+
+ _rebreatherTank._moveDiff.y = 1;
+ ADD_MOVER(_rebreatherTank, 164, 133);
}
break;
case 2537:
- _actor3.remove();
- R2_INVENTORY.setObjectScene(20, 1);
+ _rebreatherTank.remove();
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
R2_GLOBALS._player.enableControl();
break;
case 20:
@@ -2963,9 +2967,10 @@ void Scene2535::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2600 - Ice Maze: Exit
+ * Scene 2600 - Spill Mountains: Exit
*
*--------------------------------------------------------------------------*/
+
Scene2600::Scene2600(): SceneExt() {
_rotation = NULL;
}
@@ -2980,6 +2985,8 @@ void Scene2600::postInit(SceneObjectList *OwnerList) {
loadScene(2600);
R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
R2_GLOBALS._sound1.fadeSound(214);
R2_GLOBALS._sound2.play(215);
_rotation = R2_GLOBALS._scenePalette.addRotation(176, 191, 1);
@@ -2994,6 +3001,7 @@ void Scene2600::postInit(SceneObjectList *OwnerList) {
void Scene2600::remove() {
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._uiElements._visible = true;
// _rotation->remove();
SceneExt::remove();
}
@@ -3004,57 +3012,65 @@ void Scene2600::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2700 - Forest Maze
+ * Scene 2700 - Outer Forest
*
*--------------------------------------------------------------------------*/
+
Scene2700::Scene2700(): SceneExt() {
- _field412 = _field414 = _field416 = 0;
+ _areaMode = _moveMode = _stripNumber = 0;
+
+ _walkRect1.set(70, 122, 90, 132);
+ _walkRect2.set(150, 122, 160, 132);
+ _walkRect3.set(90, 142, 130, 157);
+ _walkRect4.set(175, 137, 200, 147);
+ _walkRect5.set(280, 127, 300, 137);
+ _walkRect6.set(240, 157, 265, 167);
}
void Scene2700::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_areaMode);
+ s.syncAsSint16LE(_moveMode);
+ s.syncAsSint16LE(_stripNumber);
}
void Scene2700::Action1::signal() {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor2.animate(ANIM_MODE_5, NULL);
+ scene->_ghoulHome6.animate(ANIM_MODE_5, NULL);
}
void Scene2700::Action2::signal() {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor3.animate(ANIM_MODE_5, NULL);
+ scene->_ghoulHome7.animate(ANIM_MODE_5, NULL);
}
void Scene2700::Action3::signal() {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
setDelay(450 + R2_GLOBALS._randomSource.getRandomNumber(450));
- scene->_actor4.animate(ANIM_MODE_8, 1, NULL);
+ scene->_ghoulHome8.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2700::Action4::signal() {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
setDelay(300 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor5.animate(ANIM_MODE_8, 1, NULL);
+ scene->_ghoulHome9.animate(ANIM_MODE_8, 1, NULL);
}
-void Scene2700::Area1::process(Event &event) {
+void Scene2700::SouthExit::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 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;
- scene->_field414 = 2703;
- switch (scene->_field412) {
+ scene->_moveMode = 2703;
+ switch (scene->_areaMode) {
case 0:
// No break on purpose
case 6:
@@ -3097,14 +3113,14 @@ void Scene2700::Area1::process(Event &event) {
}
}
-void Scene2700::Area2::process(Event &event) {
+void Scene2700::EastExit::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 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;
- scene->_field414 = 2704;
- switch (scene->_field412) {
+ scene->_moveMode = 2704;
+ switch (scene->_areaMode) {
case 0: {
Common::Point pt(140, 162);
NpcMover *mover = new NpcMover();
@@ -3157,41 +3173,35 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.stop();
R2_GLOBALS._sound2.stop();
- _area1.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN);
- _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
- _rect1.set(70, 122, 90, 132);
- _rect2.set(150, 122, 160, 132);
- _rect3.set(90, 142, 130, 157);
- _rect4.set(175, 137, 200, 147);
- _rect5.set(280, 127, 300, 137);
- _rect6.set(240, 157, 265, 167);
-
- _actor2.postInit();
- _actor2.setup(2700, 1, 1);
- _actor2.setPosition(Common::Point(140, 29));
- _actor2.setAction(&_action1);
-
- _actor3.postInit();
- _actor3.setup(2700, 2, 1);
- _actor3.setPosition(Common::Point(213, 32));
- _actor3.setAction(&_action2);
-
- _actor4.postInit();
- _actor4.setup(2700, 3, 1);
- _actor4.setPosition(Common::Point(17, 39));
- _actor4.setAction(&_action3);
-
- _actor5.postInit();
- _actor5.setup(2700, 5, 1);
- _actor5.setPosition(Common::Point(17, 71));
- _actor5.setAction(&_action4);
-
- _item2.setDetails(Rect(52, 38, 68, 60), 2700, 4, -1, 6, 1, NULL);
- _item3.setDetails(Rect(113, 22, 127, 33), 2700, 4, -1, 6, 1, NULL);
- _item4.setDetails(Rect(161, 44, 170, 52), 2700, 4, -1, 6, 1, NULL);
- _item5.setDetails(Rect(221, 19, 233, 31), 2700, 4, -1, 6, 1, NULL);
- _item6.setDetails(Rect(235, 59, 250, 75), 2700, 4, -1, 6, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2700, 4, -1, 6, 1, NULL);
+ _southExit.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN);
+ _eastExit.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+
+ _ghoulHome6.postInit();
+ _ghoulHome6.setup(2700, 1, 1);
+ _ghoulHome6.setPosition(Common::Point(140, 29));
+ _ghoulHome6.setAction(&_action1);
+
+ _ghoulHome7.postInit();
+ _ghoulHome7.setup(2700, 2, 1);
+ _ghoulHome7.setPosition(Common::Point(213, 32));
+ _ghoulHome7.setAction(&_action2);
+
+ _ghoulHome8.postInit();
+ _ghoulHome8.setup(2700, 3, 1);
+ _ghoulHome8.setPosition(Common::Point(17, 39));
+ _ghoulHome8.setAction(&_action3);
+
+ _ghoulHome9.postInit();
+ _ghoulHome9.setup(2700, 5, 1);
+ _ghoulHome9.setPosition(Common::Point(17, 71));
+ _ghoulHome9.setAction(&_action4);
+
+ _ghoulHome1.setDetails(Rect(52, 38, 68, 60), 2700, 4, -1, 6, 1, NULL);
+ _ghoulHome2.setDetails(Rect(113, 22, 127, 33), 2700, 4, -1, 6, 1, NULL);
+ _ghoulHome3.setDetails(Rect(161, 44, 170, 52), 2700, 4, -1, 6, 1, NULL);
+ _ghoulHome4.setDetails(Rect(221, 19, 233, 31), 2700, 4, -1, 6, 1, NULL);
+ _ghoulHome5.setDetails(Rect(235, 59, 250, 75), 2700, 4, -1, 6, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2700, 4, -1, 6, 1, NULL);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -3204,15 +3214,15 @@ 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) {
_sceneMode = 2702;
- _field412 = 5;
+ _areaMode = 5;
setAction(&_sequenceManager, this, 2702, &R2_GLOBALS._player, NULL);
} else {
- _field412 = 0;
+ _areaMode = 0;
if (R2_GLOBALS._sceneManager._previousScene == 3900) {
_sceneMode = 2701;
setAction(&_sequenceManager, this, 2701, &R2_GLOBALS._player, NULL);
@@ -3227,26 +3237,26 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
void Scene2700::signal() {
switch (_sceneMode) {
case 10:
- switch (_field414) {
+ switch (_moveMode) {
case 1:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 2:
case 4:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2705, &R2_GLOBALS._player, NULL);
break;
case 3: {
- _sceneMode = _field414;
- _field412 = 1;
+ _sceneMode = _moveMode;
+ _areaMode = 1;
Common::Point pt(80, 127);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 1
@@ -3254,24 +3264,24 @@ void Scene2700::signal() {
}
break;
case 2:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 3:
case 4: {
- _sceneMode = _field414;
- _field412 = 2;
+ _sceneMode = _moveMode;
+ _areaMode = 2;
Common::Point pt(155, 127);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 2
@@ -3279,21 +3289,21 @@ void Scene2700::signal() {
}
break;
case 3:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 2:
case 4:
case 6: {
- _sceneMode = _field414;
- _field412 = 3;
+ _sceneMode = _moveMode;
+ _areaMode = 3;
Common::Point pt(115, 152);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 3
@@ -3301,21 +3311,21 @@ void Scene2700::signal() {
}
break;
case 4:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4:
case 5:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3323,21 +3333,21 @@ void Scene2700::signal() {
}
break;
case 5:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4: {
- _sceneMode = _field414;
- _field412 = 5;
+ _sceneMode = _moveMode;
+ _areaMode = 5;
Common::Point pt(285, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3348,11 +3358,11 @@ void Scene2700::signal() {
}
break;
case 6:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 3: {
- _sceneMode = _field414;
- _field412 = 6;
+ _sceneMode = _moveMode;
+ _areaMode = 6;
Common::Point pt(250, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3361,11 +3371,11 @@ void Scene2700::signal() {
case 1:
case 2:
case 4:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3373,21 +3383,21 @@ void Scene2700::signal() {
}
break;
case 2703:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 3:
case 6:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2703, &R2_GLOBALS._player, NULL);
break;
case 1:
case 2:
case 4:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3395,21 +3405,21 @@ void Scene2700::signal() {
}
break;
case 2704:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4:
case 5:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3417,23 +3427,23 @@ void Scene2700::signal() {
}
break;
case 2710:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 3:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 2:
case 5: {
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
Common::Point pt(164, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 4:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3445,36 +3455,36 @@ void Scene2700::signal() {
}
break;
case 11:
- R2_INVENTORY.setObjectScene(36, 0);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 0);
R2_GLOBALS._player.disableControl();
- _field412 = 0;
+ _areaMode = 0;
_sceneMode = 2700;
- setAction(&_sequenceManager, this, 2700, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2700, &_nej, NULL);
break;
case 12:
R2_GLOBALS._sound1.play(234);
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2711;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 13:
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2712;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 14:
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2713;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 15:
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 11;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 2700:
- _actor1.remove();
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _nej.remove();
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 2703:
g_globals->_sceneManager.changeScene(3900);
@@ -3483,31 +3493,32 @@ void Scene2700::signal() {
g_globals->_sceneManager.changeScene(2750);
break;
case 2710:
- _field416 = 1200;
+ // Start of Nej assault
+ _stripNumber = 1200;
_sceneMode = 12;
- _actor1.postInit();
- setAction(&_sequenceManager, this, 2710, &R2_GLOBALS._player, &_actor1, NULL);
+ _nej.postInit();
+ setAction(&_sequenceManager, this, 2710, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2711:
R2_GLOBALS._player.disableControl();
- _field416 = 1201;
+ _stripNumber = 1201;
_sceneMode = 13;
- setAction(&_sequenceManager, this, 2711, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2711, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2712:
R2_GLOBALS._player.disableControl();
- _field416 = 1202;
+ _stripNumber = 1202;
_sceneMode = 14;
- setAction(&_sequenceManager, this, 2712, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2712, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2713:
R2_GLOBALS._player.disableControl();
- _field416 = 1203;
- _sceneMode = 14;
- setAction(&_sequenceManager, this, 2713, &R2_GLOBALS._player, &_actor1, NULL);
+ _stripNumber = 1203;
+ _sceneMode = 15;
+ setAction(&_sequenceManager, this, 2713, &R2_GLOBALS._player, &_nej, NULL);
break;
default:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
@@ -3516,10 +3527,11 @@ void Scene2700::process(Event &event) {
if (R2_GLOBALS._events.getCursor() == R2_FLUTE) {
if (R2_GLOBALS._player._bounds.contains(event.mousePos)) {
_sceneMode = 10;
- _field414 = 2710;
+ _moveMode = 2710;
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- switch (_field412) {
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+
+ switch (_areaMode) {
case 0: {
_sceneMode = 2710;
Common::Point pt(164, 160);
@@ -3566,46 +3578,47 @@ void Scene2700::process(Event &event) {
default:
break;
}
- event.handled = true;
} else {
- SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
- } else if (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) {
- if (_rect1.contains(event.mousePos)) {
- if (!_rect1.contains(R2_GLOBALS._player._position)) {
+
+ event.handled = true;
+ } else if (R2_GLOBALS._events.getCursor() == CURSOR_WALK) {
+ if (_walkRect1.contains(event.mousePos)) {
+ if (!_walkRect1.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 1;
+ _moveMode = 1;
}
- } else if (_rect2.contains(event.mousePos)) {
- if (!_rect2.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect2.contains(event.mousePos)) {
+ if (!_walkRect2.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 2;
+ _moveMode = 2;
}
- } else if (_rect3.contains(event.mousePos)) {
- if (!_rect3.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect3.contains(event.mousePos)) {
+ if (!_walkRect3.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 3;
+ _moveMode = 3;
}
- } else if (_rect4.contains(event.mousePos)) {
- if (!_rect4.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect4.contains(event.mousePos)) {
+ if (!_walkRect4.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 4;
+ _moveMode = 4;
}
- } else if (_rect5.contains(event.mousePos)) {
- if (!_rect5.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect5.contains(event.mousePos)) {
+ if (!_walkRect5.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 5;
+ _moveMode = 5;
}
- } else if (_rect6.contains(event.mousePos)) {
- if (!_rect6.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect6.contains(event.mousePos)) {
+ if (!_walkRect6.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 6;
+ _moveMode = 6;
}
} else {
event.handled = true;
@@ -3613,9 +3626,9 @@ void Scene2700::process(Event &event) {
}
if (_sceneMode == 10) {
R2_GLOBALS._player.disableControl();
- switch (_field412) {
+ switch (_areaMode) {
case 0:
- if (_field414 >= 6) {
+ if (_moveMode >= 6) {
Common::Point pt(205, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3638,11 +3651,11 @@ void Scene2700::process(Event &event) {
break;
}
case 3:
- if (_field414 == 1) {
+ if (_moveMode == 1) {
Common::Point pt(80, 137);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if (_field414 == 6) {
+ } else if (_moveMode == 6) {
Common::Point pt(140, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3653,7 +3666,7 @@ void Scene2700::process(Event &event) {
}
break;
case 4:
- if (_field414 == 5) {
+ if (_moveMode == 5) {
Common::Point pt(235, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3685,19 +3698,20 @@ void Scene2700::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 2750 - Forest Maze
+ * Scene 2750 - Inner Forest
*
*--------------------------------------------------------------------------*/
+
Scene2750::Scene2750(): SceneExt() {
- _field412 = _field414 = _field416 = 0;
+ _areaMode = _moveMode = _stripNumber = 0;
}
void Scene2750::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_areaMode);
+ s.syncAsSint16LE(_moveMode);
+ s.syncAsSint16LE(_stripNumber);
}
void Scene2750::Action1::signal() {
@@ -3707,20 +3721,20 @@ void Scene2750::Action1::signal() {
case 1:
setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(240));
_actionIndex = 2;
- scene->_actor5.show();
- scene->_actor5.animate(ANIM_MODE_8, 1, NULL);
+ scene->_bird2.show();
+ scene->_bird2.animate(ANIM_MODE_8, 1, NULL);
break;
case 2:
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(600));
_actionIndex = 0;
- scene->_actor5.show();
- scene->_actor3.animate(ANIM_MODE_2, NULL);
+ scene->_bird2.show();
+ scene->_bird1.animate(ANIM_MODE_2, NULL);
break;
default:
setDelay(30);
_actionIndex = 1;
- scene->_actor3.animate(ANIM_MODE_6, NULL);
- scene->_actor4.animate(ANIM_MODE_8, 1, NULL);
+ scene->_bird1.animate(ANIM_MODE_6, NULL);
+ scene->_folliage1.animate(ANIM_MODE_8, 1, NULL);
break;
}
}
@@ -3729,20 +3743,20 @@ void Scene2750::Action2::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor6.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage2.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action3::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_actor7._position.x <= 320) {
+ if (scene->_folliage3._position.x <= 320) {
setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
} else {
setDelay(60);
- scene->_actor7.setPosition(Common::Point(-10, 25));
+ scene->_folliage3.setPosition(Common::Point(-10, 25));
Common::Point pt(330, 45);
NpcMover *mover = new NpcMover();
- scene->_actor7.addMover(mover, &pt, NULL);
+ scene->_folliage3.addMover(mover, &pt, NULL);
}
}
@@ -3750,38 +3764,38 @@ void Scene2750::Action4::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor8.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage4.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action5::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor9.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage5.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action6::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor10.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage6.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action7::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor11.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage7.animate(ANIM_MODE_8, 1, NULL);
}
-void Scene2750::Area1::process(Event &event) {
+void Scene2750::WestExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2752;
- switch (scene->_field412) {
+ scene->_moveMode = 2752;
+ switch (scene->_areaMode) {
case 1: {
scene->_sceneMode = 2752;
scene->setAction(&scene->_sequenceManager, scene, 2752, &R2_GLOBALS._player, NULL);
@@ -3805,14 +3819,14 @@ void Scene2750::Area1::process(Event &event) {
}
}
-void Scene2750::Area2::process(Event &event) {
+void Scene2750::EastExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2753;
- switch (scene->_field412) {
+ scene->_moveMode = 2753;
+ switch (scene->_areaMode) {
case 1: {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
@@ -3840,93 +3854,93 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
loadScene(2750);
R2_GLOBALS._sound2.stop();
SceneExt::postInit();
- _area1.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W);
- _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+ _westExit.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W);
+ _eastExit.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
- _rect1.set(30, 127, 155, 147);
- _rect2.set(130, 142, 210, 167);
- _rect3.set(-1, 137, 290, 147);
+ _walkRect1.set(30, 127, 155, 147);
+ _walkRect2.set(130, 142, 210, 167);
+ _walkRect3.set(-1, 137, 290, 147);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.changeSound(235);
- _actor2.postInit();
- _actor2.setup(2751, 1, 1);
- _actor2.setPosition(Common::Point(104, 158));
- _actor2.animate(ANIM_MODE_2, NULL);
- }
-
- _actor3.postInit();
- _actor3.setup(2750, 1, 1);
- _actor3.setPosition(Common::Point(188, 34));
- _actor3.animate(ANIM_MODE_2, NULL);
- _actor3._numFrames = 16;
-
- _actor4.postInit();
- _actor4.setup(2700, 4, 1);
- _actor4.setPosition(Common::Point(188, 37));
- _actor4.fixPriority(26);
-
- _actor5.postInit();
- _actor5.setup(2750, 2, 1);
- _actor5.setPosition(Common::Point(188, 34));
- _actor5.hide();
-
- _actor3.setAction(&_action1);
-
- _actor6.postInit();
- _actor6.setup(2750, 3, 1);
- _actor6.setPosition(Common::Point(9, 167));
- _actor6.fixPriority(252);
- _actor6.setAction(&_action2);
-
- _actor7.postInit();
- _actor7.setup(2750, 4, 1);
- _actor7.setPosition(Common::Point(-10, 25));
- _actor7.animate(ANIM_MODE_1, NULL);
- _actor7.setStrip2(4);
- _actor7._moveRate = 20;
- _actor7.setAction(&_action3);
-
- _actor8.postInit();
- _actor8.fixPriority(26);
- _actor8.setup(2750, 5, 1);
- _actor8.setPosition(Common::Point(258, 33));
- _actor8.setAction(&_action4);
-
- _actor9.postInit();
- _actor9.fixPriority(26);
- _actor9.setup(2750, 6, 1);
- _actor9.setPosition(Common::Point(61, 38));
- _actor9.setAction(&_action5);
-
- _actor10.postInit();
- _actor10.fixPriority(26);
- _actor10.setup(2750, 7, 1);
- _actor10.setPosition(Common::Point(69, 37));
- _actor10.setAction(&_action6);
-
- _actor11.postInit();
- _actor11.fixPriority(26);
- _actor11.setup(2750, 8, 1);
- _actor11.setPosition(Common::Point(80, 35));
- _actor11.setAction(&_action7);
-
- _item2.setDetails(Rect(29, 50, 35, 56), 2750, 3, -1, 5, 1, NULL);
- _item3.setDetails(Rect(47, 36, 54, 42), 2750, 3, -1, 5, 1, NULL);
- _item4.setDetails(Rect(193, 21, 206, 34), 2750, 3, -1, 5, 1, NULL);
- _item5.setDetails(Rect(301, 18, 315, 32), 2750, 3, -1, 5, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2700, 0, -1, 2, 1, NULL);
+ _fire.postInit();
+ _fire.setup(2751, 1, 1);
+ _fire.setPosition(Common::Point(104, 158));
+ _fire.animate(ANIM_MODE_2, NULL);
+ }
+
+ _bird1.postInit();
+ _bird1.setup(2750, 1, 1);
+ _bird1.setPosition(Common::Point(188, 34));
+ _bird1.animate(ANIM_MODE_2, NULL);
+ _bird1._numFrames = 16;
+
+ _folliage1.postInit();
+ _folliage1.setup(2700, 4, 1);
+ _folliage1.setPosition(Common::Point(188, 37));
+ _folliage1.fixPriority(26);
+
+ _bird2.postInit();
+ _bird2.setup(2750, 2, 1);
+ _bird2.setPosition(Common::Point(188, 34));
+ _bird2.hide();
+
+ _bird1.setAction(&_action1);
+
+ _folliage2.postInit();
+ _folliage2.setup(2750, 3, 1);
+ _folliage2.setPosition(Common::Point(9, 167));
+ _folliage2.fixPriority(252);
+ _folliage2.setAction(&_action2);
+
+ _folliage3.postInit();
+ _folliage3.setup(2750, 4, 1);
+ _folliage3.setPosition(Common::Point(-10, 25));
+ _folliage3.animate(ANIM_MODE_1, NULL);
+ _folliage3.setStrip2(4);
+ _folliage3._moveRate = 20;
+ _folliage3.setAction(&_action3);
+
+ _folliage4.postInit();
+ _folliage4.fixPriority(26);
+ _folliage4.setup(2750, 5, 1);
+ _folliage4.setPosition(Common::Point(258, 33));
+ _folliage4.setAction(&_action4);
+
+ _folliage5.postInit();
+ _folliage5.fixPriority(26);
+ _folliage5.setup(2750, 6, 1);
+ _folliage5.setPosition(Common::Point(61, 38));
+ _folliage5.setAction(&_action5);
+
+ _folliage6.postInit();
+ _folliage6.fixPriority(26);
+ _folliage6.setup(2750, 7, 1);
+ _folliage6.setPosition(Common::Point(69, 37));
+ _folliage6.setAction(&_action6);
+
+ _folliage7.postInit();
+ _folliage7.fixPriority(26);
+ _folliage7.setup(2750, 8, 1);
+ _folliage7.setPosition(Common::Point(80, 35));
+ _folliage7.setAction(&_action7);
+
+ _ghoulHome1.setDetails(Rect(29, 50, 35, 56), 2750, 3, -1, 5, 1, NULL);
+ _ghoulHome2.setDetails(Rect(47, 36, 54, 42), 2750, 3, -1, 5, 1, NULL);
+ _ghoulHome3.setDetails(Rect(193, 21, 206, 34), 2750, 3, -1, 5, 1, NULL);
+ _ghoulHome4.setDetails(Rect(301, 18, 315, 32), 2750, 3, -1, 5, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2700, 0, -1, 2, 1, NULL);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_nejSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
- _actor1.postInit();
- _actor1.setup(2752, 5, 1);
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setPosition(Common::Point(101, 148));
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
+ _nej.postInit();
+ _nej.setup(2752, 5, 1);
+ _nej.animate(ANIM_MODE_NONE, NULL);
+ _nej.setPosition(Common::Point(101, 148));
}
R2_GLOBALS._player.postInit();
@@ -3936,47 +3950,49 @@ 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);
R2_GLOBALS._player.setPosition(Common::Point(81, 165));
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- _field416 = 1204;
+
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripNumber = 1204;
_sceneMode = 11;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
} else {
_sceneMode = 2750;
- _field412 = 1;
+ _areaMode = 1;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2750, &R2_GLOBALS._player, NULL);
}
} else if (R2_GLOBALS._sceneManager._previousScene == 2800) {
_sceneMode = 2751;
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2751, &R2_GLOBALS._player, NULL);
} else {
- _field412 = 1;
+ _areaMode = 1;
R2_GLOBALS._player.setPosition(Common::Point(90, 137));
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.enableControl();
}
}
+
void Scene2750::signal() {
switch (_sceneMode) {
case 10:
- switch (_field414) {
+ switch (_moveMode) {
case 1:
- switch (_field412) {
+ switch (_areaMode) {
case 2: {
- _sceneMode = _field414;
- _field412 = 1;
+ _sceneMode = _moveMode;
+ _areaMode = 1;
Common::Point pt(90, 137);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3987,25 +4003,25 @@ void Scene2750::signal() {
}
break;
case 2: {
- _sceneMode = _field414;
- _field412 = 2;
+ _sceneMode = _moveMode;
+ _areaMode = 2;
Common::Point pt(170, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3:
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(210, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 2: {
- _sceneMode = _field414;
- _field412 = 3;
+ _sceneMode = _moveMode;
+ _areaMode = 3;
Common::Point pt(270, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4016,20 +4032,20 @@ void Scene2750::signal() {
}
break;
case 2752:
- switch (_field412) {
+ switch (_areaMode) {
case 1:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2752, &R2_GLOBALS._player, NULL);
break;
case 2: {
- _field412 = 1;
+ _areaMode = 1;
Common::Point pt(20, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4040,23 +4056,23 @@ void Scene2750::signal() {
}
break;
case 2753:
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(210, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 2: {
- _field412 = 3;
+ _areaMode = 3;
Common::Point pt(300, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2753, &R2_GLOBALS._player, NULL);
break;
default:
@@ -4076,30 +4092,31 @@ void Scene2750::signal() {
g_globals->_sceneManager.changeScene(2700);
break;
default:
- R2_GLOBALS._player.enableControl(R2_NEGATOR_GUN);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
void Scene2750::process(Event &event) {
- if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
- if (_rect1.contains(event.mousePos)) {
- if (!_rect1.contains(R2_GLOBALS._player._position)) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN)
+ && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
+ if (_walkRect1.contains(event.mousePos)) {
+ if (!_walkRect1.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 1;
+ _moveMode = 1;
}
- } else if (_rect2.contains(event.mousePos)) {
- if (!_rect2.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect2.contains(event.mousePos)) {
+ if (!_walkRect2.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 2;
+ _moveMode = 2;
}
- } else if (_rect3.contains(event.mousePos)) {
- if (!_rect3.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect3.contains(event.mousePos)) {
+ if (!_walkRect3.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 3;
+ _moveMode = 3;
}
} else {
event.handled = true;
@@ -4108,7 +4125,7 @@ void Scene2750::process(Event &event) {
if (_sceneMode == 10) {
R2_GLOBALS._player.disableControl();
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
@@ -4116,7 +4133,7 @@ void Scene2750::process(Event &event) {
}
break;
case 2:
- if (_field414 == 1) {
+ if (_moveMode == 1) {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4141,23 +4158,24 @@ void Scene2750::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 2800 - Exiting forest
+ * Scene 2800 - Guard post
*
*--------------------------------------------------------------------------*/
+
Scene2800::Scene2800(): SceneExt() {
- _field412 = 0;
+ _stripNumber = 0;
}
void Scene2800::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_stripNumber);
}
-bool Scene2800::Item2::startAction(CursorType action, Event &event) {
- Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2800::Outpost::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_GLOBALS.getFlag(47))) {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2805;
scene->setAction(&scene->_sequenceManager, scene, 2805, &R2_GLOBALS._player, NULL);
@@ -4166,23 +4184,23 @@ bool Scene2800::Item2::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene2800::Actor1::startAction(CursorType action, Event &event) {
+bool Scene2800::Guard::startAction(CursorType action, Event &event) {
Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS.setFlag(47);
- scene->_field412 = 1205;
+ scene->_stripNumber = 1205;
scene->_sceneMode = 2803;
- scene->_stripManager.start(scene->_field412, scene);
+ scene->_stripManager.start(scene->_stripNumber, scene);
return true;
} else if (action == R2_SONIC_STUNNER) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.disableControl();
R2_GLOBALS.setFlag(47);
scene->_sceneMode = 10;
- scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_nej, &scene->_guard, NULL);
return true;
} else
return SceneActor::startAction(action, event);
@@ -4195,10 +4213,10 @@ void Scene2800::Action1::signal() {
setDelay(120);
Common::Point pt(330, 25);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, NULL);
+ scene->_bird.addMover(mover, &pt, NULL);
} else {
setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
- scene->_object1.setPosition(Common::Point(-10, 45));
+ scene->_bird.setPosition(Common::Point(-10, 45));
}
}
@@ -4253,37 +4271,37 @@ void Scene2800::Action2::signal() {
case 4:
setDelay(18);
_object4.setStrip(4);
- scene->_actor1.setVisage(2800);
- scene->_actor1.setStrip(5);
- scene->_actor1.setFrame(1);
- scene->_actor1._numFrames = 5;
- scene->_actor1._moveRate = 5;
- scene->_actor1.setPosition(Common::Point(300, 104));
- scene->_actor1.fixPriority(110);
- scene->_actor1.changeZoom(100);
- scene->_actor1.show();
+ scene->_guard.setVisage(2800);
+ scene->_guard.setStrip(5);
+ scene->_guard.setFrame(1);
+ scene->_guard._numFrames = 5;
+ scene->_guard._moveRate = 5;
+ scene->_guard.setPosition(Common::Point(300, 104));
+ scene->_guard.fixPriority(110);
+ scene->_guard.changeZoom(100);
+ scene->_guard.show();
break;
case 5:
- scene->_actor1.animate(ANIM_MODE_5, this);
+ scene->_guard.animate(ANIM_MODE_5, this);
break;
case 6: {
- scene->_actor1.changeZoom(-1);
- scene->_actor1.setVisage(3107);
- scene->_actor1.animate(ANIM_MODE_1, NULL);
- scene->_actor1.setStrip(3);
- scene->_actor1.setPosition(Common::Point(297, 140));
- scene->_actor1._numFrames = 10;
- scene->_actor1._moveRate = 10;
- scene->_actor1._moveDiff = Common::Point(3, 2);
+ scene->_guard.changeZoom(-1);
+ scene->_guard.setVisage(3107);
+ scene->_guard.animate(ANIM_MODE_1, NULL);
+ scene->_guard.setStrip(3);
+ scene->_guard.setPosition(Common::Point(297, 140));
+ scene->_guard._numFrames = 10;
+ scene->_guard._moveRate = 10;
+ scene->_guard._moveDiff = Common::Point(3, 2);
Common::Point pt(297, 160);
NpcMover *mover = new NpcMover();
- scene->_actor1.addMover(mover, &pt, this);
+ scene->_guard.addMover(mover, &pt, this);
break;
}
case 7: {
- scene->_actor1.changeZoom(75);
- scene->_actor1.updateAngle(R2_GLOBALS._player._position);
+ scene->_guard.changeZoom(75);
+ scene->_guard.updateAngle(R2_GLOBALS._player._position);
Common::Point pt(105, 82);
NpcMover *mover = new NpcMover();
@@ -4309,7 +4327,7 @@ void Scene2800::Action2::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
- Common::Point pt(100, 64);
+ Common::Point pt(64, 100);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
@@ -4338,9 +4356,9 @@ void Scene2800::Action2::signal() {
break;
}
case 13:
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- scene->_field412 = 1207;
- scene->_stripManager.start(scene->_field412, this);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ scene->_stripNumber = 1207;
+ scene->_stripManager.start(scene->_stripNumber, this);
break;
case 14: {
R2_GLOBALS._player.disableControl();
@@ -4353,7 +4371,7 @@ void Scene2800::Action2::signal() {
}
case 15:
setDelay(18);
- scene->_actor1.updateAngle(R2_GLOBALS._player._position);
+ scene->_guard.updateAngle(R2_GLOBALS._player._position);
R2_GLOBALS._player.setVisage(2800);
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.setFrame(1);
@@ -4406,34 +4424,34 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound2.stop();
SceneExt::postInit();
- _object1.postInit();
- _object1.setup(2750, 4, 1);
- _object1.setPosition(Common::Point(-10, 25));
- _object1.animate(ANIM_MODE_1, NULL);
- _object1.setStrip2(4);
- _object1._moveRate = 20;
- _object1.setAction(&_action1);
-
- _actor3.postInit();
- _actor3.setup(2802, 1, 1);
- _actor3.setPosition(Common::Point(116, 80));
- _actor3.fixPriority(111);
- _actor3.animate(ANIM_MODE_2, NULL);
- _actor3._numFrames = 6;
+ _bird.postInit();
+ _bird.setup(2750, 4, 1);
+ _bird.setPosition(Common::Point(-10, 25));
+ _bird.animate(ANIM_MODE_1, NULL);
+ _bird.setStrip2(4);
+ _bird._moveRate = 20;
+ _bird.setAction(&_action1);
+
+ _lightBar.postInit();
+ _lightBar.setup(2802, 1, 1);
+ _lightBar.setPosition(Common::Point(116, 80));
+ _lightBar.fixPriority(111);
+ _lightBar.animate(ANIM_MODE_2, NULL);
+ _lightBar._numFrames = 6;
if (!R2_GLOBALS.getFlag(47)) {
- _actor1.postInit();
- _actor1.setVisage(3105);
- _actor1.setStrip(3);
- _actor1.setFrame(1);
- _actor1.setZoom(50);
- _actor1._moveDiff = Common::Point(2, 1);
- _actor1.setPosition(Common::Point(122, 82));
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setDetails(2800, -1, -1, -1, 1, (SceneItem *)NULL);
+ _guard.postInit();
+ _guard.setVisage(3105);
+ _guard.setStrip(3);
+ _guard.setFrame(1);
+ _guard.setZoom(50);
+ _guard._moveDiff = Common::Point(2, 1);
+ _guard.setPosition(Common::Point(122, 82));
+ _guard.animate(ANIM_MODE_NONE, NULL);
+ _guard.setDetails(2800, -1, -1, -1, 1, (SceneItem *)NULL);
}
- _item1.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4441,17 +4459,17 @@ 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);
+ _outpost.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
} else {
- _actor2.postInit();
- _actor2.setup(2752, 5, 1);
- _actor2.animate(ANIM_MODE_NONE, NULL);
- _actor2.changeZoom(100);
- _actor2._moveDiff = Common::Point(2, 1);
- _actor2.setPosition(Common::Point(101, 148));
+ _nej.postInit();
+ _nej.setup(2752, 5, 1);
+ _nej.animate(ANIM_MODE_NONE, NULL);
+ _nej.changeZoom(100);
+ _nej._moveDiff = Common::Point(2, 1);
+ _nej.setPosition(Common::Point(101, 148));
}
}
@@ -4462,7 +4480,8 @@ 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) {
+ _sceneMode = 2800;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(47)) {
R2_GLOBALS._player.setVisage(3110);
@@ -4472,7 +4491,8 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
} else {
_sceneMode = 2801;
- R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player, &_actor2, &_actor1, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player,
+ &_nej, &_guard, NULL);
}
}
@@ -4480,17 +4500,17 @@ void Scene2800::signal() {
switch (_sceneMode) {
case 10:
R2_GLOBALS._sound1.play(238);
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- _field412 = 1206;
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ _stripNumber = 1206;
_sceneMode = 2804;
- _stripManager.start(_field412, this);
+ _stripManager.start(_stripNumber, this);
break;
case 11:
- _actor2.remove();
- _object1.setAction(NULL);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _nej.remove();
+ _bird.setAction(NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
+ _outpost.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
break;
case 12:
R2_GLOBALS._sound1.fadeOut2(NULL);
@@ -4501,21 +4521,21 @@ void Scene2800::signal() {
g_globals->_sceneManager.changeScene(2750);
break;
case 2801:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._player._canWalk = false;
break;
case 2803:
R2_GLOBALS._player.disableControl();
_sceneMode = 10;
- setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_actor2, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_nej, &_guard, NULL);
break;
case 2804:
R2_GLOBALS._player.disableControl();
_sceneMode = 11;
- setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2805:
- _object1.remove();
+ _bird.remove();
setAction(&_action2);
break;
default:
@@ -4523,5 +4543,668 @@ void Scene2800::signal() {
}
}
+/*--------------------------------------------------------------------------
+ * Scene 2900 - Balloon Cutscene
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene2900::Scenery::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_USE:
+ SceneItem::display2(1, 5 + R2_GLOBALS._randomSource.getRandomNumber(5));
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(2900, 0);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(1, 10 + R2_GLOBALS._randomSource.getRandomNumber(5));
+ break;
+ default:
+ break;
+ }
+
+ event.handled = true;
+ return true;
+}
+
+bool Scene2900::ControlPanel::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_USE:
+ SceneItem::display2(2900, 5);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(2900, 3);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(2900, 4);
+ break;
+ default:
+ break;
+ }
+
+ event.handled = true;
+ return true;
+}
+
+bool Scene2900::Altimeter::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_USE:
+ SceneItem::display2(2900, 8);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(2900, 6);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(2900, 4);
+ break;
+ default:
+ break;
+ }
+
+ event.handled = true;
+ return true;
+}
+
+bool Scene2900::KnobLeft::startAction(CursorType action, Event &event) {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_USE:
+ if (scene->_majorMinorFlag || scene->_altitudeChanging ||
+ scene->_xAmount != scene->_xComparison) {
+ // Let your altitude stablize first
+ SceneItem::display2(2900, 17);
+ } else if (R2_GLOBALS._balloonAltitude / 48 == 0) {
+ // Maximum altitude
+ SceneItem::display2(2900, 15);
+ } else {
+ // Increase altitude
+ R2_GLOBALS._sound2.fadeSound(282);
+ scene->_altitudeChanging = true;
+ scene->_altitudeMajorChange = -1;
+ scene->_xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) - 1) * 25;
+ }
+ break;
+
+ case CURSOR_LOOK:
+ SceneItem::display2(2900, 9);
+ break;
+
+ case CURSOR_TALK:
+ SceneItem::display2(2900, 4);
+ break;
+
+ default:
+ break;
+ }
+
+ event.handled = true;
+ return true;
+}
+
+bool Scene2900::KnobRight::startAction(CursorType action, Event &event) {
+ switch (action) {
+ case CURSOR_USE: {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_majorMinorFlag || scene->_altitudeChanging ||
+ scene->_xAmount != scene->_xComparison) {
+ // Let your altitude stablize first
+ SceneItem::display2(2900, 17);
+ } else if (R2_GLOBALS._balloonAltitude / 48 >= 3) {
+ // Altitude is too low - cannot land here
+ SceneItem::display2(2900, 16);
+ } else {
+ // Decrease altitude
+ R2_GLOBALS._sound2.fadeSound(212);
+ scene->_altitudeChanging = true;
+ scene->_altitudeMajorChange = 1;
+ scene->_xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) + 1) * 25;
+ }
+ break;
+ }
+
+ case CURSOR_LOOK:
+ SceneItem::display2(2900, 12);
+ break;
+
+ case CURSOR_TALK:
+ SceneItem::display2(2900, 4);
+ break;
+
+ default:
+ break;
+ }
+
+ event.handled = true;
+ return true;
+}
+
+bool Scene2900::Skip::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE) {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 12;
+ scene->signal();
+ }
+
+ return true;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene2900::Action1::signal() {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+ setDelay(3);
+
+ if (!scene->_majorMinorFlag && !scene->_altitudeChanging) {
+ scene->_fadeCounter = 2;
+ scene->_controlsActiveChanging = false;
+ } else if (scene->_majorMinorFlag) {
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ } else if (scene->_fadeCounter == 0) {
+ R2_GLOBALS._sound2.fadeOut2(NULL);
+ } else if (!scene->_controlsActiveChanging) {
+ scene->_knobLeftContent.hide();
+ scene->_knobRightContent.hide();
+ scene->_controlsActiveChanging = true;
+ } else {
+ --scene->_fadeCounter;
+ scene->_knobLeftContent.show();
+ scene->_knobRightContent.show();
+ scene->_controlsActiveChanging = false;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene2900::Map::Map() {
+ _mapWidth = _mapHeight = 0;
+ _resNum = 0;
+ _xV = _yV = 0;
+ _bounds = Rect(40, 0, 280, 150);
+}
+
+void Scene2900::Map::load(int resNum) {
+ byte *data = g_resourceManager->getResource(RES_BITMAP, resNum, 9999);
+
+ _resNum = resNum;
+ _xV = _yV = 0;
+ _mapWidth = READ_LE_UINT16(data);
+ _mapHeight = READ_LE_UINT16(data + 2);
+
+ DEALLOCATE(data);
+}
+
+Common::Point Scene2900::Map::setPosition(const Common::Point &pos, bool initialFlag) {
+ Common::Point p = pos;
+ Rect updateRect;
+
+ if (p.x >= 0) {
+ int xRight = p.x + _bounds.width();
+ if (xRight > _mapWidth) {
+ p.x = _mapWidth - _bounds.width();
+ }
+ } else {
+ p.x = 0;
+ }
+
+ if (p.y >= 0) {
+ int yBottom = p.y + _bounds.height();
+ if (yBottom > _mapHeight) {
+ p.y = _mapHeight - _bounds.height();
+ }
+ } else {
+ p.y = 0;
+ }
+
+ if ((p.x != 0 || p.y != 0) && !initialFlag) {
+ moveArea(updateRect, _xV - p.x, _yV - p.y);
+ redraw(&updateRect);
+ } else {
+ redraw();
+ }
+
+ _xV = p.x;
+ _yV = p.y;
+ return Common::Point(_xV, _yV);
+}
+
+void Scene2900::Map::redraw(Rect *updateRect) {
+ int xHalfCount = _mapWidth / 160;
+ int yHalfCount = _mapHeight / 100;
+ int rlbNum = 0;
+
+ Rect blockRect(0, 0, 160, 100);
+ Rect screenRect = _bounds;
+ screenRect.translate(_xV - _bounds.left, _yV - _bounds.top);
+
+ Rect modifyRect;
+ if (updateRect)
+ modifyRect = *updateRect;
+
+ for (int xCtr = 0; xCtr < xHalfCount; ++xCtr) {
+ for (int yCtr = 0; yCtr < yHalfCount; ++yCtr, ++rlbNum) {
+ blockRect.moveTo(160 * xCtr, 100 * yCtr);
+ if (blockRect.intersects(screenRect)) {
+ // The block of the map is at least partially on-screen, so needs drawing
+ blockRect.translate(_bounds.left - _xV, _bounds.top - _yV);
+ byte *data = g_resourceManager->getResource(RES_BITMAP, _resNum, rlbNum);
+
+ drawBlock(data, blockRect.left, blockRect.top, _bounds, modifyRect);
+
+ DEALLOCATE(data);
+ }
+ }
+ }
+}
+
+void Scene2900::Map::synchronize(Serializer &s) {
+ s.syncAsUint16LE(_resNum);
+ if (s.isLoading())
+ load(_resNum);
+
+ s.syncAsSint16LE(_xV);
+ s.syncAsSint16LE(_yV);
+ _bounds.synchronize(s);
+}
+
+int Scene2900::Map::adjustRect(Common::Rect &r1, const Common::Rect &r2) {
+ if (r2.contains(r1))
+ return 0;
+ if (!r2.intersects(r1))
+ return 1;
+
+ if (r1.top >= r2.top && r1.bottom <= r2.bottom) {
+ if (r1.left >= r2.left && r1.left < r2.right) {
+ r1.left = r2.right - 1;
+ return 1;
+ }
+ if (r1.right > r2.left && r1.right <= r2.right) {
+ r1.right = r2.left + 1;
+ return 1;
+ }
+ }
+
+ if (r1.left < r2.left || r1.right > r2.right)
+ return -1;
+
+ if (r1.top >= r2.top && r1.top < r2.bottom) {
+ r1.top = r2.bottom - 1;
+ return 1;
+ }
+ if (r1.bottom > r2.top && r1.bottom <= r2.bottom) {
+ r1.bottom = r2.top + 1;
+ return 1;
+ }
+
+ return -1;
+}
+
+void Scene2900::Map::drawBlock(const byte *data, int xp, int yp,
+ const Rect &bounds, const Rect &updateRect) {
+ Rect blockRect(xp, yp, xp + 160, yp + 100);
+ const byte *src = data;
+
+ if (blockRect.intersects(bounds)) {
+ blockRect.clip(bounds);
+
+ if (adjustRect(blockRect, updateRect) != 0) {
+ int width = blockRect.width();
+ int height = blockRect.height();
+ src += (blockRect.top - yp) * 160 + blockRect.left - xp;
+
+ GfxSurface &surface = R2_GLOBALS._sceneManager._scene->_backSurface;
+ Graphics::Surface s = surface.lockSurface();
+
+ for (int yCtr = 0; yCtr < height; ++yCtr, src += 160) {
+ byte *destP = (byte *)s.getBasePtr(blockRect.left, blockRect.top + yCtr);
+ Common::copy(src, src + width, destP);
+ }
+
+ surface.unlockSurface();
+ R2_GLOBALS.gfxManager().copyFrom(surface, blockRect, blockRect);
+ }
+ }
+}
+
+void Scene2900::Map::moveArea(Rect &r, int xAmt, int yAmt) {
+ Rect tempRect = r;
+ tempRect.translate(xAmt, yAmt);
+ int xpSrc, xpDest, width;
+ int ypSrc, ypDest, height;
+
+ if (tempRect.intersects(r)) {
+ if (xAmt >= 0) {
+ xpSrc = tempRect.left;
+ width = tempRect.width() - xAmt;
+ xpDest = tempRect.left + xAmt;
+ } else {
+ xpSrc = tempRect.left - xAmt;
+ width = tempRect.width() + xAmt;
+ xpDest = tempRect.left;
+ }
+
+ if (yAmt > 0) {
+ height = tempRect.height() - yAmt;
+ ypDest = tempRect.top + yAmt + (height - 1);
+ ypSrc = tempRect.top + (height - 1);
+
+ for (int yCtr = 0; yCtr < height; ++yCtr, --ypSrc, --ypDest) {
+ moveLine(xpSrc, ypSrc, xpDest, ypDest, width);
+ }
+ } else {
+ ypSrc = tempRect.top - yAmt;
+ height = tempRect.height() + yAmt;
+ ypDest = tempRect.top;
+
+ for (int yCtr = 0; yCtr < height; ++yCtr, ++ypSrc, ++ypDest) {
+ moveLine(xpSrc, ypSrc, xpDest, ypDest, width);
+ }
+ }
+ } else {
+ r = Rect(0, 0, 0, 0);
+ }
+}
+
+void Scene2900::Map::moveLine(int xpSrc, int ypSrc, int xpDest, int ypDest, int width) {
+ byte buffer[SCREEN_WIDTH];
+ assert(width <= SCREEN_WIDTH);
+
+ GfxSurface &surface = R2_GLOBALS.gfxManager().getSurface();
+ Graphics::Surface s = surface.lockSurface();
+
+ byte *srcP = (byte *)s.getBasePtr(xpSrc, ypSrc);
+ byte *destP = (byte *)s.getBasePtr(xpDest, ypDest);
+ Common::copy(srcP, srcP + width, &buffer[0]);
+ Common::copy(&buffer[0], &buffer[width], destP);
+
+ surface.unlockSurface();
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene2900::Scene2900(): SceneExt() {
+ _controlsActiveChanging = false;
+ _altitudeChanging = false;
+ _majorMinorFlag = false;
+ _balloonLocation = Common::Point(550, 550);
+ _altitudeMinorChange = 0;
+ _altitudeMajorChange = 0;
+ _balloonScreenPos = Common::Point(160, 100);
+ _newAltitude = 0;
+ _xAmount = 100;
+ _xComparison = 100;
+ _fadeCounter = 0;
+ _paletteReloadNeeded = false;
+}
+
+void Scene2900::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_controlsActiveChanging);
+ s.syncAsSint16LE(_altitudeChanging);
+ s.syncAsSint16LE(_majorMinorFlag);
+ s.syncAsSint16LE(_altitudeMinorChange);
+ s.syncAsSint16LE(_altitudeMajorChange);
+ s.syncAsSint16LE(_balloonLocation.x);
+ s.syncAsSint16LE(_balloonLocation.y);
+ s.syncAsSint16LE(_balloonScreenPos.x);
+ s.syncAsSint16LE(_balloonScreenPos.y);
+ s.syncAsSint16LE(_newAltitude);
+ s.syncAsSint16LE(_xAmount);
+ s.syncAsSint16LE(_xComparison);
+ s.syncAsSint16LE(_fadeCounter);
+ s.syncAsSint16LE(_paletteReloadNeeded);
+
+ _map.synchronize(s);
+}
+
+void Scene2900::postInit(SceneObjectList *OwnerList) {
+ R2_GLOBALS._uiElements._active = false;
+ // TODO: Determine correct colors
+ R2_GLOBALS._gfxColors.foreground = 228;
+ R2_GLOBALS._fontColors.background = 12;
+ R2_GLOBALS._fontColors.foreground = 22;
+
+ _map.load(2950);
+
+ loadScene(2900);
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
+ _leftEdge.setup(2900, 6, 1, 22, 0, 25);
+ _rightEdge.setup(2900, 6, 1, 280, 0, 25);
+ _knob.setup(2900, 1, 3, 228, 199, 25);
+
+ _altimeterContent.postInit();
+ _altimeterContent.setVisage(2900);
+ _altimeterContent.setStrip(2);
+ _altimeterContent.setFrame(1);
+ _altimeterContent.fixPriority(10);
+
+ _knobLeftContent.postInit();
+ _knobLeftContent.setVisage(2900);
+ _knobLeftContent.setStrip(1);
+ _knobLeftContent.setFrame(1);
+ _knobLeftContent.setPosition(Common::Point(209, 199));
+ _knobLeftContent.fixPriority(200);
+
+ _knobRightContent.postInit();
+ _knobRightContent.setVisage(2900);
+ _knobRightContent.setStrip(1);
+ _knobRightContent.setFrame(2);
+ _knobRightContent.setPosition(Common::Point(247, 199));
+ _knobRightContent.fixPriority(200);
+
+ // Set up hotspots
+ _scenery.setDetails(Rect(0, 0, 320, 150), 2900, -1, -1, -1, 1, (SceneItem *)NULL);
+ _controlPanel.setDetails(Rect(0, 150, 320, 200), 2900, -1, -1, -1, 1, (SceneItem *)NULL);
+ _altimeter.setDetails(Rect(42, 164, 129, 190), 2900, -1, -1, -1, 2, (SceneItem *)NULL);
+ _knobLeft.setDetails(Rect(165, 160, 228, 200), 2900, -1, -1, -1, 2, (SceneItem *)NULL);
+ _knobRight.setDetails(Rect(228, 160, 285, 200), 2900, -1, -1, -1, 2, (SceneItem *)NULL);
+ _skip.postInit();
+ _skip.setBounds(185, 50, 200, 0);
+ R2_GLOBALS._sceneItems.push_front(&_skip);
+
+ // For ScummVM, we're introducing a Skip button, since the scene is a pain
+ _skipText._color1 = R2_GLOBALS._scenePalette._colors.foreground;
+ _skipText._color2 = R2_GLOBALS._scenePalette._colors.background;
+ _skipText.setPosition(Common::Point(0, 185));
+ _skipText.setup("Skip");
+
+ setAction(&_action1);
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.setVisage(2900);
+ R2_GLOBALS._player.setStrip2(3);
+ R2_GLOBALS._player.setFrame2(1);
+ R2_GLOBALS._player.fixPriority(15);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_GLOBALS._sceneManager._previousScene == 2350 &&
+ R2_GLOBALS._balloonPosition.x == 0 && R2_GLOBALS._balloonPosition.y == 0) {
+ R2_GLOBALS._balloonAltitude = 5;
+ _map.setPosition(Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100));
+ _sceneMode = 10;
+
+ R2_GLOBALS._player.changeZoom(100);
+ R2_GLOBALS._player.setPosition(Common::Point(160, 180));
+ ADD_PLAYER_MOVER(160, 100);
+
+ _altimeterContent.setPosition(Common::Point(9, 189));
+ } else {
+ _balloonLocation.x = R2_GLOBALS._balloonPosition.x + 120;
+ _balloonLocation.y = R2_GLOBALS._balloonPosition.y + 100;
+
+ if ((R2_GLOBALS._balloonAltitude % 8) == 0)
+ _balloonLocation.x -= 70;
+ else if ((R2_GLOBALS._balloonAltitude % 8) == 7)
+ _balloonLocation.x += 70;
+
+ if (_balloonLocation.x <= 120)
+ _balloonScreenPos.x = _balloonLocation.x + 40;
+ else if (_balloonLocation.x >= 680)
+ _balloonScreenPos.x = _balloonLocation.x - 520;
+
+ if ((R2_GLOBALS._balloonAltitude / 6) == 5)
+ _balloonLocation.y -= 50;
+ if (_balloonLocation.y <= 100)
+ _balloonScreenPos.y = _balloonLocation.y;
+
+ _xAmount = _xComparison = 100 - (R2_GLOBALS._balloonAltitude / 48) * 25;
+ _map.setPosition(Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100));
+ _sceneMode = 11;
+
+ R2_GLOBALS._player.changeZoom(_xAmount);
+ R2_GLOBALS._player.setPosition(_balloonScreenPos);
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ _altimeterContent.setPosition(Common::Point(109 - _xAmount, 189));
+ }
+
+ R2_GLOBALS._sound1.play(211);
+}
+
+void Scene2900::remove() {
+ // TODO: Figure out correct colors
+ R2_GLOBALS._gfxColors.foreground = 59;
+ R2_GLOBALS._fontColors.background = 4;
+ R2_GLOBALS._fontColors.foreground = 15;
+
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 255, 255, 255);
+
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound2.stop();
+
+ R2_GLOBALS._interfaceY = UI_INTERFACE_Y;
+ SceneExt::remove();
+}
+
+void Scene2900::signal() {
+ switch (_sceneMode) {
+ case 10:
+ _sceneMode = 11;
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 12:
+ R2_GLOBALS._sceneManager.changeScene(2600);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene2900::dispatch() {
+ if (_sceneMode == 11) {
+ _balloonLocation.x += balloonData[R2_GLOBALS._balloonAltitude].x;
+ _balloonLocation.y += balloonData[R2_GLOBALS._balloonAltitude].y;
+ _altitudeMinorChange = balloonData[R2_GLOBALS._balloonAltitude].v3;
+
+ if (_altitudeMinorChange == 0) {
+ _majorMinorFlag = false;
+ } else {
+ _majorMinorFlag = true;
+ _altitudeChanging = false;
+ _xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) + _altitudeMinorChange) * 25;
+ }
+
+ // Zooming/altitude balloon change
+ if (_xAmount == _xComparison) {
+ _majorMinorFlag = false;
+ } else {
+ if (!_majorMinorFlag) {
+ _xAmount = _xAmount - _altitudeMajorChange;
+ } else {
+ _xAmount = _xAmount - _altitudeMinorChange;
+ }
+
+ if (_altitudeMinorChange == -1 || _altitudeMajorChange == -1) {
+ if (_altimeterContent._frame == 1) {
+ _altimeterContent.setFrame2(10);
+ } else {
+ _altimeterContent.setFrame2(_altimeterContent._frame - 1);
+ }
+ } else if (_altitudeMinorChange == -1 || _altitudeMajorChange == 1) {
+ if (_altimeterContent._frame == 10)
+ _altimeterContent.setFrame2(1);
+ else
+ _altimeterContent.setFrame2(_altimeterContent._frame + 1);
+ }
+
+ _altimeterContent.setPosition(Common::Point(109 - _xAmount, 189));
+ R2_GLOBALS._player.changeZoom(_xAmount);
+ }
+
+ if (!_paletteReloadNeeded) {
+ R2_GLOBALS._scenePalette.loadPalette(2950);
+ R2_GLOBALS._scenePalette.refresh();
+ }
+
+ R2_GLOBALS._balloonPosition = _map.setPosition(
+ Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100), !_paletteReloadNeeded);
+ _paletteReloadNeeded = true;
+
+ if (_balloonLocation.x <= 120)
+ _balloonScreenPos.x = _balloonLocation.x + 40;
+ else if (_balloonLocation.x >= 680)
+ _balloonScreenPos.x = _balloonLocation.x - 520;
+
+ if (_balloonLocation.y <= 100)
+ _balloonScreenPos.y = _balloonLocation.y;
+
+ R2_GLOBALS._player.setPosition(_balloonScreenPos);
+
+ if ((_balloonLocation.x % 100) == 50 && (_balloonLocation.y % 100) == 50 && !_majorMinorFlag) {
+ // At an altitude change point, so calculate new altitude
+ _newAltitude = R2_GLOBALS._balloonAltitude;
+ if (_altitudeChanging) {
+ _newAltitude += _altitudeMajorChange * 48;
+ _altitudeChanging = false;
+ }
+
+ if (balloonData[R2_GLOBALS._balloonAltitude].x > 0) {
+ ++_newAltitude;
+ } else if (balloonData[R2_GLOBALS._balloonAltitude].x < 0) {
+ --_newAltitude;
+ }
+
+ if (balloonData[R2_GLOBALS._balloonAltitude].y > 0) {
+ _newAltitude -= 8;
+ } else if (balloonData[R2_GLOBALS._balloonAltitude].y < 0) {
+ _newAltitude += 8;
+ }
+
+ if (balloonData[R2_GLOBALS._balloonAltitude].v3 > 0) {
+ _newAltitude += 48;
+ } else if (balloonData[R2_GLOBALS._balloonAltitude].v3 < 0) {
+ _newAltitude -= 48;
+ }
+
+ assert(_newAltitude < 193);
+ R2_GLOBALS._balloonAltitude = _newAltitude;
+ if (R2_GLOBALS._balloonAltitude == 189) {
+ // Finally reached landing point
+ _sceneMode = 12;
+ R2_GLOBALS._player.disableControl();
+
+ ADD_MOVER(R2_GLOBALS._player, 160, -10);
+ }
+ }
+ }
+
+ Scene::dispatch();
+}
+
+void Scene2900::refreshBackground(int xAmount, int yAmount) {
+ SceneExt::refreshBackground(xAmount, yAmount);
+
+ _map.redraw();
+}
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h
index 281d1da366..3960d93f94 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.h
@@ -45,23 +45,23 @@ class Scene2000 : public SceneExt {
virtual void signal();
};
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit5 : public SceneExit {
+ class DoorExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -69,17 +69,18 @@ public:
bool _exitingFlag;
int _mazePlayerMode;
- NamedHotspot _item1;
- SceneActor _object1;
- SceneActor _objList1[11];
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
- Exit5 _exit5;
+ NamedHotspot _background;
+ SceneActor _companion;
+ SceneActor _persons[11];
+ WestExit _westExit;
+ EastExit _eastExit;
+ SouthExit _southExit;
+ NorthExit _northExit;
+ DoorExit _doorExit;
Action1 _action1, _action2, _action3, _action4, _action5;
SequenceManager _sequenceManager;
+ Scene2000();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
@@ -91,10 +92,10 @@ public:
};
class Scene2350 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Companion : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Balloon : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
@@ -105,14 +106,13 @@ class Scene2350 : public SceneExt {
virtual void changeScene();
};
public:
-
SpeakerQuinn _quinnSpeaker;
SpeakerPharisha _pharishaSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor3 _actor4;
+ NamedHotspot _background;
+ SceneActor _person;
+ Companion _companion;
+ Balloon _balloon;
+ Balloon _harness;
ExitUp _exitUp;
ExitWest _exitWest;
SequenceManager _sequenceManager;
@@ -120,19 +120,18 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
- virtual void process(Event &event);
};
class Scene2400 : public SceneExt {
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
virtual void changeScene();
};
public:
- Exit1 _exit1;
- Exit2 _exit2;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -140,45 +139,45 @@ public:
};
class Scene2425 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class RopeDest1 : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item2 : public NamedHotspot {
+ class RopeDest2 : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item3 : public NamedHotspot {
+ class Crevasse : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item4 : public NamedHotspot {
+ class Background : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor1 : public SceneActor {
+ class Rope : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Pictographs : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthEastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- Item1 _item1;
- Item2 _item2;
- Item3 _item3;
- Item4 _item4;
- Actor1 _actor1;
- Actor2 _actor2;
- Actor2 _actor3;
- Exit1 _exit1;
+ RopeDest1 _ropeDest1;
+ RopeDest2 _ropeDest2;
+ Crevasse _crevasse;
+ Background _background;
+ Rope _rope;
+ Pictographs _pictographs1;
+ Pictographs _pictographs2;
+ SouthEastExit _southEastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -187,41 +186,41 @@ public:
};
class Scene2430 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class GunPowder : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class OilLamp : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- NamedHotspot _item8;
- NamedHotspot _item9;
- NamedHotspot _item10;
- NamedHotspot _item11;
- NamedHotspot _item12;
- NamedHotspot _item13;
- Actor1 _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _bottles2;
+ NamedHotspot _furnishings;
+ NamedHotspot _rug1;
+ NamedHotspot _mirror;
+ NamedHotspot _garments;
+ NamedHotspot _bed;
+ NamedHotspot _towel;
+ NamedHotspot _bottles1;
+ NamedHotspot _post;
+ NamedHotspot _clothesPile1;
+ NamedHotspot _clothesPile2;
+ NamedHotspot _rug2;
+ Companion _companion;
+ GunPowder _gunPowder;
+ OilLamp _oilLamp;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -229,16 +228,16 @@ public:
};
class Scene2435 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Astor : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -246,12 +245,12 @@ public:
SpeakerQuinn2435 _quinnSpeaker;
SpeakerSeeker2435 _seekerSpeaker;
SpeakerPharisha2435 _pharishaSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- Actor1 _actor1;
- Actor2 _actor2;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _leftWindow;
+ NamedHotspot _rightWindow;
+ Companion _companion;
+ Astor _astor;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -260,30 +259,30 @@ public:
};
class Scene2440 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class OilLamp : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthEastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- Actor1 _actor1;
- Actor2 _actor2;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _garments;
+ NamedHotspot _bedspread;
+ NamedHotspot _post;
+ NamedHotspot _rug;
+ NamedHotspot _furnishings;
+ NamedHotspot _bottles;
+ Companion _companion;
+ OilLamp _oilLamp;
+ SouthEastExit _southEastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -300,16 +299,16 @@ public:
};
class Scene2450 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Parker : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class CareTaker : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthWestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -317,13 +316,13 @@ public:
SpeakerQuinn2450 _quinnSpeaker;
SpeakerSeeker2450 _seekerSpeaker;
SpeakerCaretaker2450 _caretakerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _post;
+ NamedHotspot _bedspread;
+ SceneActor _companion;
+ Parker _parker;
+ CareTaker _careTaker;
+ SouthWestExit _southWestExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -332,29 +331,29 @@ public:
};
class Scene2455 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Lamp : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Pool : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class ScrithKey : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- Actor1 _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ Lamp _lamp;
+ Pool _pool;
+ ScrithKey _scrithKey;
+ NorthExit _northExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -363,7 +362,7 @@ public:
};
class Scene2500 : public SceneExt {
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -372,11 +371,11 @@ public:
SpeakerSeeker _seekerSpeaker;
SpeakerMiranda _mirandaSpeaker;
SpeakerWebbster2500 _webbsterSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ SceneActor _companion;
+ SceneActor _quinn;
+ SceneActor _ship;
+ WestExit _westExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -384,30 +383,30 @@ public:
};
class Scene2525 : public SceneExt {
- class Item5 : public NamedHotspot {
+ class StopCock : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class GlassDome : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Item5 _item5;
- SceneActor _actor1;
- SceneActor _actor2;
- Actor3 _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _machine;
+ NamedHotspot _pipes1;
+ NamedHotspot _pipes2;
+ StopCock _stopcock;
+ SceneActor _companion;
+ SceneActor _compressor;
+ GlassDome _glassDome;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -416,29 +415,29 @@ public:
};
class Scene2530 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Flask : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Crank : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
+ NamedHotspot _background;
+ NamedHotspot _crank2;
+ NamedHotspot _shelf;
NamedHotspot _item4;
- NamedHotspot _item5;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Exit1 _exit1;
+ NamedHotspot _rope;
+ SceneActor _companion;
+ Flask _flask;
+ Crank _crank;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -446,32 +445,32 @@ public:
};
class Scene2535 : public SceneExt {
- class Actor3 : public SceneActor {
+ class RebreatherTank : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class TannerMask : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- SceneActor _actor1;
- SceneActor _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _roof;
+ NamedHotspot _skin1;
+ NamedHotspot _skin2;
+ NamedHotspot _skin3;
+ NamedHotspot _skin4;
+ NamedHotspot _depression;
+ SceneActor _companion;
+ SceneActor _rope;
+ RebreatherTank _rebreatherTank;
+ TannerMask _tannerMask;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -508,37 +507,38 @@ class Scene2700 : public SceneExt {
void signal();
};
- class Area1: public SceneArea {
+ class SouthExit: public SceneArea {
public:
void process(Event &event);
};
- class Area2: public SceneArea {
+ class EastExit: public SceneArea {
public:
void process(Event &event);
};
public:
SpeakerQuinn2700 _quinnSpeaker;
SpeakerNej2700 _nejSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ NamedHotspot _background;
+ NamedHotspot _ghoulHome1;
+ NamedHotspot _ghoulHome2;
+ NamedHotspot _ghoulHome3;
+ NamedHotspot _ghoulHome4;
+ NamedHotspot _ghoulHome5;
+ SceneActor _nej;
+ SceneActor _ghoulHome6;
+ SceneActor _ghoulHome7;
+ SceneActor _ghoulHome8;
+ SceneActor _ghoulHome9;
Action1 _action1;
Action2 _action2;
Action3 _action3;
Action4 _action4;
- Area1 _area1;
- Area2 _area2;
- Rect _rect1, _rect2, _rect3, _rect4, _rect5, _rect6;
+ SouthExit _southExit;
+ EastExit _eastExit;
+ Rect _walkRect1, _walkRect2, _walkRect3;
+ Rect _walkRect4, _walkRect5, _walkRect6;
SequenceManager _sequenceManager;
- int _field412, _field414, _field416;
+ int _areaMode, _moveMode, _stripNumber;
Scene2700();
virtual void synchronize(Serializer &s);
@@ -577,33 +577,33 @@ class Scene2750 : public SceneExt {
void signal();
};
- class Area1: public SceneArea {
+ class WestExit: public SceneArea {
public:
void process(Event &event);
};
- class Area2: public SceneArea {
+ class EastExit: public SceneArea {
public:
void process(Event &event);
};
public:
SpeakerQuinn2750 _quinnSpeaker;
SpeakerNej2750 _nejSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
+ NamedHotspot _background;
+ NamedHotspot _ghoulHome1;
+ NamedHotspot _ghoulHome2;
+ NamedHotspot _ghoulHome3;
+ NamedHotspot _ghoulHome4;
+ SceneActor _nej;
+ SceneActor _fire;
+ SceneActor _bird1;
+ SceneActor _folliage1;
+ SceneActor _bird2;
+ SceneActor _folliage2;
+ SceneActor _folliage3;
+ SceneActor _folliage4;
+ SceneActor _folliage5;
+ SceneActor _folliage6;
+ SceneActor _folliage7;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -611,11 +611,11 @@ public:
Action5 _action5;
Action6 _action6;
Action7 _action7;
- Area1 _area1;
- Area2 _area2;
- Rect _rect1, _rect2, _rect3;
+ WestExit _westExit;
+ EastExit _eastExit;
+ Rect _walkRect1, _walkRect2, _walkRect3;
SequenceManager _sequenceManager;
- int _field412, _field414, _field416;
+ int _areaMode, _moveMode, _stripNumber;
Scene2750();
virtual void synchronize(Serializer &s);
@@ -625,12 +625,12 @@ public:
};
class Scene2800 : public SceneExt {
- class Item2 : public NamedHotspot {
+ class Outpost : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor1 : public SceneActor {
+ class Guard : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
@@ -649,16 +649,16 @@ public:
SpeakerQuinn2800 _quinnSpeaker;
SpeakerNej2800 _nejSpeaker;
SpeakerGuard2800 _guardSpeaker;
- NamedHotspot _item1;
- Item2 _item2;
- Actor1 _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneObject _object1;
+ NamedHotspot _background;
+ Outpost _outpost;
+ Guard _guard;
+ SceneActor _nej;
+ SceneActor _lightBar;
+ SceneObject _bird;
Action1 _action1;
Action2 _action2;
SequenceManager _sequenceManager;
- int _field412;
+ int _stripNumber;
Scene2800();
virtual void synchronize(Serializer &s);
@@ -666,6 +666,97 @@ public:
virtual void signal();
};
+class Scene2900 : public SceneExt {
+ /* Items */
+ class Scenery : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class ControlPanel : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Altimeter : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class KnobLeft : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class KnobRight : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+ class Skip : public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ /* Actions */
+ class Action1: public Action {
+ public:
+ void signal();
+ };
+
+ /* Miscellaneous */
+ class Map {
+ private:
+ void moveArea(Rect &r, int xAmt, int yAmt);
+ void moveLine(int xpSrc, int ypSrc, int xpDest, int ypDest, int width);
+ int adjustRect(Common::Rect &r1, const Common::Rect &r2);
+ void drawBlock(const byte *data, int xp, int yp, const Rect &r1, const Rect &r2);
+ public:
+ int _mapWidth, _mapHeight;
+ int _resNum;
+ int _xV, _yV;
+ Rect _bounds;
+
+ Map();
+ void load(int resNum);
+ Common::Point setPosition(const Common::Point &pos, bool initialFlag = false);
+ void synchronize(Serializer &s);
+ void redraw(Rect *updateRect = NULL);
+ };
+public:
+ SceneObject _leftEdge;
+ SceneObject _rightEdge;
+ SceneObject _knob;
+ SceneObject _altimeterContent;
+ SceneObject _knobRightContent;
+ SceneObject _knobLeftContent;
+ Scenery _scenery;
+ ControlPanel _controlPanel;
+ Altimeter _altimeter;
+ KnobLeft _knobLeft;
+ KnobRight _knobRight;
+ Skip _skip;
+ Action1 _action1;
+ Map _map;
+ SceneText _skipText;
+
+ bool _controlsActiveChanging;
+ bool _altitudeChanging;
+ bool _majorMinorFlag;
+ int _altitudeMinorChange;
+ int _altitudeMajorChange;
+ Common::Point _balloonLocation;
+ Common::Point _balloonScreenPos;
+ int _newAltitude;
+ int _xAmount;
+ int _xComparison;
+ int _fadeCounter;
+ bool _paletteReloadNeeded;
+
+ Scene2900();
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+ virtual void refreshBackground(int xAmount, int yAmount);
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index 61711d0a4f..732add03ec 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -30,17 +30,18 @@ namespace TsAGE {
namespace Ringworld2 {
/*--------------------------------------------------------------------------
- * Scene 3100 -
+ * Scene 3100 - ARM Base Hanager
*
*--------------------------------------------------------------------------*/
+
Scene3100::Scene3100() {
- _field412 = 0;
+ _fadeSound = false;
}
void Scene3100::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_fadeSound);
}
bool Scene3100::Guard::startAction(CursorType action, Event &event) {
@@ -58,12 +59,12 @@ bool Scene3100::Guard::startAction(CursorType action, Event &event) {
void Scene3100::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100) {
loadScene(3101);
R2_GLOBALS._uiElements._active = false;
} else {
loadScene(3100);
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ _sceneBounds = Rect(160, 0, 480, SCREEN_HEIGHT);
}
} else {
loadScene(3100);
@@ -83,20 +84,21 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _item2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL);
- _field412 = 0;
+ _hammerHead.postInit();
+ _hammerHead2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL);
+ _fadeSound = false;
if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100) {
_sceneMode = 3102;
- _actor3.postInit();
- _actor4.postInit();
- _actor5.postInit();
+ _ghoul.postInit();
+ _technicians.postInit();
+ _deadBodies.postInit();
R2_GLOBALS._sound1.play(274);
_sound1.fadeSound(130);
- setAction(&_sequenceManager, this, 3102, &_actor1, &R2_GLOBALS._player, &_actor3, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 3102, &_hammerHead, &R2_GLOBALS._player,
+ &_ghoul, &_technicians, &_deadBodies, NULL);
} else {
_guard.postInit();
_guard.setup(3110, 5, 1);
@@ -104,27 +106,28 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
_guard.setPosition(Common::Point(10, 149));
_guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
- _actor4.postInit();
- _actor4.setup(3103, 1, 1);
- _actor4.setPosition(Common::Point(278, 113));
- _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
- _actor4.animate(ANIM_MODE_2, NULL);
+ _technicians.postInit();
+ _technicians.setup(3103, 1, 1);
+ _technicians.setPosition(Common::Point(278, 113));
+ _technicians.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _technicians.animate(ANIM_MODE_2, NULL);
- _field412 = 1;
- _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+ _fadeSound = true;
+ _hammerHead.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._sound1.play(243);
R2_GLOBALS._sound2.play(130);
_sceneMode = 3100;
- setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_hammerHead, NULL);
}
} else if (R2_GLOBALS._sceneManager._previousScene == 3255) {
_sceneMode = 3101;
- _actor2.postInit();
- _actor3.postInit();
- _field412 = 1;
+ _miranda.postInit();
+ _ghoul.postInit();
+ _fadeSound = true;
- setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_hammerHead,
+ &_miranda, &_ghoul, NULL);
} else {
_guard.postInit();
_guard.setup(3110, 5, 1);
@@ -132,28 +135,28 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
_guard.setPosition(Common::Point(10, 149));
_guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
- _actor4.postInit();
- _actor4.setup(3103, 1, 1);
- _actor4.setPosition(Common::Point(278, 113));
- _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
- _actor4.animate(ANIM_MODE_2, NULL);
+ _technicians.postInit();
+ _technicians.setup(3103, 1, 1);
+ _technicians.setPosition(Common::Point(278, 113));
+ _technicians.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _technicians.animate(ANIM_MODE_2, NULL);
- _actor1.postInit();
- _actor1.setup(3104, 4, 1);
- _actor1.setPosition(Common::Point(143, 104));
- _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+ _hammerHead.postInit();
+ _hammerHead.setup(3104, 4, 1);
+ _hammerHead.setPosition(Common::Point(143, 104));
+ _hammerHead.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.setup(3110, 3, 1);
R2_GLOBALS._player.changeZoom(50);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setPosition(Common::Point(160, 150));
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._sound1.play(243);
}
- R2_GLOBALS._player._oldCharacterScene[1] = 3100;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 3100;
}
void Scene3100::remove() {
@@ -172,29 +175,29 @@ void Scene3100::signal() {
case 3100:
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 3101:
R2_GLOBALS._sceneManager.changeScene(1000);
break;
case 3102:
- R2_GLOBALS._player._oldCharacterScene[1] = 1000;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1000;
R2_GLOBALS._sceneManager.changeScene(1000);
break;
default:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
void Scene3100::dispatch() {
- if ((_sceneMode == 3100) && (_field412 != 0) && (R2_GLOBALS._player._position.y == 104)) {
- _field412 = 0;
+ if ((_sceneMode == 3100) && _fadeSound && (R2_GLOBALS._player._position.y == 104)) {
+ _fadeSound = false;
R2_GLOBALS._sound2.fadeOut2(NULL);
}
- if ((_sceneMode == 3101) && (_field412 != 0) && (R2_GLOBALS._player._position.y < 104)) {
- _field412 = 0;
+ if ((_sceneMode == 3101) && _fadeSound && (R2_GLOBALS._player._position.y < 104)) {
+ _fadeSound = false;
_sound1.fadeSound(130);
}
@@ -205,54 +208,56 @@ void Scene3100::dispatch() {
* Scene 3125 - Ghouls dormitory
*
*--------------------------------------------------------------------------*/
+
Scene3125::Scene3125() {
- _field412 = 0;
+ _soundPlayed = false;
}
void Scene3125::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_soundPlayed);
}
-bool Scene3125::Item1::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3125::Background::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1)
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_LOOK:
if (_lookLineNum != -1)
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
if (_talkLineNum != -1)
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
- default:
+ default: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
+ }
break;
}
return true;
}
-bool Scene3125::Item2::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3125::Table::startAction(CursorType action, Event &event) {
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3125;
- scene->setAction(&scene->_sequenceManager1, scene, 3125, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3125, &R2_GLOBALS._player, NULL);
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3125, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
- SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
default:
return SceneHotspot::startAction(action, event);
@@ -262,21 +267,24 @@ bool Scene3125::Item2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3125::Item3::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3125::Computer::startAction(CursorType action, Event &event) {
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
+ scene->_ghoul4.postInit();
scene->_sceneMode = 3126;
- scene->setAction(&scene->_sequenceManager1, scene, 3126, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor3, &scene->_actor4, &scene->_actor1, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3126, &R2_GLOBALS._player,
+ &scene->_ghoul1, &scene->_ghoul2, &scene->_ghoul3, &scene->_door,
+ &scene->_ghoul4, NULL);
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3125, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
- SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
default:
return SceneHotspot::startAction(action, event);
@@ -286,68 +294,68 @@ bool Scene3125::Item3::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3125::Actor1::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3125::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3176;
- scene->setAction(&scene->_sequenceManager1, scene, 3176, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
void Scene3125::postInit(SceneObjectList *OwnerList) {
loadScene(3125);
SceneExt::postInit();
- _field412 = 0;
+ _soundPlayed = false;
- _actor1.postInit();
- _actor1.setup(3175, 1, 1);
- _actor1.setPosition(Common::Point(35, 72));
- _actor1.setDetails(3125, 12, 13, -1, 1, (SceneItem *)NULL);
+ _door.postInit();
+ _door.setup(3175, 1, 1);
+ _door.setPosition(Common::Point(35, 72));
+ _door.setDetails(3125, 12, 13, -1, 1, (SceneItem *)NULL);
- _actor2.postInit();
- _actor2.setup(3126, 4, 1);
- _actor2.setPosition(Common::Point(71, 110));
- _actor2._numFrames = 20;
+ _ghoul1.postInit();
+ _ghoul1.setup(3126, 4, 1);
+ _ghoul1.setPosition(Common::Point(71, 110));
+ _ghoul1._numFrames = 20;
- _actor3.postInit();
- _actor3.setup(3126, 1, 1);
- _actor3.setPosition(Common::Point(215, 62));
- _actor3.fixPriority(71);
+ _ghoul2.postInit();
+ _ghoul2.setup(3126, 1, 1);
+ _ghoul2.setPosition(Common::Point(215, 62));
+ _ghoul2.fixPriority(71);
- _actor4.postInit();
- _actor4.setup(3126, 1, 1);
- _actor4.setPosition(Common::Point(171, 160));
- _actor4.fixPriority(201);
+ _ghoul3.postInit();
+ _ghoul3.setup(3126, 1, 1);
+ _ghoul3.setPosition(Common::Point(171, 160));
+ _ghoul3.fixPriority(201);
- _item3.setDetails(12, 3125, 9, 13, -1);
- _item2.setDetails(11, 3125, 15, 13, -1);
- _item1.setDetails(Rect(0, 0, 320, 200), 3125, 0, 1, 2, 1, NULL);
+ _computer.setDetails(12, 3125, 9, 13, -1);
+ _table.setDetails(11, 3125, 15, 13, -1);
+ _background.setDetails(Rect(0, 0, 320, 200), 3125, 0, 1, 2, 1, NULL);
R2_GLOBALS._sound1.play(262);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._oldCharacterScene[3] == 3250) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3250) {
_sceneMode = 3175;
- setAction(&_sequenceManager1, this, 3175, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 3175, &R2_GLOBALS._player, &_door, NULL);
} else {
R2_GLOBALS._player.setup(30, 5, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setPosition(Common::Point(89, 76));
R2_GLOBALS._player.enableControl();
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3125;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3125;
}
void Scene3125::signal() {
switch (_sceneMode) {
case 3125:
- SceneItem::display(3125, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
_sceneMode = 3127;
- setAction(&_sequenceManager1, this, 3127, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager, this, 3127, &R2_GLOBALS._player, NULL);
break;
case 3126:
R2_GLOBALS.setFlag(79);
@@ -362,9 +370,9 @@ void Scene3125::signal() {
}
void Scene3125::dispatch() {
- if ((_sceneMode == 3126) && (_actor2._frame == 2) && (_field412 == 0)) {
- _field412 = 1;
+ if ((_sceneMode == 3126) && (_ghoul1._frame == 2) && !_soundPlayed) {
R2_GLOBALS._sound1.play(265);
+ _soundPlayed = true;
}
Scene::dispatch();
}
@@ -373,28 +381,29 @@ void Scene3125::dispatch() {
* Scene 3150 - Jail
*
*--------------------------------------------------------------------------*/
-bool Scene3150::Item5::startAction(CursorType action, Event &event) {
+
+bool Scene3150::LightFixture::startAction(CursorType action, Event &event) {
Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
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();
scene->_sceneMode = 3154;
- scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_bulbOrWire, 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;
- scene->_actor3._shade = 5;
+ scene->_bulbOrWire.postInit();
+ scene->_bulbOrWire._effect = EFFECT_SHADED2;
+ scene->_bulbOrWire._shade = 5;
scene->_sceneMode = 3155;
- scene->setAction(&scene->_sequenceManager, scene, 3155, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3155, &R2_GLOBALS._player, &scene->_bulbOrWire, NULL);
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
default:
@@ -403,50 +412,54 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
}
}
-bool Scene3150::Item6::startAction(CursorType action, Event &event) {
+bool Scene3150::Toilet::startAction(CursorType action, Event &event) {
Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case R2_PILLOW:
R2_GLOBALS._player.disableControl();
- scene->_actor4.postInit();
- scene->_actor4._effect = 6;
- scene->_actor4._shade = 3;
+ scene->_water.postInit();
+ scene->_water._effect = EFFECT_SHADED2;
+ scene->_water._shade = 3;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3158;
- scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_water, NULL);
return true;
case R2_FOOD_TRAY:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_INVENTORY.getObjectScene(40) == 3150) && (R2_GLOBALS.getFlag(75))) {
- scene->_actor5.postInit();
- scene->_actor5._effect = 6;
- scene->_actor5._shade = 3;
- scene->_actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) &&
+ (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150)
+ && (R2_GLOBALS.getFlag(75))) {
+ scene->_foodTray.postInit();
+ scene->_foodTray._effect = EFFECT_SHADED2;
+ scene->_foodTray._shade = 3;
+ scene->_foodTray.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3159;
- scene->setAction(&scene->_sequenceManager, scene, 3159, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3159, &R2_GLOBALS._player, &scene->_foodTray, NULL);
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
+ return true;
default:
return SceneHotspot::startAction(action, event);
break;
}
}
-bool Scene3150::Actor4::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3150::Water::startAction(CursorType action, Event &event) {
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
if (R2_GLOBALS.getFlag(75))
return SceneActor::startAction(action, event);
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3151;
- scene->setAction(&scene->_sequenceManager, scene, 3151, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3151, &R2_GLOBALS._player, &scene->_water, NULL);
return true;
+ }
case R2_FOOD_TRAY:
return false;
default:
@@ -455,22 +468,22 @@ bool Scene3150::Actor4::startAction(CursorType action, Event &event) {
}
}
-bool Scene3150::Actor5::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3150::FoodTray::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(77)))
- return SceneActor::startAction(action ,event);
+ return SceneActor::startAction(action, event);
+
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3157;
- scene->setAction(&scene->_sequenceManager, scene, 3157, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3157, &R2_GLOBALS._player, &scene->_foodTray, NULL);
return true;
}
-bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3150::ToiletFlush::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(77)) {
R2_GLOBALS._player.disableControl();
@@ -479,10 +492,10 @@ bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 3153;
- scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3153, &R2_GLOBALS._player, &scene->_water, NULL);
}
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
} else {
R2_GLOBALS._player.disableControl();
@@ -495,20 +508,20 @@ bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
}
}
-bool Scene3150::Actor7::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3150::AirVent::startAction(CursorType action, Event &event) {
if ((action == R2_LASER_HACKSAW) && (!R2_GLOBALS.getFlag(80))) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3160;
- scene->setAction(&scene->_sequenceManager, scene, 3160, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3160, &R2_GLOBALS._player, &scene->_airVent, NULL);
return true;
}
return SceneActor::startAction(action, event);
}
-void Scene3150::Exit1::changeScene() {
+void Scene3150::DoorExit::changeScene() {
Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -521,7 +534,7 @@ void Scene3150::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3150::Exit2::changeScene() {
+void Scene3150::VentExit::changeScene() {
Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -535,128 +548,128 @@ void Scene3150::Exit2::changeScene() {
void Scene3150::postInit(SceneObjectList *OwnerList) {
loadScene(3150);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(35, 2000);
- R2_GLOBALS._player._oldCharacterScene[1] = 3100;
- R2_GLOBALS._player._oldCharacterScene[3] = 0;
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2000);
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 3100;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 0;
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
}
SceneExt::postInit();
if (R2_GLOBALS.getFlag(78)) {
- _exit1.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
- _exit1.setDest(Common::Point(70, 125));
+ _doorExit.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
+ _doorExit.setDest(Common::Point(70, 125));
}
if (R2_GLOBALS.getFlag(80)) {
- _exit2.setDetails(Rect(249, 36, 279, 60), EXITCURSOR_NE, 3150);
- _exit2.setDest(Common::Point(241, 106));
+ _ventExit.setDetails(Rect(249, 36, 279, 60), EXITCURSOR_NE, 3150);
+ _ventExit.setDest(Common::Point(241, 106));
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- _actor2.postInit();
- _actor2.setPosition(Common::Point(64, 139));
+ _doorBars.postInit();
+ _doorBars.setPosition(Common::Point(64, 139));
if (R2_GLOBALS.getFlag(78)) {
- _actor2.setup(3151, 1, 5);
- _actor2.fixPriority(125);
+ _doorBars.setup(3151, 1, 5);
+ _doorBars.fixPriority(125);
} else {
- _actor2.setup(3151, 1, 1);
- _actor2.setDetails(3150, 8, -1, 9, 1, (SceneItem *)NULL);
+ _doorBars.setup(3151, 1, 1);
+ _doorBars.setDetails(3150, 8, -1, 9, 1, (SceneItem *)NULL);
}
if (R2_GLOBALS.getFlag(78)) {
- _actor1.postInit();
- _actor1.setup(3154, 1, 16);
- _actor1.setPosition(Common::Point(104, 129));
- _actor1._effect = 6;
- _actor1._shade = 3;
- _actor1.setDetails(3150, 24, -1, -1, -1, (SceneItem *)NULL);
+ _guard.postInit();
+ _guard.setup(3154, 1, 16);
+ _guard.setPosition(Common::Point(104, 129));
+ _guard._effect = EFFECT_SHADED2;
+ _guard._shade = 3;
+ _guard.setDetails(3150, 24, -1, -1, -1, (SceneItem *)NULL);
}
- _actor7.postInit();
- _actor7.setup(3154, 5, 1);
+ _airVent.postInit();
+ _airVent.setup(3154, 5, 1);
if (R2_GLOBALS.getFlag(80))
- _actor7.setPosition(Common::Point(264, 108));
+ _airVent.setPosition(Common::Point(264, 108));
else
- _actor7.setPosition(Common::Point(264, 58));
- _actor7.fixPriority(50);
- _actor7.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
+ _airVent.setPosition(Common::Point(264, 58));
+ _airVent.fixPriority(50);
+ _airVent.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(41) == 3150) {
- _actor4.postInit();
+ if (R2_INVENTORY.getObjectScene(R2_PILLOW) == 3150) {
+ _water.postInit();
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(76)) {
- R2_GLOBALS._walkRegions.enableRegion(1);
- R2_GLOBALS._walkRegions.enableRegion(4);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
- _actor4.setup(3152, 4, 10);
- _actor4.setDetails(3150, 14, -1, -1, 1, (SceneItem *)NULL);
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ _water.setup(3152, 4, 10);
+ _water.setDetails(3150, 14, -1, -1, 1, (SceneItem *)NULL);
} else {
- _actor4.setup(3152, 7, 4);
- _actor4.setDetails(3150, 13, -1, -1, 1, (SceneItem *)NULL);
+ _water.setup(3152, 7, 4);
+ _water.setDetails(3150, 13, -1, -1, 1, (SceneItem *)NULL);
}
- _actor4.fixPriority(110);
- _actor4.setPosition(Common::Point(83, 88));
- _actor4._effect = 6;
- _actor4._shade = 3;
+ _water.fixPriority(110);
+ _water.setPosition(Common::Point(83, 88));
+ _water._effect = EFFECT_SHADED2;
+ _water._shade = 3;
} else {
- _actor4.setup(3152, 7, 3);
- _actor4.setPosition(Common::Point(143, 70));
- _actor4.setDetails(3150, 15, -1, -1, 1, (SceneItem *)NULL);
+ _water.setup(3152, 7, 3);
+ _water.setPosition(Common::Point(143, 70));
+ _water.setDetails(3150, 15, -1, -1, 1, (SceneItem *)NULL);
}
}
- if (R2_INVENTORY.getObjectScene(47) == 3150) {
- _actor3.postInit();
- _actor3.setup(3152, 7, 1);
- _actor3.setPosition(Common::Point(73, 83));
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) == 3150) {
+ _bulbOrWire.postInit();
+ _bulbOrWire.setup(3152, 7, 1);
+ _bulbOrWire.setPosition(Common::Point(73, 83));
}
- if (R2_INVENTORY.getObjectScene(40) == 3150) {
- _actor3.postInit();
- _actor3.setup(3152, 7, 3);
- _actor3.setPosition(Common::Point(70, 55));
- _actor3.fixPriority(111);
- _actor3._effect = 6;
- _actor3._shade = 5;
+ if (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) {
+ _bulbOrWire.postInit();
+ _bulbOrWire.setup(3152, 7, 2);
+ _bulbOrWire.setPosition(Common::Point(70, 55));
+ _bulbOrWire.fixPriority(111);
+ _bulbOrWire._effect = EFFECT_SHADED2;
+ _bulbOrWire._shade = 5;
}
- if (R2_INVENTORY.getObjectScene(42) == 3150) {
- _actor5.postInit();
+ if (R2_INVENTORY.getObjectScene(R2_FOOD_TRAY) == 3150) {
+ _foodTray.postInit();
if (R2_GLOBALS.getFlag(77)) {
- _actor5.setup(3152, 7, 8);
- _actor5.setPosition(Common::Point(82, 92));
- _actor5.fixPriority(111);
- _actor5._effect = 6;
- _actor5._shade = 3;
+ _foodTray.setup(3152, 7, 8);
+ _foodTray.setPosition(Common::Point(82, 92));
+ _foodTray.fixPriority(111);
+ _foodTray._effect = EFFECT_SHADED2;
+ _foodTray._shade = 3;
} else {
- _actor5.setup(3152, 7, 7);
- _actor5.setPosition(Common::Point(155, 79));
+ _foodTray.setup(3152, 7, 7);
+ _foodTray.setPosition(Common::Point(155, 79));
}
- _actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+ _foodTray.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
}
- _actor6.postInit();
- _actor6.setup(3152, 7, 6);
- _actor6.setPosition(Common::Point(98, 73));
- _actor6.setDetails(3150, 43, -1, -1, 1, (SceneItem *)NULL);
+ _toiletFlush.postInit();
+ _toiletFlush.setup(3152, 7, 6);
+ _toiletFlush.setPosition(Common::Point(98, 73));
+ _toiletFlush.setDetails(3150, 43, -1, -1, 1, (SceneItem *)NULL);
- _item2.setDetails(12, 3150, 10, -1, 12);
- _item3.setDetails(Rect(186, 17, 210, 36), 3150, 6, -1, -1, 1, NULL);
- _item4.setDetails(Rect(61, 21, 92, 41), 3150, 7, -1, -1, 1, NULL);
- _item5.setDetails(Rect(63, 48, 78, 58), 3150, 6, -1, -1, 1, NULL);
- _item6.setDetails(Rect(63, 81, 100, 95), 3150, 3, 4, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 200, 320), 3150, 0, 1, 2, 1, NULL);
+ _bed.setDetails(12, 3150, 10, -1, 12);
+ _lightFixture2.setDetails(Rect(186, 17, 210, 36), 3150, 6, -1, -1, 1, NULL);
+ _bars.setDetails(Rect(61, 21, 92, 41), 3150, 7, -1, -1, 1, NULL);
+ _lightFixture.setDetails(Rect(63, 48, 78, 58), 3150, 6, -1, -1, 1, NULL);
+ _toilet.setDetails(Rect(63, 81, 100, 95), 3150, 3, 4, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 200, 320), 3150, 0, 1, 2, 1, NULL);
- switch (R2_GLOBALS._player._oldCharacterScene[3]) {
+ switch (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA]) {
case 0:
_sceneMode = 3150;
- _actor1.postInit();
- _actor1._effect = 6;
- _actor1._shade = 5;
- setAction(&_sequenceManager, this, 3150, &R2_GLOBALS._player, &_actor1, &_actor2, NULL);
+ _guard.postInit();
+ _guard._effect = EFFECT_SHADED2;
+ _guard._shade = 5;
+ setAction(&_sequenceManager, this, 3150, &R2_GLOBALS._player, &_guard, &_doorBars, NULL);
break;
case 1200:
_sceneMode = 3162;
@@ -675,22 +688,24 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
break;
}
default:
- if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(35) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
- ++R2_GLOBALS._v56AA0;
+ if ((R2_GLOBALS._mirandaJailState == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000)
+ && (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100)) {
+ // Moving story on to Miranda getting food delivered
+ ++R2_GLOBALS._mirandaJailState;
_sceneMode = 3156;
- _actor1.postInit();
- _actor1._effect = 6;
- _actor1._shade = 3;
+ _guard.postInit();
+ _guard._effect = EFFECT_SHADED2;
+ _guard._shade = 3;
- _actor2.postInit();
- _actor5.postInit();
- _actor5._effect = 6;
- _actor5._shade = 3;
+ _doorBars.postInit();
+ _foodTray.postInit();
+ _foodTray._effect = EFFECT_SHADED2;
+ _foodTray._shade = 3;
- setAction(&_sequenceManager, this, 3156, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 3156, &R2_GLOBALS._player, &_guard, &_doorBars, &_foodTray, NULL);
} else {
- if (R2_GLOBALS._v56AA0 != 2)
- ++R2_GLOBALS._v56AA0;
+ if ((R2_GLOBALS._mirandaJailState != 1) && (R2_GLOBALS._mirandaJailState != 2))
+ ++R2_GLOBALS._mirandaJailState;
R2_GLOBALS._player.setup(30, 3, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -700,7 +715,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
}
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3150;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
}
void Scene3150::signal() {
@@ -712,62 +727,62 @@ void Scene3150::signal() {
R2_GLOBALS._sceneManager.changeScene(1200);
break;
case 3151:
- _actor1.remove();
- R2_INVENTORY.setObjectScene(41, 3);
+ _guard.remove();
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3);
R2_GLOBALS._player.enableControl();
break;
case 3153:
R2_GLOBALS.setFlag(76);
- _actor4.setDetails(3150, 14, -1, -1, 3, (SceneItem *)NULL);
- _actor1.postInit();
- _actor1.setDetails(3150, 24, -1, -1, 2, (SceneItem *)NULL);
+ _water.setDetails(3150, 14, -1, -1, 3, (SceneItem *)NULL);
+ _guard.postInit();
+ _guard.setDetails(3150, 24, -1, -1, 2, (SceneItem *)NULL);
_sceneMode = 3161;
- setAction(&_sequenceManager, this, 3161, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3161, &_guard, &_doorBars, NULL);
break;
case 3154:
- _actor3.remove();
- R2_INVENTORY.setObjectScene(47, 3);
+ _bulbOrWire.remove();
+ 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);
+ _foodTray.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3157:
- _actor5.remove();
- R2_INVENTORY.setObjectScene(42, 3);
+ _foodTray.remove();
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3);
R2_GLOBALS._player.enableControl();
break;
case 3158:
R2_GLOBALS.setFlag(75);
- R2_INVENTORY.setObjectScene(41, 3150);
- _actor4.fixPriority(110);
- _actor4.setDetails(3150, 13, -1, -1, 2, (SceneItem *)NULL);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3150);
+ _water.fixPriority(110);
+ _water.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;
case 3161:
- R2_GLOBALS._sceneItems.remove(&_actor2);
- _exit1.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
- _exit1.setDest(Common::Point(70, 125));
- R2_GLOBALS._walkRegions.enableRegion(1);
- R2_GLOBALS._walkRegions.enableRegion(4);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._sceneItems.remove(&_doorBars);
+ _doorExit.setDetails(Rect(0, 135, 60, 168), EXITCURSOR_SW, 3275);
+ _doorExit.setDest(Common::Point(70, 125));
+ R2_GLOBALS._walkRegions.disableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
R2_GLOBALS.setFlag(78);
R2_GLOBALS._player.enableControl();
break;
@@ -778,14 +793,14 @@ void Scene3150::signal() {
}
void Scene3150::dispatch() {
- if (_actor5._position.x == 155) {
- _actor5._effect = 0;
- _actor5._shade = 0;
+ if (_foodTray._position.x == 155) {
+ _foodTray._effect = EFFECT_NONE;
+ _foodTray._shade = 0;
}
- if (_actor1._visage == 3154) {
- _actor1._effect = 0;
- _actor1._shade = 0;
+ if (_guard._visage == 3154) {
+ _guard._effect = EFFECT_NONE;
+ _guard._shade = 0;
}
Scene::dispatch();
@@ -795,25 +810,24 @@ void Scene3150::dispatch() {
* Scene 3175 - Autopsy room
*
*--------------------------------------------------------------------------*/
-bool Scene3175::Item1::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+bool Scene3175::RoomItem::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -821,28 +835,27 @@ bool Scene3175::Item1::startAction(CursorType action, Event &event) {
break;
}
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
-bool Scene3175::Actor3::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3175::Corpse::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -850,25 +863,27 @@ bool Scene3175::Actor3::startAction(CursorType action, Event &event) {
break;
}
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
-bool Scene3175::Actor1::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3175::Door::startAction(CursorType action, Event &event) {
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3176;
- scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3175, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3175, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
break;
case CURSOR_TALK:
- SceneItem::display(3175, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3175, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
break;
default:
@@ -881,37 +896,37 @@ void Scene3175::postInit(SceneObjectList *OwnerList) {
loadScene(3175);
SceneExt::postInit();
- _actor1.postInit();
- _actor1.setup(3175, 1, 1);
- _actor1.setPosition(Common::Point(35, 72));
- _actor1.setDetails(3175, 9, 10, -1, 1, (SceneItem *)NULL);
+ _door.postInit();
+ _door.setup(3175, 1, 1);
+ _door.setPosition(Common::Point(35, 72));
+ _door.setDetails(3175, 9, 10, -1, 1, (SceneItem *)NULL);
- _actor2.postInit();
- _actor2.setup(3175, 2, 1);
- _actor2.setPosition(Common::Point(87, 148));
+ _computer.postInit();
+ _computer.setup(3175, 2, 1);
+ _computer.setPosition(Common::Point(87, 148));
- _actor3.postInit();
- _actor3.setup(3175, 3, 1);
- _actor3.setPosition(Common::Point(199, 117));
- _actor3.setDetails(3175, 15, 16, 17, 1, (SceneItem *)NULL);
+ _corpse.postInit();
+ _corpse.setup(3175, 3, 1);
+ _corpse.setPosition(Common::Point(199, 117));
+ _corpse.setDetails(3175, 15, 16, 17, 1, (SceneItem *)NULL);
- _item2.setDetails(12, 3175, 3, 1, 5);
- _item3.setDetails(11, 3175, 6, 7, 8);
- _item1.setDetails(Rect(0, 0, 320, 200), 3175, 0, 1, 2, 1, NULL);
+ _table.setDetails(12, 3175, 3, 1, 5);
+ _autopsies.setDetails(11, 3175, 6, 7, 8);
+ _background.setDetails(Rect(0, 0, 320, 200), 3175, 0, 1, 2, 1, NULL);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._oldCharacterScene[3] == 3250) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3250) {
R2_GLOBALS._player.setup(30, 5, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setPosition(Common::Point(126, 77));
R2_GLOBALS._player.enableControl();
} else {
_sceneMode = 3175;
- setAction(&_sequenceManager, this, 3175, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 3175, &R2_GLOBALS._player, &_door, NULL);
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3175;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3175;
}
void Scene3175::signal() {
@@ -925,6 +940,7 @@ void Scene3175::signal() {
* Scene 3200 - Cutscene : Guards - Discussion
*
*--------------------------------------------------------------------------*/
+
void Scene3200::postInit(SceneObjectList *OwnerList) {
loadScene(3200);
R2_GLOBALS._uiElements._active = false;
@@ -938,11 +954,12 @@ void Scene3200::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor3.postInit();
- _actor2.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
+ _socko.postInit();
- setAction(&_sequenceManager, this, 3200 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3200 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, &_socko, NULL);
}
void Scene3200::signal() {
@@ -953,6 +970,7 @@ void Scene3200::signal() {
* Scene 3210 - Cutscene : Captain and Private - Discussion
*
*--------------------------------------------------------------------------*/
+
void Scene3210::postInit(SceneObjectList *OwnerList) {
loadScene(3210);
R2_GLOBALS._uiElements._active = false;
@@ -965,10 +983,11 @@ void Scene3210::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _captain.postInit();
+ _private.postInit();
- setAction(&_sequenceManager, this, 3210 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3210 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_captain, &_private, NULL);
}
void Scene3210::signal() {
@@ -979,6 +998,7 @@ void Scene3210::signal() {
* Scene 3220 - Cutscene : Guards in cargo zone
*
*--------------------------------------------------------------------------*/
+
void Scene3220::postInit(SceneObjectList *OwnerList) {
loadScene(3220);
R2_GLOBALS._uiElements._active = false;
@@ -991,10 +1011,11 @@ void Scene3220::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
- setAction(&_sequenceManager, this, 3220 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3220 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, NULL);
}
void Scene3220::signal() {
@@ -1005,6 +1026,7 @@ void Scene3220::signal() {
* Scene 3230 - Cutscene : Guards on duty
*
*--------------------------------------------------------------------------*/
+
void Scene3230::postInit(SceneObjectList *OwnerList) {
loadScene(3230);
R2_GLOBALS._uiElements._active = false;
@@ -1017,11 +1039,12 @@ void Scene3230::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
- _actor3.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
+ _ghoul.postInit();
- setAction(&_sequenceManager, this, 3230 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3230 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, &_ghoul, NULL);
}
void Scene3230::signal() {
@@ -1032,6 +1055,7 @@ void Scene3230::signal() {
* Scene 3240 - Cutscene : Teal monolog
*
*--------------------------------------------------------------------------*/
+
void Scene3240::postInit(SceneObjectList *OwnerList) {
loadScene(3240);
R2_GLOBALS._uiElements._active = false;
@@ -1045,10 +1069,11 @@ void Scene3240::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _teal.postInit();
+ _webbster.postInit();
- setAction(&_sequenceManager, this, 3240 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3240 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_teal, &_webbster, NULL);
}
void Scene3240::signal() {
@@ -1059,6 +1084,7 @@ void Scene3240::signal() {
* Scene 3245 - Cutscene : Discussions with Dr. Tomko
*
*--------------------------------------------------------------------------*/
+
void Scene3245::postInit(SceneObjectList *OwnerList) {
loadScene(3245);
R2_GLOBALS._uiElements._active = false;
@@ -1071,17 +1097,18 @@ void Scene3245::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _ralf.postInit();
+ _tomko.postInit();
- if (R2_GLOBALS._v56AA1 < 4)
- ++R2_GLOBALS._v56AA1;
+ if (R2_GLOBALS._scientistConvIndex < 4)
+ ++R2_GLOBALS._scientistConvIndex;
- if (R2_GLOBALS._v56AA1 >= 4) {
- SceneItem::display(1200, 7, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ if (R2_GLOBALS._scientistConvIndex >= 4) {
+ SceneItem::display(1200, 7, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
signal();
} else {
- setAction(&_sequenceManager, this, 3244 + R2_GLOBALS._v56AA1, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3244 + R2_GLOBALS._scientistConvIndex,
+ &_ralf, &_tomko, NULL);
}
}
@@ -1093,25 +1120,24 @@ void Scene3245::signal() {
* Scene 3250 - Room with large stasis field negator
*
*--------------------------------------------------------------------------*/
-bool Scene3250::Item::startAction(CursorType action, Event &event) {
- Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
+bool Scene3250::Item::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -1119,29 +1145,29 @@ bool Scene3250::Item::startAction(CursorType action, Event &event) {
break;
}
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
-bool Scene3250::Actor::startAction(CursorType action, Event &event) {
- Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3250::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
switch(_position.x) {
case 25:
scene->_sceneMode = 3262;
- scene->setAction(&scene->_sequenceManager, scene, 3262, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3262, &R2_GLOBALS._player, &scene->_leftDoor, NULL);
break;
case 259:
scene->_sceneMode = 3260;
- scene->setAction(&scene->_sequenceManager, scene, 3260, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3260, &R2_GLOBALS._player, &scene->_topDoor, NULL);
break;
case 302:
scene->_sceneMode = 3261;
- scene->setAction(&scene->_sequenceManager, scene, 3261, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3261, &R2_GLOBALS._player, &scene->_rightDoor, NULL);
break;
default:
break;
@@ -1153,65 +1179,66 @@ void Scene3250::postInit(SceneObjectList *OwnerList) {
loadScene(3250);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_GLOBALS._player._oldCharacterScene[3] = 1200;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1200;
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
}
SceneExt::postInit();
- _actor1.postInit();
- _actor1.setup(3250, 6, 1);
- _actor1.setPosition(Common::Point(25, 148));
- _actor1.fixPriority(10);
- _actor1.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
-
- _actor2.postInit();
- _actor2.setup(3250, 4, 1);
- _actor2.setPosition(Common::Point(259, 126));
- _actor2.fixPriority(10);
- _actor2.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
-
- _actor3.postInit();
- _actor3.setup(3250, 5, 1);
- _actor3.setPosition(Common::Point(302, 138));
- _actor3.fixPriority(10);
- _actor3.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
-
- _item3.setDetails(Rect(119, 111, 149, 168), 3250, 6, 7, 2, 1, NULL);
- _item2.setDetails(Rect(58, 85, 231, 138), 3250, 12, 7, 2, 1, NULL);
- _item4.setDetails(12, 3250, 3, 1, 2);
- _item1.setDetails(Rect(0, 0, 320, 200), 3250, 0, 1, 2, 1, NULL);
+ _leftDoor.postInit();
+ _leftDoor.setup(3250, 6, 1);
+ _leftDoor.setPosition(Common::Point(25, 148));
+ _leftDoor.fixPriority(10);
+ _leftDoor.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _topDoor.postInit();
+ _topDoor.setup(3250, 4, 1);
+ _topDoor.setPosition(Common::Point(259, 126));
+ _topDoor.fixPriority(10);
+ _topDoor.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _rightDoor.postInit();
+ _rightDoor.setup(3250, 5, 1);
+ _rightDoor.setPosition(Common::Point(302, 138));
+ _rightDoor.fixPriority(10);
+ _rightDoor.setDetails(3250, 9, 10, -1, 1, (SceneItem *)NULL);
+
+ _floodLights.setDetails(Rect(119, 111, 149, 168), 3250, 6, 7, 2, 1, NULL);
+ _tnuctipunShip.setDetails(Rect(58, 85, 231, 138), 3250, 12, 7, 2, 1, NULL);
+ _negator.setDetails(12, 3250, 3, 1, 2);
+ _background.setDetails(Rect(0, 0, 320, 200), 3250, 0, 1, 2, 1, NULL);
R2_GLOBALS._player.postInit();
- switch (R2_GLOBALS._player._oldCharacterScene[3]) {
+ switch (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA]) {
case 1200:
_sceneMode = 3250;
- _actor4.postInit();
- R2_GLOBALS._player._effect = 0;
- setAction(&_sequenceManager, this, 3250, &R2_GLOBALS._player, &_actor4, NULL);
+ _grate.postInit();
+ R2_GLOBALS._player._effect = EFFECT_NONE;
+ setAction(&_sequenceManager, this, 3250, &R2_GLOBALS._player, &_grate, NULL);
break;
case 3125:
if (R2_GLOBALS.getFlag(79)) {
_sceneMode = 3254;
- _actor5.postInit();
- _actor5._effect = 1;
- _actor6.postInit();
- _actor6._effect = 1;
- _actor7.postInit();
- _actor7._effect = 1;
- setAction(&_sequenceManager, this, 3254, &R2_GLOBALS._player, &_actor3, &_actor5, &_actor6, &_actor7, &_actor1, NULL);
+ _ghoul1.postInit();
+ _ghoul1._effect = EFFECT_SHADED;
+ _ghoul2.postInit();
+ _ghoul2._effect = EFFECT_SHADED;
+ _ghoul3.postInit();
+ _ghoul3._effect = EFFECT_SHADED;
+ setAction(&_sequenceManager, this, 3254, &R2_GLOBALS._player, &_rightDoor,
+ &_ghoul1, &_ghoul2, &_ghoul3, &_leftDoor, NULL);
} else {
_sceneMode = 3252;
- setAction(&_sequenceManager, this, 3252, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3252, &R2_GLOBALS._player, &_rightDoor, NULL);
}
break;
case 3175:
_sceneMode = 3251;
- setAction(&_sequenceManager, this, 3251, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3251, &R2_GLOBALS._player, &_topDoor, NULL);
break;
case 3255:
_sceneMode = 3253;
- setAction(&_sequenceManager, this, 3253, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 3253, &R2_GLOBALS._player, &_leftDoor, NULL);
break;
default:
R2_GLOBALS._player.setup(31, 3, 1);
@@ -1221,13 +1248,13 @@ void Scene3250::postInit(SceneObjectList *OwnerList) {
break;
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3250;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3250;
}
void Scene3250::signal() {
switch(_sceneMode) {
case 3250:
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
R2_GLOBALS._player.enableControl();
break;
case 3254:
@@ -1249,7 +1276,7 @@ void Scene3250::signal() {
void Scene3250::dispatch() {
if ((R2_GLOBALS._player._visage == 3250) && (R2_GLOBALS._player._strip == 3) && (R2_GLOBALS._player._effect == 0)) {
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 6;
}
@@ -1257,9 +1284,10 @@ void Scene3250::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 3255 -
+ * Scene 3255 - Guard Post
*
*--------------------------------------------------------------------------*/
+
void Scene3255::postInit(SceneObjectList *OwnerList) {
loadScene(3255);
SceneExt::postInit();
@@ -1277,31 +1305,32 @@ void Scene3255::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(267);
R2_GLOBALS._sound2.play(268);
_sceneMode = 3257;
- _actor3.postInit();
- _actor4.postInit();
- _actor4._effect = 1;
- setAction(&_sequenceManager, this, 3257, &R2_GLOBALS._player, &_actor4, &_actor3, NULL);
+ _door.postInit();
+ _quinn.postInit();
+ _quinn._effect = EFFECT_SHADED;
+ setAction(&_sequenceManager, this, 3257, &R2_GLOBALS._player, &_quinn, &_door, NULL);
} else {
- _actor1.postInit();
- _actor1.setup(303, 1, 1);
- _actor1.setPosition(Common::Point(208, 128));
- _actor2.postInit();
- _actor2.setup(3107, 3, 1);
- _actor2.setPosition(Common::Point(230, 127));
+ _teal.postInit();
+ _teal.setup(303, 1, 1);
+ _teal.setPosition(Common::Point(208, 128));
+ _guard.postInit();
+ _guard.setup(3107, 3, 1);
+ _guard.setPosition(Common::Point(230, 127));
_sceneMode = 3255;
setAction(&_sequenceManager, this, 3255, &R2_GLOBALS._player, NULL);
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3255;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3255;
}
void Scene3255::signal() {
switch (_sceneMode) {
case 10:
_sceneMode = 3258;
- _actor5.postInit();
- _actor6.postInit();
- _actor7.postInit();
- setAction(&_sequenceManager, this, 3258, &R2_GLOBALS._player, &_actor4, &_actor3, &_actor5, &_actor6, &_actor7, NULL);
+ _ghoul1.postInit();
+ _ghoul2.postInit();
+ _ghoul3.postInit();
+ setAction(&_sequenceManager, this, 3258, &R2_GLOBALS._player, &_quinn,
+ &_door, &_ghoul1, &_ghoul2, &_ghoul3, NULL);
break;
case 3256:
R2_GLOBALS._sceneManager.changeScene(3250);
@@ -1315,7 +1344,7 @@ void Scene3255::signal() {
R2_GLOBALS._sceneManager.changeScene(3100);
break;
default:
- SceneItem::display(3255, 0, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3255, 0, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
_sceneMode = 3256;
setAction(&_sequenceManager, this, 3256, &R2_GLOBALS._player, NULL);
}
@@ -1323,40 +1352,40 @@ void Scene3255::signal() {
void Scene3255::dispatch() {
if (R2_GLOBALS.getFlag(79)) {
- if (_actor5._position.y >= 95) {
- if (_actor5._position.y <= 110)
- _actor5._shade = 6 - (_actor5._position.y - 95) / 3;
+ if (_ghoul1._position.y >= 95) {
+ if (_ghoul1._position.y <= 110)
+ _ghoul1._shade = 6 - (_ghoul1._position.y - 95) / 3;
else
- _actor5._effect = 1;
+ _ghoul1._effect = EFFECT_SHADED;
} else {
- _actor5._effect = 6;
- _actor5._shade = 6;
+ _ghoul1._effect = EFFECT_SHADED2;
+ _ghoul1._shade = 6;
}
- if (_actor6._position.y >= 95) {
- if (_actor6._position.y <= 110)
- _actor6._shade = 6 - (_actor6._position.y - 95) / 3;
+ if (_ghoul2._position.y >= 95) {
+ if (_ghoul2._position.y <= 110)
+ _ghoul2._shade = 6 - (_ghoul2._position.y - 95) / 3;
else
- _actor6._effect = 1;
+ _ghoul2._effect = EFFECT_SHADED;
} else {
- _actor6._effect = 6;
- _actor6._shade = 6;
+ _ghoul2._effect = EFFECT_SHADED2;
+ _ghoul2._shade = 6;
}
- if (_actor7._position.y >= 95) {
- if (_actor7._position.y <= 110)
- _actor7._shade = 6 - (_actor7._position.y - 95) / 3;
+ if (_ghoul3._position.y >= 95) {
+ if (_ghoul3._position.y <= 110)
+ _ghoul3._shade = 6 - (_ghoul3._position.y - 95) / 3;
else
- _actor7._effect = 1;
+ _ghoul3._effect = EFFECT_SHADED;
} else {
- _actor7._effect = 6;
- _actor7._shade = 6;
+ _ghoul3._effect = EFFECT_SHADED2;
+ _ghoul3._shade = 6;
}
}
if ((R2_GLOBALS._player._position.x > 250) && (R2_GLOBALS._player._shade == 1)) {
- R2_GLOBALS._player._effect = 6;
- _actor4._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
+ _quinn._effect = EFFECT_SHADED2;
}
Scene::dispatch();
}
@@ -1365,27 +1394,28 @@ void Scene3255::dispatch() {
* Scene 3260 - Computer room
*
*--------------------------------------------------------------------------*/
-bool Scene3260::Actor13::startAction(CursorType action, Event &event) {
- Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+bool Scene3260::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3271;
- scene->setAction(&scene->_sequenceManager, scene, 3271, &R2_GLOBALS._player, &scene->_actor13, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3271, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
-bool Scene3260::Actor14::startAction(CursorType action, Event &event) {
- Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3260::Toolbox::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3272;
- scene->setAction(&scene->_sequenceManager, scene, 3272, &R2_GLOBALS._player, &scene->_actor14, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3272, &R2_GLOBALS._player, &scene->_toolbox, NULL);
return true;
}
@@ -1402,103 +1432,103 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
R2_GLOBALS._sound1.play(285);
- _actor13.postInit();
- _actor13.setup(3260, 6, 1);
- _actor13.setPosition(Common::Point(40, 106));
- _actor13.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
+ _door.postInit();
+ _door.setup(3260, 6, 1);
+ _door.setPosition(Common::Point(40, 106));
+ _door.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(52) == 3260) {
- _actor14.postInit();
- _actor14.setup(3260, 7, 1);
- _actor14.setPosition(Common::Point(202, 66));
- _actor14.setDetails(3260, 12, 1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_TOOLBOX) == 3260) {
+ _toolbox.postInit();
+ _toolbox.setup(3260, 7, 1);
+ _toolbox.setPosition(Common::Point(202, 66));
+ _toolbox.setDetails(3260, 12, 1, -1, 1, (SceneItem *)NULL);
}
- _actor1.postInit();
- _actor1.setup(3260, 1, 1);
- _actor1.setPosition(Common::Point(93, 73));
- _actor1.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor1.setAction(&_action1, &_actor1);
-
- _actor2.postInit();
- _actor2.setup(3260, 2, 1);
- _actor2.setPosition(Common::Point(142, 63));
- _actor2.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor2.setAction(&_action2, &_actor2);
-
- _actor3.postInit();
- _actor3.setup(3260, 2, 1);
- _actor3.setPosition(Common::Point(166, 54));
- _actor3.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor3.setAction(&_action3, &_actor3);
-
- _actor4.postInit();
- _actor4.setup(3260, 2, 1);
- _actor4.setPosition(Common::Point(190, 46));
- _actor4.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor4.setAction(&_action4, &_actor4);
-
- _actor5.postInit();
- _actor5.setup(3260, 2, 1);
- _actor5.setPosition(Common::Point(142, 39));
- _actor5.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor5.setAction(&_action5, &_actor5);
-
- _actor6.postInit();
- _actor6.setup(3260, 2, 1);
- _actor6.setPosition(Common::Point(166, 30));
- _actor6.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor6.setAction(&_action6, &_actor6);
-
- _actor7.postInit();
- _actor7.setup(3260, 2, 1);
- _actor7.setPosition(Common::Point(190, 22));
- _actor7.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor7.setAction(&_action7, &_actor7);
-
- _actor8.postInit();
- _actor8.setup(3260, 2, 1);
- _actor8.setPosition(Common::Point(142, 14));
- _actor8.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor8.setAction(&_action8, &_actor8);
-
- _actor9.postInit();
- _actor9.setup(3260, 2, 1);
- _actor9.setPosition(Common::Point(166, 6));
- _actor9.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor9.setAction(&_action9, &_actor9);
-
- _actor10.postInit();
- _actor10.setup(3260, 3, 1);
- _actor10.setPosition(Common::Point(265, 163));
- _actor10.fixPriority(180);
- _actor10._numFrames = 10;
- _actor10.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
- _actor10.animate(ANIM_MODE_2, NULL);
-
- _actor11.postInit();
- _actor11.setup(3260, 4, 1);
- _actor11.setPosition(Common::Point(127, 108));
- _actor11.fixPriority(120);
- _actor11.setAction(&_action11, &_actor11);
- _actor11._numFrames = 15;
- _actor11.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
- _actor11.animate(ANIM_MODE_2, NULL);
-
- _actor12.postInit();
- _actor12.setup(3260, 5, 1);
- _actor12.setPosition(Common::Point(274, 65));
- _actor12.setAction(&_action12, &_actor12);
- _actor12._numFrames = 5;
- _actor12.setDetails(3260, 9, 1, 11, 1, (SceneItem *)NULL);
- _actor12.animate(ANIM_MODE_2, NULL);
-
- _item1.setDetails(Rect(0, 0, 320, 200), 3260, 0, 1, 2, 1, NULL);
+ _sceeen1.postInit();
+ _sceeen1.setup(3260, 1, 1);
+ _sceeen1.setPosition(Common::Point(93, 73));
+ _sceeen1.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _sceeen1.setAction(&_action1, &_sceeen1);
+
+ _screen2.postInit();
+ _screen2.setup(3260, 2, 1);
+ _screen2.setPosition(Common::Point(142, 63));
+ _screen2.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen2.setAction(&_action2, &_screen2);
+
+ _screen3.postInit();
+ _screen3.setup(3260, 2, 1);
+ _screen3.setPosition(Common::Point(166, 54));
+ _screen3.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen3.setAction(&_action3, &_screen3);
+
+ _screen4.postInit();
+ _screen4.setup(3260, 2, 1);
+ _screen4.setPosition(Common::Point(190, 46));
+ _screen4.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen4.setAction(&_action4, &_screen4);
+
+ _screen5.postInit();
+ _screen5.setup(3260, 2, 1);
+ _screen5.setPosition(Common::Point(142, 39));
+ _screen5.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen5.setAction(&_action5, &_screen5);
+
+ _screen6.postInit();
+ _screen6.setup(3260, 2, 1);
+ _screen6.setPosition(Common::Point(166, 30));
+ _screen6.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen6.setAction(&_action6, &_screen6);
+
+ _screen7.postInit();
+ _screen7.setup(3260, 2, 1);
+ _screen7.setPosition(Common::Point(190, 22));
+ _screen7.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen7.setAction(&_action7, &_screen7);
+
+ _screen8.postInit();
+ _screen8.setup(3260, 2, 1);
+ _screen8.setPosition(Common::Point(142, 14));
+ _screen8.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen8.setAction(&_action8, &_screen8);
+
+ _screen9.postInit();
+ _screen9.setup(3260, 2, 1);
+ _screen9.setPosition(Common::Point(166, 6));
+ _screen9.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen9.setAction(&_action9, &_screen9);
+
+ _securityConsole.postInit();
+ _securityConsole.setup(3260, 3, 1);
+ _securityConsole.setPosition(Common::Point(265, 163));
+ _securityConsole.fixPriority(180);
+ _securityConsole._numFrames = 10;
+ _securityConsole.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
+ _securityConsole.animate(ANIM_MODE_2, NULL);
+
+ _computerConsole.postInit();
+ _computerConsole.setup(3260, 4, 1);
+ _computerConsole.setPosition(Common::Point(127, 108));
+ _computerConsole.fixPriority(120);
+ _computerConsole.setAction(&_action11, &_computerConsole);
+ _computerConsole._numFrames = 15;
+ _computerConsole.setDetails(3260, 6, 1, 8, 1, (SceneItem *)NULL);
+ _computerConsole.animate(ANIM_MODE_2, NULL);
+
+ _lightingConsole.postInit();
+ _lightingConsole.setup(3260, 5, 1);
+ _lightingConsole.setPosition(Common::Point(274, 65));
+ _lightingConsole.setAction(&_action12, &_lightingConsole);
+ _lightingConsole._numFrames = 5;
+ _lightingConsole.setDetails(3260, 9, 1, 11, 1, (SceneItem *)NULL);
+ _lightingConsole.animate(ANIM_MODE_2, NULL);
+
+ _background.setDetails(Rect(0, 0, 320, 200), 3260, 0, 1, 2, 1, NULL);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._oldCharacterScene[3] == 3275) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3275) {
_sceneMode = 3270;
- setAction(&_sequenceManager, this, 3270, &R2_GLOBALS._player, &_actor13, NULL);
+ setAction(&_sequenceManager, this, 3270, &R2_GLOBALS._player, &_door, NULL);
} else {
R2_GLOBALS._player.setup(30, 5, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -1506,7 +1536,7 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._player.enableControl();
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3260;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3260;
}
void Scene3260::remove() {
@@ -1521,15 +1551,15 @@ void Scene3260::signal() {
break;
case 3272:
_sceneMode = 3273;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(52, 3);
- R2_INVENTORY.setObjectScene(43, 3);
- setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_actor14, NULL);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3);
+ R2_INVENTORY.setObjectScene(R2_LASER_HACKSAW, 3);
+ setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_toolbox, NULL);
break;
case 3273:
- _actor4.remove();
+ _screen4.remove();
R2_GLOBALS._player.enableControl();
break;
default:
@@ -1542,19 +1572,20 @@ void Scene3260::signal() {
* Scene 3275 - Hall
*
*--------------------------------------------------------------------------*/
-bool Scene3275::Actor2::startAction(CursorType action, Event &event) {
- Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
+bool Scene3275::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3275;
- scene->setAction(&scene->_sequenceManager, scene, 3275, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3275, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
-void Scene3275::Exit1::changeScene() {
+void Scene3275::CellExit::changeScene() {
Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 0;
@@ -1573,33 +1604,31 @@ void Scene3275::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sceneManager._previousScene = 3260;
if (R2_GLOBALS._sceneManager._previousScene == 3150)
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
- else
- g_globals->gfxManager()._bounds.moveTo(Common::Point(0, 0));
+ _sceneBounds = Rect(160, 0, 480, 200);
SceneExt::postInit();
- _exit1.setDetails(Rect(398, 60, 439, 118), SHADECURSOR_UP, 3150);
- _exit1.setDest(Common::Point(418, 128));
+ _cellExit.setDetails(Rect(398, 60, 439, 118), SHADECURSOR_UP, 3150);
+ _cellExit.setDest(Common::Point(418, 128));
- _actor1.postInit();
- _actor1.setup(3275, 1, 7);
- _actor1.setPosition(Common::Point(419, 119));
+ _doorFrame.postInit();
+ _doorFrame.setup(3275, 1, 7);
+ _doorFrame.setPosition(Common::Point(419, 119));
- _actor2.postInit();
- _actor2.setup(3275, 2, 1);
- _actor2.setPosition(Common::Point(56, 118));
- _actor2.setDetails(3275, 3, 4, -1, 1, (SceneItem *)NULL);
+ _door.postInit();
+ _door.setup(3275, 2, 1);
+ _door.setPosition(Common::Point(56, 118));
+ _door.setDetails(3275, 3, 4, -1, 1, (SceneItem *)NULL);
- _item2.setDetails(Rect(153, 58, 200, 120), 3275, 6, 7, 8, 1, NULL);
- _item3.setDetails(Rect(275, 58, 331, 120), 3275, 6, 7, 8, 1, NULL);
- _item4.setDetails(Rect(0, 66, 22, 127), 3275, 9, 10, 11, 1, NULL);
- _item5.setDetails(Rect(457, 66, 480, 127), 3275, 9, 10, 11, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 3275, 0, 1, 2, 1, NULL);
+ _emptyCell1.setDetails(Rect(153, 58, 200, 120), 3275, 6, 7, 8, 1, NULL);
+ _emptyCell2.setDetails(Rect(275, 58, 331, 120), 3275, 6, 7, 8, 1, NULL);
+ _securityBeams1.setDetails(Rect(0, 66, 22, 127), 3275, 9, 10, 11, 1, NULL);
+ _securityBeams2.setDetails(Rect(457, 66, 480, 127), 3275, 9, 10, 11, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 3275, 0, 1, 2, 1, NULL);
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._oldCharacterScene[3] == 3150) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3150) {
_sceneMode = 11;
R2_GLOBALS._player.setup(30, 3, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -1608,9 +1637,9 @@ void Scene3275::postInit(SceneObjectList *OwnerList) {
Common::Point pt(418, 128);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if (R2_GLOBALS._player._oldCharacterScene[3] == 3260) {
+ } else if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3260) {
_sceneMode = 3276;
- setAction(&_sequenceManager, this, 3276, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3276, &R2_GLOBALS._player, &_door, NULL);
} else {
R2_GLOBALS._player.setup(30, 3, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -1618,7 +1647,7 @@ void Scene3275::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._player.enableControl();
}
- R2_GLOBALS._player._oldCharacterScene[3] = 3275;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3275;
}
void Scene3275::signal() {
@@ -1639,10 +1668,12 @@ void Scene3275::signal() {
* Scene 3350 - Cutscene - Ship landing
*
*--------------------------------------------------------------------------*/
+
void Scene3350::postInit(SceneObjectList *OwnerList) {
loadScene(3350);
R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._sound2.play(310);
_rotation = R2_GLOBALS._scenePalette.addRotation(176, 203, 1);
@@ -1652,27 +1683,27 @@ void Scene3350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor1.hide();
- _actor2.postInit();
- _actor2.hide();
- _actor3.postInit();
- _actor3.hide();
- _actor4.postInit();
- _actor4.hide();
- _actor9.postInit();
- _actor9.hide();
- _actor8.postInit();
- _actor8.hide();
- _actor5.postInit();
- _actor5.hide();
- _actor6.postInit();
- _actor6.hide();
- _actor7.postInit();
- _actor7.hide();
+ _miranda.postInit();
+ _miranda.hide();
+ _seeker.postInit();
+ _seeker.hide();
+ _webbster.postInit();
+ _webbster.hide();
+ _seatedPeople.postInit();
+ _seatedPeople.hide();
+ _shipFront.postInit();
+ _shipFront.hide();
+ _canopy.postInit();
+ _canopy.hide();
+ _ship.postInit();
+ _ship.hide();
+ _landedShip.postInit();
+ _landedShip.hide();
+ _shipShadow.postInit();
+ _shipShadow.hide();
_sceneMode = 3350;
- setAction(&_sequenceManager, this, _sceneMode, &_actor5, &_actor6, &_actor7, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &_ship, &_landedShip, &_shipShadow, NULL);
}
void Scene3350::remove() {
@@ -1684,11 +1715,13 @@ void Scene3350::signal() {
switch (_sceneMode) {
case 3350:
_sceneMode = 3351;
- setAction(&_sequenceManager, this, 3351, &_actor4, &_actor9, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 3351, &_seatedPeople, &_shipFront, &_canopy, NULL);
break;
case 3351:
_sceneMode = 3352;
- setAction(&_sequenceManager, this, 3352, &_actor4, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3352, &_seatedPeople, &R2_GLOBALS._player,
+ &_miranda, &_seeker, &_webbster, NULL);
+ break;
case 3352:
R2_GLOBALS._sceneManager.changeScene(3395);
break;
@@ -1699,109 +1732,103 @@ void Scene3350::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 3375 -
+ * Scene 3375 - Circular Walkway
*
*--------------------------------------------------------------------------*/
-Scene3375::Scene3375() {
- _field1488 = _field1492 = 0;
- for (int i = 0; i < 4; ++i)
- _field148A[i] = 0;
-}
void Scene3375::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1488);
- s.syncAsSint16LE(_field1492);
+ s.syncAsSint16LE(_newSceneMode);
for (int i = 0; i < 4; ++i)
- s.syncAsSint16LE(_field148A[i]);
+ s.syncAsSint16LE(_sceneAreas[i]);
}
-void Scene3375::subFC696(int sceneMode) {
+void Scene3375::enterArea(int sceneMode) {
switch (sceneMode) {
case 3379:
R2_GLOBALS._player.setPosition(Common::Point(0, 155));
- _actor1.setPosition(Common::Point(-20, 163));
- _actor2.setPosition(Common::Point(-5, 150));
- _actor3.setPosition(Common::Point(-20, 152));
+ _companion1.setPosition(Common::Point(-20, 163));
+ _companion2.setPosition(Common::Point(-5, 150));
+ _webbster.setPosition(Common::Point(-20, 152));
break;
case 3380:
- ++R2_GLOBALS._v56A9E;
- if (R2_GLOBALS._v56A9E >= 4)
- R2_GLOBALS._v56A9E = 0;
+ ++R2_GLOBALS._walkwaySceneNumber;
+ if (R2_GLOBALS._walkwaySceneNumber >= 4)
+ R2_GLOBALS._walkwaySceneNumber = 0;
- loadScene(_field148A[R2_GLOBALS._v56A9E]);
+ loadScene(_sceneAreas[R2_GLOBALS._walkwaySceneNumber]);
R2_GLOBALS._uiElements.show();
R2_GLOBALS._player.setStrip(4);
R2_GLOBALS._player.setPosition(Common::Point(148, 230));
- _actor1.setPosition(Common::Point(191, 274));
- _actor1._effect = 1;
- _actor2.setPosition(Common::Point(124, 255));
- _actor2._effect = 1;
- _actor3.setPosition(Common::Point(155, 245));
- _actor3._effect = 1;
+ _companion1.setPosition(Common::Point(191, 274));
+ _companion1._effect = EFFECT_SHADED;
+ _companion2.setPosition(Common::Point(124, 255));
+ _companion2._effect = EFFECT_SHADED;
+ _webbster.setPosition(Common::Point(155, 245));
+ _webbster._effect = EFFECT_SHADED;
break;
case 3381:
- --R2_GLOBALS._v56A9E;
- if (R2_GLOBALS._v56A9E < 0)
- R2_GLOBALS._v56A9E = 3;
+ --R2_GLOBALS._walkwaySceneNumber;
+ if (R2_GLOBALS._walkwaySceneNumber < 0)
+ R2_GLOBALS._walkwaySceneNumber = 3;
- loadScene(_field148A[R2_GLOBALS._v56A9E]);
+ loadScene(_sceneAreas[R2_GLOBALS._walkwaySceneNumber]);
R2_GLOBALS._uiElements.show();
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.setPosition(Common::Point(201, 131));
- _actor1.setPosition(Common::Point(231, 127));
- _actor1._effect = 1;
- _actor2.setPosition(Common::Point(231, 127));
- _actor2._effect = 1;
- _actor3.setPosition(Common::Point(231, 127));
- _actor3._effect = 1;
+ _companion1.setPosition(Common::Point(231, 127));
+ _companion1._effect = EFFECT_SHADED;
+ _companion2.setPosition(Common::Point(231, 127));
+ _companion2._effect = EFFECT_SHADED;
+ _webbster.setPosition(Common::Point(231, 127));
+ _webbster._effect = EFFECT_SHADED;
break;
default:
R2_GLOBALS._player.setPosition(Common::Point(192, 155));
- _actor1.setPosition(Common::Point(138, 134));
- _actor2.setPosition(Common::Point(110, 139));
- _actor3.setPosition(Common::Point(125, 142));
+ _companion1.setPosition(Common::Point(138, 134));
+ _companion2.setPosition(Common::Point(110, 139));
+ _webbster.setPosition(Common::Point(125, 142));
break;
}
- if (R2_GLOBALS._v56A9E == 2) {
- R2_GLOBALS._sceneItems.remove(&_actor4);
+ if (R2_GLOBALS._walkwaySceneNumber == 2) {
+ R2_GLOBALS._sceneItems.remove(&_door);
for (int i = 0; i <= 12; i++)
R2_GLOBALS._sceneItems.remove(&_itemArray[i]);
- R2_GLOBALS._sceneItems.remove(&_item1);
+ R2_GLOBALS._sceneItems.remove(&_background);
- _actor4.show();
- _actor4.setDetails(3375, 9, 10, -1, 1, (SceneItem *)NULL);
+ _door.show();
+ _door.setDetails(3375, 9, 10, -1, 1, (SceneItem *)NULL);
for (int i = 0; i <= 12; i++)
_itemArray[i].setDetails(3375, 3, -1, -1);
- _item1.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, -1, 1, NULL);
} else {
- _actor4.hide();
- R2_GLOBALS._sceneItems.remove(&_actor4);
+ _door.hide();
+ R2_GLOBALS._sceneItems.remove(&_door);
}
if (_sceneMode == 0)
signal();
else
- setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_companion1, &_companion2, &_webbster, NULL);
}
-bool Scene3375::Actor1::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3375::Companion2::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3304, scene);
@@ -1809,14 +1836,14 @@ bool Scene3375::Actor1::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3375::Actor2::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3375::Companion1::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3301, scene);
@@ -1824,69 +1851,70 @@ bool Scene3375::Actor2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3375::Actor3::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3375::Webbster::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
return true;
}
-bool Scene3375::Actor4::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3375::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._v56A9E != 0) {
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(3);
+ if (R2_GLOBALS._walkwaySceneNumber != 0) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
} else {
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
}
- R2_GLOBALS._walkRegions.disableRegion(6);
- R2_GLOBALS._walkRegions.disableRegion(7);
- R2_GLOBALS._walkRegions.disableRegion(8);
+ R2_GLOBALS._walkRegions.enableRegion(6);
+ R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(8);
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3375;
- scene->setAction(&scene->_sequenceManager, scene, 3375, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3375, &R2_GLOBALS._player,
+ &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door, NULL);
return true;
}
-void Scene3375::Exit1::changeScene() {
+void Scene3375::LeftExit::changeScene() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3376;
- if (R2_GLOBALS._v56A9E != 0) {
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(3);
+ if (R2_GLOBALS._walkwaySceneNumber != 0) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
} else {
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
}
- if (scene->_actor1._position.y != 163) {
- R2_GLOBALS._player.setStrip(-1);
- scene->_actor1.setStrip2(-1);
- scene->_actor2.setStrip2(-1);
- scene->_actor3.setStrip2(-1);
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ if (scene->_companion1._position.y != 163) {
+ R2_GLOBALS._player.setStrip2(-1);
+ scene->_companion1.setStrip2(-1);
+ scene->_companion2.setStrip2(-1);
+ scene->_webbster.setStrip2(-1);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2, &scene->_webbster, NULL);
} else {
R2_GLOBALS._player.setStrip2(2);
- scene->_actor1.setStrip2(2);
- scene->_actor2.setStrip2(2);
- scene->_actor3.setStrip2(2);
+ scene->_companion1.setStrip2(2);
+ scene->_companion2.setStrip2(2);
+ scene->_webbster.setStrip2(2);
R2_GLOBALS._sound2.play(314);
Common::Point pt(50, 150);
@@ -1895,57 +1923,61 @@ void Scene3375::Exit1::changeScene() {
}
}
-void Scene3375::Exit2::changeScene() {
+void Scene3375::DownExit::changeScene() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 4;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3377;
- scene->_field1488 = 3381;
+ scene->_newSceneMode = 3381;
- if (R2_GLOBALS._v56A9E != 0) {
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(3);
+ if (R2_GLOBALS._walkwaySceneNumber != 0) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
} else {
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
}
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2, &scene->_webbster, NULL);
}
-void Scene3375::Exit3::changeScene() {
+void Scene3375::RightExit::changeScene() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 4;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3378;
- scene->_field1488 = 3380;
+ scene->_newSceneMode = 3380;
- if (R2_GLOBALS._v56A9E != 0) {
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(3);
+ if (R2_GLOBALS._walkwaySceneNumber != 0) {
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(3);
} else {
- R2_GLOBALS._walkRegions.disableRegion(1);
- R2_GLOBALS._walkRegions.disableRegion(3);
- R2_GLOBALS._walkRegions.disableRegion(4);
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.enableRegion(3);
+ R2_GLOBALS._walkRegions.enableRegion(4);
}
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2, &scene->_webbster, NULL);
}
-void Scene3375::postInit(SceneObjectList *OwnerList) {
- _field148A[0] = 3376;
- _field148A[1] = 3377;
- _field148A[2] = 3375;
- _field148A[3] = 3378;
+Scene3375::Scene3375() {
+ _newSceneMode = 0;
+
+ _sceneAreas[0] = 3376;
+ _sceneAreas[1] = 3377;
+ _sceneAreas[2] = 3375;
+ _sceneAreas[3] = 3378;
+}
- loadScene(_field148A[R2_GLOBALS._v56A9E]);
+void Scene3375::postInit(SceneObjectList *OwnerList) {
+ loadScene(_sceneAreas[R2_GLOBALS._walkwaySceneNumber]);
SceneExt::postInit();
R2_GLOBALS._sound1.play(313);
@@ -1957,28 +1989,28 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3375;
- R2_GLOBALS._player._characterScene[2] = 3375;
- R2_GLOBALS._player._characterScene[3] = 3375;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3375;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3375;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3375;
setZoomPercents(126, 55, 200, 167);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- } else {
+ else
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- }
+
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._player._characterIndex) {
- case 2:
+ case R2_SEEKER:
if (R2_GLOBALS._sceneManager._previousScene == 3385)
R2_GLOBALS._player.setup(20, 1, 1);
else
R2_GLOBALS._player.setup(20, 3, 1);
break;
- case 3:
+ case R2_MIRANDA:
if (R2_GLOBALS._sceneManager._previousScene == 3385)
R2_GLOBALS._player.setup(30, 1, 1);
else
@@ -1995,16 +2027,16 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor1._moveRate = 10;
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _companion1._moveRate = 10;
+ _companion1._moveDiff = Common::Point(3, 2);
} else {
- _actor1._moveRate = 7;
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion1._moveRate = 7;
+ _companion1._moveDiff = Common::Point(5, 3);
}
- _actor1.changeZoom(-1);
- _actor1._effect = 1;
+ _companion1.changeZoom(-1);
+ _companion1._effect = EFFECT_SHADED;
int tmpStrip, tmpVisage;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2012,72 +2044,72 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
else
tmpStrip = 4;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
tmpVisage = 10;
else
tmpVisage = 20;
- _actor1.setup(tmpVisage, tmpStrip, 1);
- _actor1.animate(ANIM_MODE_1, NULL);
+ _companion1.setup(tmpVisage, tmpStrip, 1);
+ _companion1.animate(ANIM_MODE_1, NULL);
- _actor2.postInit();
- _actor2._moveDiff = Common::Point(3, 2);
- _actor2.changeZoom(-1);
- _actor2._effect = 1;
+ _companion2.postInit();
+ _companion2._moveDiff = Common::Point(3, 2);
+ _companion2.changeZoom(-1);
+ _companion2._effect = EFFECT_SHADED;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
tmpStrip = 1;
else
tmpStrip = 8;
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
tmpVisage = 10;
else
tmpVisage = 30;
- _actor2.setup(tmpVisage, tmpStrip, 1);
- _actor2.animate(ANIM_MODE_1, NULL);
+ _companion2.setup(tmpVisage, tmpStrip, 1);
+ _companion2.animate(ANIM_MODE_1, NULL);
- _actor3.postInit();
- _actor3._moveRate = 7;
- _actor3._moveDiff = Common::Point(5, 3);
- _actor3.changeZoom(-1);
- _actor3._effect = 1;
+ _webbster.postInit();
+ _webbster._moveRate = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
tmpStrip = 1;
else
tmpStrip = 4;
- _actor3.setup(40, tmpStrip, 1);
- _actor3.animate(ANIM_MODE_1, NULL);
+ _webbster.setup(40, tmpStrip, 1);
+ _webbster.animate(ANIM_MODE_1, NULL);
- _actor2.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
- _actor3.setDetails(3375, 21, -1, -1, 1, (SceneItem *)NULL);
- _actor1.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
+ _companion2.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
+ _webbster.setDetails(3375, 21, -1, -1, 1, (SceneItem *)NULL);
+ _companion1.setDetails(3375, -1, -1, -1, 1, (SceneItem *)NULL);
- _actor4.postInit();
- _actor4.setup(3375, 1, 1);
- _actor4.setPosition(Common::Point(254, 166));
- _actor4.fixPriority(140);
- _actor4.hide();
+ _door.postInit();
+ _door.setup(3375, 1, 1);
+ _door.setPosition(Common::Point(254, 166));
+ _door.fixPriority(140);
+ _door.hide();
- _exit1.setDetails(Rect(0, 84, 24, 167), EXITCURSOR_W, 3375);
- _exit1.setDest(Common::Point(65, 155));
- _exit2.setDetails(Rect(103, 152, 183, 170), SHADECURSOR_DOWN, 3375);
- _exit2.setDest(Common::Point(158, 151));
- _exit3.setDetails(Rect(180, 75, 213, 132), EXITCURSOR_E, 3375);
- _exit3.setDest(Common::Point(201, 131));
+ _leftExit.setDetails(Rect(0, 84, 24, 167), EXITCURSOR_W, 3375);
+ _leftExit.setDest(Common::Point(65, 155));
+ _downExit.setDetails(Rect(103, 152, 183, 170), SHADECURSOR_DOWN, 3375);
+ _downExit.setDest(Common::Point(158, 151));
+ _rightExit.setDetails(Rect(180, 75, 213, 132), EXITCURSOR_E, 3375);
+ _rightExit.setDest(Common::Point(201, 131));
for (int i = 0; i <= 12; ++i)
_itemArray[i].setDetails(i, 3375, 3, -1, -1);
- _item1.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, 1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3375, 0, -1, 1, 1, NULL);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
_sceneMode = 3379;
else
_sceneMode = 0;
- subFC696(_sceneMode);
+ enterArea(_sceneMode);
}
void Scene3375::remove() {
@@ -2086,44 +2118,61 @@ void Scene3375::remove() {
}
void Scene3375::signalCase3379() {
- switch (R2_GLOBALS._v56A9E) {
+ switch (R2_GLOBALS._walkwaySceneNumber) {
case 0:
- _exit1._enabled = true;
- if (R2_GLOBALS._sceneManager._previousScene == 3385)
- R2_GLOBALS._walkRegions.enableRegion(1);
- else {
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(4);
+ _leftExit._enabled = true;
+ if (R2_GLOBALS._sceneManager._previousScene == 3385) {
+ // WORKAROUND: The original disables the left entry region here for
+ // some reason. But there's also some walk issue even I leave it enabled.
+ // Instead, for now, add an extra walk into the properly enabled regions
+ _sceneMode = 1;
+ ADD_MOVER(R2_GLOBALS._player, 70, R2_GLOBALS._player._position.y);
+ R2_GLOBALS._sceneManager._previousScene = 3375;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion1._effect = EFFECT_SHADED;
+ _companion2._effect = EFFECT_SHADED;
+ _webbster._effect = EFFECT_SHADED;
+
+ return;
+ //R2_GLOBALS._walkRegions.disableRegion(1);
+ } else {
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(4);
}
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ break;
case 2:
- _exit1._enabled = false;
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._walkRegions.enableRegion(8);
- R2_GLOBALS._walkRegions.enableRegion(9);
+ _leftExit._enabled = false;
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(8);
+ R2_GLOBALS._walkRegions.disableRegion(9);
+ break;
default:
- _exit1._enabled = false;
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(3);
- R2_GLOBALS._walkRegions.enableRegion(5);
- R2_GLOBALS._walkRegions.enableRegion(6);
+ _leftExit._enabled = false;
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(3);
+ R2_GLOBALS._walkRegions.disableRegion(5);
+ R2_GLOBALS._walkRegions.disableRegion(6);
break;
}
R2_GLOBALS._sceneManager._previousScene = 3375;
- R2_GLOBALS._player._effect = 1;
- _actor1._effect = 1;
- _actor2._effect = 1;
- _actor3._effect = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion1._effect = EFFECT_SHADED;
+ _companion2._effect = EFFECT_SHADED;
+ _webbster._effect = EFFECT_SHADED;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
}
void Scene3375::signal() {
switch (_sceneMode) {
+ case 1:
+ R2_GLOBALS._player.enableControl();
+ break;
case 3375:
R2_GLOBALS._sceneManager.changeScene(3400);
break;
@@ -2133,29 +2182,39 @@ void Scene3375::signal() {
case 3377:
// No break on purpose
case 3378:
- _sceneMode = _field1488;
- _field1488 = 0;
- _actor1._effect = 6;
- _actor1._shade = 4;
- _actor2._effect = 6;
- _actor2._shade = 4;
- _actor3._effect = 6;
- _actor3._shade = 4;
- subFC696(_sceneMode);
+ _sceneMode = _newSceneMode;
+ _newSceneMode = 0;
+
+ _companion1._effect = EFFECT_SHADED2;
+ _companion1._shade = 4;
+ _companion2._effect = EFFECT_SHADED2;
+ _companion2._shade = 4;
+ _webbster._effect = EFFECT_SHADED2;
+ _webbster._shade = 4;
+
+ // HACK: Reset zooms in order to avoid giant characters on the upper right of the screen
+ R2_GLOBALS._player.setZoom(-1);
+ _companion1.setZoom(-1);
+ _companion2.setZoom(-1);
+ _webbster.setZoom(-1);
+ //
+
+ enterArea(_sceneMode);
break;
case 3379:
signalCase3379();
break;
case 9999:
- if (_actor1._position.y == 163)
+ if (_companion1._position.y == 163)
R2_GLOBALS._player.setStrip(1);
else
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
default:
- _actor1.setPriority(130);
- _actor2.setPriority(132);
- _actor3.setPriority(134);
+ _companion1.setPriority(130);
+ _companion2.setPriority(132);
+ _webbster.setPriority(134);
signalCase3379();
break;
}
@@ -2163,50 +2222,51 @@ void Scene3375::signal() {
void Scene3375::dispatch() {
if ((R2_GLOBALS._player._position.y >= 168) && (R2_GLOBALS._player._effect == 1))
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
else if ((R2_GLOBALS._player._position.y < 168) && (R2_GLOBALS._player._effect == 6))
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
- if ((_actor1._position.y >= 168) && (_actor1._effect == 1))
- _actor1._effect = 6;
- else if ((_actor1._position.y < 168) && (_actor1._effect == 6))
- _actor1._effect = 1;
+ if ((_companion1._position.y >= 168) && (_companion1._effect == 1))
+ _companion1._effect = EFFECT_SHADED2;
+ else if ((_companion1._position.y < 168) && (_companion1._effect == 6))
+ _companion1._effect = EFFECT_SHADED;
- if ((_actor2._position.y >= 168) && (_actor2._effect == 1))
- _actor2._effect = 6;
- else if ((_actor2._position.y < 168) && (_actor2._effect == 6))
- _actor2._effect = 1;
+ if ((_companion2._position.y >= 168) && (_companion2._effect == 1))
+ _companion2._effect = EFFECT_SHADED2;
+ else if ((_companion2._position.y < 168) && (_companion2._effect == 6))
+ _companion2._effect = EFFECT_SHADED;
- if ((_actor3._position.y >= 168) && (_actor3._effect == 1))
- _actor3._effect = 6;
- else if ((_actor3._position.y < 168) && (_actor3._effect == 6))
- _actor3._effect = 1;
+ if ((_webbster._position.y >= 168) && (_webbster._effect == 1))
+ _webbster._effect = EFFECT_SHADED2;
+ else if ((_webbster._position.y < 168) && (_webbster._effect == 6))
+ _webbster._effect = EFFECT_SHADED;
Scene::dispatch();
}
/*--------------------------------------------------------------------------
- * Scene 3385 -
+ * Scene 3385 - Corridor
*
*--------------------------------------------------------------------------*/
+
Scene3385::Scene3385() {
- _field11B2 = 0;
+ _playerStrip = 0;
}
void Scene3385::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field11B2);
+ s.syncAsSint16LE(_playerStrip);
}
-bool Scene3385::Actor1::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3385::Companion1::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3304, scene);
@@ -2214,14 +2274,14 @@ bool Scene3385::Actor1::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3385::Actor2::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3385::Companion2::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3301, scene);
@@ -2229,21 +2289,19 @@ bool Scene3385::Actor2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3385::Actor3::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3385::Webbster::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
return true;
}
-bool Scene3385::Actor4::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3385::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -2251,20 +2309,26 @@ bool Scene3385::Actor4::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._sceneManager._previousScene == 3375)
R2_GLOBALS._sound2.play(314);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3386;
- scene->setAction(&scene->_sequenceManager, scene, 3386, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3386, &R2_GLOBALS._player,
+ &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
+ NULL);
return true;
}
-void Scene3385::Exit1::changeScene() {
+void Scene3385::SouthExit::changeScene() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3387;
if (R2_GLOBALS._sceneManager._previousScene == 3375)
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2,
+ &scene->_webbster, NULL);
else
scene->signal();
}
@@ -2292,103 +2356,103 @@ void Scene3385::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3385;
- R2_GLOBALS._player._characterScene[2] = 3385;
- R2_GLOBALS._player._characterScene[3] = 3385;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3385;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3385;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3385;
if (R2_GLOBALS._sceneManager._previousScene == 3375)
- _field11B2 = 3;
+ _playerStrip = 3;
else
- _field11B2 = 4;
+ _playerStrip = 4;
setZoomPercents(102, 40, 200, 160);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
else
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._player.changeZoom(-1);
- if (R2_GLOBALS._player._characterIndex == 2)
- R2_GLOBALS._player.setup(20, _field11B2, 1);
- else if (R2_GLOBALS._player._characterIndex == 3)
- R2_GLOBALS._player.setup(30, _field11B2, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ R2_GLOBALS._player.setup(20, _playerStrip, 1);
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ R2_GLOBALS._player.setup(30, _playerStrip, 1);
else
- R2_GLOBALS._player.setup(10, _field11B2, 1);
+ R2_GLOBALS._player.setup(10, _playerStrip, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor1._moveRate = 10;
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _companion1._moveRate = 10;
+ _companion1._moveDiff = Common::Point(3, 2);
} else {
- _actor1._moveRate = 7;
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion1._moveRate = 7;
+ _companion1._moveDiff = Common::Point(5, 3);
}
- _actor1.changeZoom(-1);
- _actor1._effect = 1;
- if (R2_GLOBALS._player._characterIndex == 2)
- _actor1.setup(10, _field11B2, 1);
+ _companion1.changeZoom(-1);
+ _companion1._effect = EFFECT_SHADED;
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _companion1.setup(10, _playerStrip, 1);
else
- _actor1.setup(20, _field11B2, 1);
- _actor1.animate(ANIM_MODE_1, NULL);
- _actor1.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
-
- _actor2.postInit();
- _actor2._moveDiff = Common::Point(3, 2);
- _actor2.changeZoom(-1);
- _actor2._effect = 1;
- if (R2_GLOBALS._player._characterIndex == 3)
- _actor2.setup(10, _field11B2, 1);
+ _companion1.setup(20, _playerStrip, 1);
+ _companion1.animate(ANIM_MODE_1, NULL);
+ _companion1.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _companion2.postInit();
+ _companion2._moveDiff = Common::Point(3, 2);
+ _companion2.changeZoom(-1);
+ _companion2._effect = EFFECT_SHADED;
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ _companion2.setup(10, _playerStrip, 1);
else
- _actor2.setup(30, _field11B2, 1);
- _actor2.animate(ANIM_MODE_1, NULL);
- _actor2.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3._moveDiff = Common::Point(3, 2);
- _actor3.changeZoom(-1);
- _actor3._effect = 1;
- _actor3.setup(40, _field11B2, 1);
- _actor3.animate(ANIM_MODE_1, NULL);
- _actor3.setDetails(3385, 15, -1, -1, 1, (SceneItem *) NULL);
-
- _exit1.setDetails(Rect(103, 152, 217, 170), SHADECURSOR_DOWN, 3395);
- _exit1.setDest(Common::Point(158, 151));
-
- _actor4.postInit();
- _actor4.setPosition(Common::Point(160, 100));
- _actor4.fixPriority(90);
- _actor4.setDetails(3385, 3, 4, -1, 1, (SceneItem *) NULL);
+ _companion2.setup(30, _playerStrip, 1);
+ _companion2.animate(ANIM_MODE_1, NULL);
+ _companion2.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _webbster.postInit();
+ _webbster._moveDiff = Common::Point(3, 2);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setup(40, _playerStrip, 1);
+ _webbster.animate(ANIM_MODE_1, NULL);
+ _webbster.setDetails(3385, 15, -1, -1, 1, (SceneItem *) NULL);
+
+ _southExit.setDetails(Rect(103, 152, 217, 170), SHADECURSOR_DOWN, 3395);
+ _southExit.setDest(Common::Point(158, 151));
+
+ _door.postInit();
+ _door.setPosition(Common::Point(160, 100));
+ _door.fixPriority(90);
+ _door.setDetails(3385, 3, 4, -1, 1, (SceneItem *) NULL);
if (R2_GLOBALS._sceneManager._previousScene == 3375) {
R2_GLOBALS._player.setPosition(Common::Point(158, 102));
- _actor1.setPosition(Common::Point(164, 100));
- _actor1.fixPriority(98);
- _actor2.setPosition(Common::Point(150, 100));
- _actor2.fixPriority(97);
- _actor3.setPosition(Common::Point(158, 100));
- _actor3.fixPriority(96);
+ _companion1.setPosition(Common::Point(164, 100));
+ _companion1.fixPriority(98);
+ _companion2.setPosition(Common::Point(150, 100));
+ _companion2.fixPriority(97);
+ _webbster.setPosition(Common::Point(158, 100));
+ _webbster.fixPriority(96);
_sceneMode = 3384;
- _actor4.setup(3385, 1, 6);
- _actor4.animate(ANIM_MODE_6, this);
- setAction(&_action1, &_actor4);
+ _door.setup(3385, 1, 6);
+ _door.animate(ANIM_MODE_6, this);
+ setAction(&_action1, &_door);
} else {
R2_GLOBALS._player.setPosition(Common::Point(158, 230));
- _actor1.setPosition(Common::Point(191, 270));
- _actor2.setPosition(Common::Point(124, 255));
- _actor3.setPosition(Common::Point(155, 245));
- _actor4.setup(3385, 1, 1);
+ _companion1.setPosition(Common::Point(191, 270));
+ _companion2.setPosition(Common::Point(124, 255));
+ _webbster.setPosition(Common::Point(155, 245));
+ _door.setup(3385, 1, 1);
_sceneMode = 3385;
- setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_companion1, &_companion2, &_webbster, NULL);
}
- _item1.setDetails(Rect(0, 0, 320, 200), 3385, 0, -1, -1, 1, NULL);
- R2_GLOBALS._v56A9E = 0;
+ _background.setDetails(Rect(0, 0, 320, 200), 3385, 0, -1, -1, 1, NULL);
+ R2_GLOBALS._walkwaySceneNumber = 0;
}
void Scene3385::remove() {
@@ -2412,33 +2476,34 @@ void Scene3385::signal() {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
default:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 3395 -
+ * Scene 3395 - Walkway
*
*--------------------------------------------------------------------------*/
+
Scene3395::Scene3395() {
- _field142E = 0;
+ _playerStrip = 0;
}
void Scene3395::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field142E);
+ s.syncAsSint16LE(_playerStrip);
}
-bool Scene3395::Actor1::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3395::Companion1::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3304, scene);
@@ -2446,14 +2511,14 @@ bool Scene3395::Actor1::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3395::Actor2::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3395::Companion2::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
else
scene->_stripManager.start(3301, scene);
@@ -2461,21 +2526,19 @@ bool Scene3395::Actor2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3395::Actor3::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3395::Webbster::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
return true;
}
-bool Scene3395::Actor4::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3395::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -2483,8 +2546,12 @@ bool Scene3395::Actor4::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._sceneManager._previousScene == 3385)
R2_GLOBALS._sound2.play(314);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3396;
- scene->setAction(&scene->_sequenceManager, scene, 3396, &R2_GLOBALS._player, &scene->_actor1, &scene->_actor2, &scene->_actor3, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3396, &R2_GLOBALS._player,
+ &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
+ NULL);
return true;
}
@@ -2512,106 +2579,106 @@ void Scene3395::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3395;
- R2_GLOBALS._player._characterScene[2] = 3395;
- R2_GLOBALS._player._characterScene[3] = 3395;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3395;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3395;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3395;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
- _field142E = 3;
+ _playerStrip = 3;
else
- _field142E = 4;
+ _playerStrip = 4;
setZoomPercents(51, 40, 200, 137);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
else
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._player.changeZoom(-1);
- if (R2_GLOBALS._player._characterIndex == 2)
- R2_GLOBALS._player.setup(20, _field142E, 1);
- else if (R2_GLOBALS._player._characterIndex == 3)
- R2_GLOBALS._player.setup(30, _field142E, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ R2_GLOBALS._player.setup(20, _playerStrip, 1);
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ R2_GLOBALS._player.setup(30, _playerStrip, 1);
else
- R2_GLOBALS._player.setup(10, _field142E, 1);
+ R2_GLOBALS._player.setup(10, _playerStrip, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor1._moveRate = 10;
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _companion1._moveRate = 10;
+ _companion1._moveDiff = Common::Point(3, 2);
} else {
- _actor1._moveRate = 7;
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion1._moveRate = 7;
+ _companion1._moveDiff = Common::Point(5, 3);
}
- _actor1.changeZoom(-1);
- _actor1._effect = 1;
- if (R2_GLOBALS._player._characterIndex == 2)
- _actor1.setup(10, _field142E, 1);
+ _companion1.changeZoom(-1);
+ _companion1._effect = EFFECT_SHADED;
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _companion1.setup(10, _playerStrip, 1);
else
- _actor1.setup(20, _field142E, 1);
- _actor1.animate(ANIM_MODE_1, NULL);
- _actor1.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
-
- _actor2.postInit();
- _actor2._moveDiff = Common::Point(3, 2);
- _actor2.changeZoom(-1);
- _actor2._effect = 1;
- if (R2_GLOBALS._player._characterIndex == 3)
- _actor2.setup(10, _field142E, 1);
+ _companion1.setup(20, _playerStrip, 1);
+ _companion1.animate(ANIM_MODE_1, NULL);
+ _companion1.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _companion2.postInit();
+ _companion2._moveDiff = Common::Point(3, 2);
+ _companion2.changeZoom(-1);
+ _companion2._effect = EFFECT_SHADED;
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ _companion2.setup(10, _playerStrip, 1);
else
- _actor2.setup(30, _field142E, 1);
- _actor2.animate(ANIM_MODE_1, NULL);
- _actor2.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3._moveDiff = Common::Point(3, 2);
- _actor3.changeZoom(-1);
- _actor3._effect = 1;
- _actor3.setup(40, _field142E, 1);
- _actor3.animate(ANIM_MODE_1, NULL);
- _actor3.setDetails(3385, 18, -1, -1, 1, (SceneItem *) NULL);
-
- _actor4.postInit();
- _actor4.setPosition(Common::Point(159, 50));
- _actor4.fixPriority(40);
- _actor4.setDetails(3395, 6, 7, -1, 1, (SceneItem *) NULL);
+ _companion2.setup(30, _playerStrip, 1);
+ _companion2.animate(ANIM_MODE_1, NULL);
+ _companion2.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
+
+ _webbster.postInit();
+ _webbster._moveDiff = Common::Point(3, 2);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setup(40, _playerStrip, 1);
+ _webbster.animate(ANIM_MODE_1, NULL);
+ _webbster.setDetails(3395, 18, -1, -1, 1, (SceneItem *) NULL);
+
+ _door.postInit();
+ _door.setPosition(Common::Point(159, 50));
+ _door.fixPriority(40);
+ _door.setDetails(3395, 6, 7, -1, 1, (SceneItem *) NULL);
if (R2_GLOBALS._sceneManager._previousScene == 3385) {
R2_GLOBALS._player.setPosition(Common::Point(158, 53));
- _actor1.setPosition(Common::Point(164, 51));
- _actor1.fixPriority(48);
- _actor2.setPosition(Common::Point(150, 51));
- _actor2.fixPriority(47);
- _actor3.setPosition(Common::Point(158, 51));
- _actor3.fixPriority(46);
+ _companion1.setPosition(Common::Point(164, 51));
+ _companion1.fixPriority(48);
+ _companion2.setPosition(Common::Point(150, 51));
+ _companion2.fixPriority(47);
+ _webbster.setPosition(Common::Point(158, 51));
+ _webbster.fixPriority(46);
_sceneMode = 3394;
- _actor4.setup(3395, 1, 7);
- _actor4.animate(ANIM_MODE_6, this);
- setAction(&_action1, &_actor4);
+ _door.setup(3395, 1, 7);
+ _door.animate(ANIM_MODE_6, this);
+ setAction(&_action1, &_door);
} else {
R2_GLOBALS._player.setPosition(Common::Point(158, 200));
- _actor1.setPosition(Common::Point(191, 255));
- _actor2.setPosition(Common::Point(124, 240));
- _actor3.setPosition(Common::Point(155, 242));
- _actor4.setup(3395, 1, 1);
+ _companion1.setPosition(Common::Point(191, 255));
+ _companion2.setPosition(Common::Point(124, 240));
+ _webbster.setPosition(Common::Point(155, 242));
+ _door.setup(3395, 1, 1);
- R2_GLOBALS._walkRegions.enableRegion(1);
+ R2_GLOBALS._walkRegions.disableRegion(1);
_sceneMode = 3395;
- setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, &_companion1, &_companion2, &_webbster, NULL);
}
for (int i = 0; i <= 12; i++) {
- _itemArray[i].setDetails(i, 3995, 0, -1, -1);
+ _itemArray[i].setDetails(i, 3395, 0, -1, -1);
}
- _item1.setDetails(Rect(0, 0, 320, 200), 3395, 3, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3395, 3, -1, -1, 1, NULL);
}
void Scene3395::remove() {
@@ -2632,31 +2699,32 @@ void Scene3395::signal() {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
default:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 3400 -
+ * Scene 3400 - Confrontation
*
*--------------------------------------------------------------------------*/
+
Scene3400::Scene3400() {
- _field157C = 0;
+ _soundFaded = false;
}
void Scene3400::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field157C);
+ s.syncAsSint16LE(_soundFaded);
}
void Scene3400::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ _sceneBounds = Rect(160, 0, 480, 200);
+
loadScene(3400);
- _field157C = 0;
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ _soundFaded = false;
SceneExt::postInit();
R2_GLOBALS._sound1.play(317);
@@ -2669,26 +2737,26 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_tealSpeaker);
setZoomPercents(51, 46, 180, 200);
- R2_GLOBALS._player._characterScene[1] = 3400;
- R2_GLOBALS._player._characterScene[2] = 3400;
- R2_GLOBALS._player._characterScene[3] = 3400;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3400;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3400;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3400;
- _actor7.postInit();
- _actor7.setup(3403, 1, 1);
- _actor7.setPosition(Common::Point(190, 103));
- _actor7.fixPriority(89);
+ _manholeCover.postInit();
+ _manholeCover.setup(3403, 1, 1);
+ _manholeCover.setPosition(Common::Point(190, 103));
+ _manholeCover.fixPriority(89);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
else
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player.setPosition(Common::Point(239, 64));
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player.setup(20, 5, 1);
- else if (R2_GLOBALS._player._characterIndex == 3)
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._player.setup(30, 5, 1);
else
R2_GLOBALS._player.setup(10, 5, 1);
@@ -2696,52 +2764,52 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor1._numFrames = 10;
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion1.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _companion1._numFrames = 10;
+ _companion1._moveDiff = Common::Point(3, 2);
} else {
- _actor1._numFrames = 7;
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion1._numFrames = 7;
+ _companion1._moveDiff = Common::Point(5, 3);
}
- _actor1.changeZoom(-1);
- _actor1._effect = 1;
- _actor1.setPosition(Common::Point(247, 63));
- if (R2_GLOBALS._player._characterIndex == 2)
- _actor1.setup(10, 5, 1);
+ _companion1.changeZoom(-1);
+ _companion1._effect = EFFECT_SHADED;
+ _companion1.setPosition(Common::Point(247, 63));
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _companion1.setup(10, 5, 1);
else
- _actor1.setup(20, 5, 1);
- _actor1.animate(ANIM_MODE_1, NULL);
-
- _actor2.postInit();
- _actor2._moveDiff = Common::Point(3, 2);
- _actor2.changeZoom(-1);
- _actor2._effect = 1;
- _actor2.setPosition(Common::Point(225, 63));
- if (R2_GLOBALS._player._characterIndex == 3)
- _actor2.setup(10, 5, 1);
+ _companion1.setup(20, 5, 1);
+ _companion1.animate(ANIM_MODE_1, NULL);
+
+ _companion2.postInit();
+ _companion2._moveDiff = Common::Point(3, 2);
+ _companion2.changeZoom(-1);
+ _companion2._effect = EFFECT_SHADED;
+ _companion2.setPosition(Common::Point(225, 63));
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ _companion2.setup(10, 5, 1);
else
- _actor2.setup(30, 5, 1);
- _actor2.animate(ANIM_MODE_1, NULL);
-
- _actor3.postInit();
- _actor3._numFrames = 7;
- _actor3._moveDiff = Common::Point(5, 3);
- _actor3.changeZoom(-1);
- _actor3._effect = 1;
- _actor3.setPosition(Common::Point(235, 61));
- _actor3.setup(40, 3, 1);
- _actor3.animate(ANIM_MODE_1, NULL);
-
- _actor6.postInit();
- _actor6.setup(3400, 1, 6);
- _actor6.setPosition(Common::Point(236, 51));
- _actor6.fixPriority(51);
- _actor6.animate(ANIM_MODE_6, NULL);
+ _companion2.setup(30, 5, 1);
+ _companion2.animate(ANIM_MODE_1, NULL);
+
+ _webbster.postInit();
+ _webbster._numFrames = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setPosition(Common::Point(235, 61));
+ _webbster.setup(40, 3, 1);
+ _webbster.animate(ANIM_MODE_1, NULL);
+
+ _door.postInit();
+ _door.setup(3400, 1, 6);
+ _door.setPosition(Common::Point(236, 51));
+ _door.fixPriority(51);
+ _door.animate(ANIM_MODE_6, NULL);
R2_GLOBALS.clearFlag(71);
_sceneMode = 3400;
- setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_companion1, &_companion2, &_webbster, NULL);
}
void Scene3400::remove() {
@@ -2753,223 +2821,236 @@ void Scene3400::remove() {
void Scene3400::signal() {
switch (_sceneMode) {
case 3305: {
- warning("STUB: sub_1D227()");
+ // First part of discussion
_tealSpeaker._object1.hide();
- _actor4.show();
- _actor4.setStrip(1);
+ _teal.show();
+ _teal.setStrip(1);
Common::Point pt(158, 190);
NpcMover *mover = new NpcMover();
- _actor4.addMover(mover, &pt, this);
+ _teal.addMover(mover, &pt, this);
_sceneMode = 3402;
- setAction(&_sequenceManager, this, 3402, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3402, &R2_GLOBALS._player, &_companion1, &_companion2, &_webbster, NULL);
}
break;
case 3306:
+ // Teal picks up the sapphire
R2_GLOBALS._sound2.play(318);
- _actor1.setStrip(2);
+ _companion1.setStrip(2);
R2_GLOBALS._player.setStrip(6);
- _actor2.setStrip(6);
- _actor3.setStrip(3);
- _actor4.setStrip(1);
- R2_INVENTORY.setObjectScene(34, 0);
+ _companion2.setStrip(6);
+ _webbster.setStrip(3);
+ _teal.setStrip(1);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 0);
_stripManager.start(3307, this);
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_sceneMode = 3400;
- R2_GLOBALS._player.setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_actor4, &_actor8, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_teal, &_sapphire, NULL);
} else {
_sceneMode = 3408;
- _actor1.setAction(&_sequenceManager, this, 3408, &_actor1, &_actor4, &_actor8, NULL);
+ _companion1.setAction(&_sequenceManager, this, 3408, &_companion1, &_teal, &_sapphire, NULL);
}
break;
case 3307:
case 3404:
case 3408:
- if (_field157C == 0) {
+ // A tasp!
+ if (!_soundFaded) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- _field157C = 1;
+ _soundFaded = true;
} else {
_sceneMode = 3308;
_stripManager.start(3308, this);
}
break;
case 3308:
- warning("STUB: sub_1D227()");
- _actor1.setStrip(2);
+ // Characters teleport one after the other
+ _companion1.setStrip(2);
R2_GLOBALS._player.setStrip(6);
- _actor2.setStrip(6);
- _actor3.setStrip(3);
- _actor4.setStrip(1);
+ _companion2.setStrip(6);
+ _webbster.setStrip(3);
+ _teal.setStrip(1);
_sceneMode = 3403;
- if (R2_GLOBALS._player._characterIndex == 2)
- setAction(&_sequenceManager, this, 3403, &R2_GLOBALS._player, &_actor3, &_actor7, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ setAction(&_sequenceManager, this, 3403, &R2_GLOBALS._player, &_webbster, &_manholeCover, NULL);
else
- setAction(&_sequenceManager, this, 3403, &_actor1, &_actor3, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3403, &_companion1, &_webbster, &_manholeCover, NULL);
break;
case 3309:
- warning("STUB: sub_1D227()");
- _actor4.setStrip(1);
+ // Miranda teleports away
+ _teal.setStrip(1);
_sceneMode = 3405;
- if (R2_GLOBALS._player._characterIndex == 3)
- setAction(&_sequenceManager, this, 3405, &R2_GLOBALS._player, &_actor7, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ setAction(&_sequenceManager, this, 3405, &R2_GLOBALS._player, &_manholeCover, NULL);
else
- setAction(&_sequenceManager, this, 3405, &_actor2, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3405, &_companion2, &_manholeCover, NULL);
break;
case 3310:
- warning("STUB: sub_1D227()");
- _actor4.setStrip(1);
+ // Quinn teleports away
+ _teal.setStrip(1);
_sceneMode = 3406;
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager, this, 3406, &R2_GLOBALS._player, &_actor7, NULL);
- else if (R2_GLOBALS._player._characterIndex == 2)
- setAction(&_sequenceManager, this, 3406, &_actor1, &_actor7, NULL);
- else if (R2_GLOBALS._player._characterIndex == 3)
- setAction(&_sequenceManager, this, 3406, &_actor2, &_actor7, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager, this, 3406, &R2_GLOBALS._player, &_manholeCover, NULL);
+ else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ setAction(&_sequenceManager, this, 3406, &_companion1, &_manholeCover, NULL);
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
+ setAction(&_sequenceManager, this, 3406, &_companion2, &_manholeCover, NULL);
break;
case 3311:
- warning("STUB: sub_1D227()");
+ // Teal teleports away
_tealSpeaker._object1.hide();
- _actor4.show();
- _actor4.setStrip(1);
+ _teal.show();
+ _teal.setStrip(1);
_sceneMode = 3407;
- setAction(&_sequenceManager, this, 3407, &_actor4, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3407, &_teal, &_manholeCover, NULL);
break;
case 3400: {
- _actor8.postInit();
- _actor8.hide();
- _actor4.postInit();
- _actor4._numFrames = 7;
- _actor4._moveDiff = Common::Point(3, 2);
- _actor4.changeZoom(-1);
- _actor4._effect = 1;
- _actor4.setPosition(Common::Point(-15, 90));
- _actor4.setup(3402, 1, 1);
- _actor4.animate(ANIM_MODE_1, NULL);
+ // Teal enters the room
+ _sapphire.postInit();
+ _sapphire.hide();
+ _teal.postInit();
+ _teal._numFrames = 7;
+ _teal._moveDiff = Common::Point(3, 2);
+ _teal.changeZoom(-1);
+ _teal._effect = EFFECT_SHADED;
+ _teal.setPosition(Common::Point(-15, 90));
+ _teal.setup(3402, 1, 1);
+ _teal.animate(ANIM_MODE_1, NULL);
Common::Point pt1(115, 90);
NpcMover *mover1 = new NpcMover();
- _actor4.addMover(mover1, &pt1, this);
- R2_GLOBALS._scrollFollower = &_actor4;
+ _teal.addMover(mover1, &pt1, this);
+ R2_GLOBALS._scrollFollower = &_teal;
Common::Point pt2(203, 76);
NpcMover *mover2 = new NpcMover();
- _actor3.addMover(mover2, &pt2, NULL);
+ _webbster.addMover(mover2, &pt2, NULL);
_sceneMode = 3401;
}
break;
case 3401:
+ // Teal first speech
_sceneMode = 3305;
_stripManager.start(3305, this);
break;
case 3402:
+ // Betrayal of Webbster
_sceneMode = 3306;
_stripManager.start(3306, this);
break;
case 3403:
+ // Teal: "Miranda..."
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
_sceneMode = 3309;
_stripManager.start(3309, this);
break;
case 3405:
+ // Teal: "And Quinn..."
_sceneMode = 3310;
_stripManager.start(3310, this);
break;
case 3406:
+ // Teal final sentence before teleporting
_sceneMode = 3311;
_stripManager.start(3311, this);
break;
case 3407:
+ // End of scene
R2_GLOBALS._sceneManager.changeScene(3600);
break;
default:
+ // Unexpected scene mode
R2_GLOBALS._player.enableControl();
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 3500 -
+ * Scene 3500 - Flub tube maze
*
*--------------------------------------------------------------------------*/
+
Scene3500::Action1::Action1() {
- _field1E = 0;
- _field20 = 0;
+ _direction = 0;
+ _field20 = false;
_field22 = 0;
- _field24 = 0;
+ _field24 = false;
}
void Scene3500::Action1::synchronize(Serializer &s) {
Action::synchronize(s);
- s.syncAsSint16LE(_field1E);
+ s.syncAsSint16LE(_direction);
s.syncAsSint16LE(_field20);
s.syncAsSint16LE(_field22);
s.syncAsSint16LE(_field24);
}
-void Scene3500::Action1::sub108670(int arg1) {
+void Scene3500::Action1::handleHorzButton(int direction) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- _field1E = arg1;
- _field20 = 1;
- _field24 = 1;
+ // Direction: -1 == Left, 1 == Right
+ _direction = direction;
+ _field20 = true;
+ _field24 = true;
- scene->_actor9.setStrip(2);
- scene->_actor9.show();
+ scene->_tunnelHorzCircle.setStrip(2);
+ scene->_tunnelHorzCircle.show();
- if (_field1E == 1)
- scene->_actor6.show();
+ if (_direction == 1)
+ scene->_symbolRight.show();
else
- scene->_actor5.show();
+ scene->_symbolLeft.show();
- if (scene->_actor1._frame % 2 == 0)
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ if (scene->_shuttle._frame % 2 == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
+ }
setActionIndex(0);
}
-void Scene3500::Action1::sub108732(int arg1) {
+void Scene3500::Action1::turnShuttle(bool arg1) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
_field20 = arg1;
- _field1E = -_field1E;
+ _direction = -_direction;
- if (_field1E == 1) {
- scene->_actor6.show();
- scene->_actor5.hide();
+ if (_direction == 1) {
+ scene->_symbolRight.show();
+ scene->_symbolLeft.hide();
} else {
- scene->_actor5.show();
- scene->_actor6.hide();
+ scene->_symbolLeft.show();
+ scene->_symbolRight.hide();
}
switch (_actionIndex) {
case 4:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
// No break on purpose
case 3:
_actionIndex = 10;
setDelay(0);
break;
case 5: {
- scene->_fieldAF8 = 160;
+ scene->_moverVertX = 160;
Common::Point pt(160, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_fieldB9E = 160 - (_field1E * 2 * 160);
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_moverHorzX = 160 - (_direction * 2 * 160);
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
_actionIndex = 11;
}
break;
case 6:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
setDelay(1);
// No break on purpose
case 8:
- scene->_actor9.setStrip(2);
+ scene->_tunnelHorzCircle.setStrip(2);
_actionIndex = 1;
break;
default:
@@ -2977,372 +3058,161 @@ void Scene3500::Action1::sub108732(int arg1) {
}
}
-Scene3500::Action2::Action2() {
- _field1E = 0;
-}
-
-void Scene3500::Action2::synchronize(Serializer &s) {
- Action::synchronize(s);
-
- s.syncAsSint16LE(_field1E);
-}
-
-Scene3500::Item4::Item4() {
- _field34 = 0;
-}
-
-void Scene3500::Item4::synchronize(Serializer &s) {
- NamedHotspot::synchronize(s);
-
- s.syncAsSint16LE(_field34);
-}
-
-Scene3500::Actor7::Actor7() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
- _fieldAA = 0;
- _fieldAC = 0;
- _fieldAE = 0;
-}
-
-void Scene3500::Actor7::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
-
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
- s.syncAsSint16LE(_fieldAC);
- s.syncAsSint16LE(_fieldAE);
-}
-
-void Scene3500::Actor7::sub109466(int arg1, int arg2, int arg3, int arg4, int arg5) {
- _fieldAE = 0;
- _fieldA4 = arg1;
- _fieldA6 = arg2;
- _fieldA8 = arg3;
- _fieldAA = arg4;
- _fieldAC = _fieldAA / _fieldA8;
-
- postInit();
- setup(10501, 3, 1);
- fixPriority(255);
- sub109663(arg5);
-}
-
-void Scene3500::Actor7::sub1094ED() {
- Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
-
- scene->_field1270 = _position.x - _fieldA4;
-}
-
-void Scene3500::Actor7::sub109663(int arg1){
- sub109693(Common::Point(_fieldA4 + arg1, _fieldA6 - (_fieldAC * arg1)));
-}
-
-void Scene3500::Actor7::sub109693(Common::Point Pt) {
- setPosition(Pt);
-}
-
-int Scene3500::UnkObject3500::sub1097C9(int arg1) {
- return (_field2A / 2) + arg1 - (arg1 % _field2A);
-}
-
-int Scene3500::UnkObject3500::sub1097EF(int arg1) {
- return (_field2C / 2) + arg1 - (arg1 % _field2C);
-}
-
-int Scene3500::UnkObject3500::sub109C09(Common::Point pt) {
- int vx = pt.x / _field2A;
- int vy = pt.y / _field2C;
-
- if ((vx >= 0) && (_field26 > vx) && (_field28 > vy)) {
- return _field16[((_field26 * vy) + vx) * 2];
- } else
- return -1;
-}
-
-int Scene3500::UnkObject3500::sub109C5E(int &x, int &y) {
- int retVal = sub51AFD(Common::Point(x, y));
- x = _field2E;
- y = _field30;
-
- return retVal;
-}
-
-Scene3500::Scene3500() {
- _fieldAF8 = 0;
- _fieldB9E = 0;
- _rotation = NULL;
- _field126E = 0;
- _field1270 = 0;
- _field1272 = 0;
- _field1274 = 0;
- _field1276 = 0;
- _field1278 = 0;
- _field127A = 0;
- _field127C = 0;
- _field127E = 0;
- _field1280 = 0;
- _field1282 = 0;
- _field1284 = 0;
- _field1286 = 0;
-}
-
-void Scene3500::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- SYNC_POINTER(_rotation);
-
- s.syncAsSint16LE(_fieldAF8);
- s.syncAsSint16LE(_fieldB9E);
- s.syncAsSint16LE(_field126E);
- s.syncAsSint16LE(_field1270);
- s.syncAsSint16LE(_field1272);
- s.syncAsSint16LE(_field1274);
- s.syncAsSint16LE(_field1276);
- s.syncAsSint16LE(_field1278);
- s.syncAsSint16LE(_field127A);
- s.syncAsSint16LE(_field127C);
- s.syncAsSint16LE(_field127E);
- s.syncAsSint16LE(_field1280);
- s.syncAsSint16LE(_field1282);
- s.syncAsSint16LE(_field1284);
- s.syncAsSint16LE(_field1286);
-}
-
-void Scene3500::sub107F71(int arg1) {
- switch (arg1) {
- case -1:
- _actor7.sub1094ED();
- if (_field1270 != 0) {
- _field1270--;
- _actor7.sub109663(_field1270);
- }
- if (_action1._field24 != 0)
- _field1270 = 0;
- break;
- case 1:
- _actor7.sub1094ED();
- if (_field1270 < 16) {
- ++_field1270;
- _actor7.sub109663(_field1270);
- }
- if (_action1._field24 != 0)
- _field1270 = 0;
- break;
- case 88:
- if ((_action == 0) || (_action1._field24 == 0)) {
- // The original makes a second useless check on action, skipped
- _action2.sub10831F(2);
- if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != 2))) {
- _action2.signal();
- } else {
- _actor9.setAction(&_action2, &_actor9, NULL);
- }
- }
- break;
- case 96:
- if ((_action) && (_action1._field24 != 0) && (_action2._field1E != 1)) {
- _field1278 = 0;
- _action1.sub108732(0);
- } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
- _field1278 = arg1;
- } else if ((_action) && (_action1._field24 == 0)) {
- _action1.sub108670(1);
- _action1.signal();
- } else if (_action == 0) {
- _action1.sub108670(1);
- setAction(&_action1, &_actor1, NULL);
- }
- break;
- case 104:
- if ((_action == 0) || (_action1._field24 == 0)) {
- _action2.sub10831F(-1);
- if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != -1))) {
- _action2.signal();
- } else {
- _actor9.setAction(&_action2, &_actor9, NULL);
- }
- }
- break;
- case 112:
- if ((_action) && (_action1._field24 != 0) && (_action2._field1E != -1)) {
- _field1278 = 0;
- _action1.sub108732(0);
- } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
- _field1278 = arg1;
- } else if ((_action) && (_action1._field24 == 0)) {
- _action1.sub108670(-1);
- _action1.signal();
- } else if (_action == 0) {
- _action1.sub108670(-1);
- setAction(&_action1, &_actor1, NULL);
- }
- break;
- default:
- _field1270 = arg1;
- _actor7.sub109663(arg1);
- if (_action1._field24 != 0) {
- _field1270 = 0;
- }
- break;
- }
-}
-
void Scene3500::Action1::signal() {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
switch(_actionIndex++) {
case 0:
R2_GLOBALS._player.disableControl();
- scene->_field1286 = 0;
- if (scene->_field1270 != 0) {
- scene->_field1270 = 0;
- scene->_field126E = 0;
- scene->_field1272 = 0;
+ scene->_directionChangesEnabled = false;
+ if (scene->_speed != 0) {
+ scene->_speed = 0;
+ scene->_mazeChangeAmount = 0;
+ scene->_field1272 = false;
scene->_rotation->_idxChange = 0;
}
break;
case 1:
- if ((scene->_actor1._frame % 2) == 0) {
+ if ((scene->_shuttle._frame % 2) == 1) {
setDelay(1);
return;
}
// No break on purpose
case 3:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
setDelay(1);
break;
case 4: {
- int si = scene->_unkObj1.sub109C09(Common::Point(scene->_field127A + 70, scene->_field127C + 46));
- int var2 = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70;
- int var4 = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46;
- int di = abs(var2 - scene->_field127A);
- int var6 = abs(var4 - scene->_field127C);
-
- if ((scene->_actor1._frame % 2) != 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ int cellId = scene->_mazeUI.getCellFromMapXY(Common::Point(scene->_mazePosition.x + 70, scene->_mazePosition.y + 46));
+ int var2 = scene->_mazeUI.cellFromX(scene->_mazePosition.x + 70) - 70;
+ int var4 = scene->_mazeUI.cellFromY(scene->_mazePosition.y + 46) - 46;
+ int di = abs(var2 - scene->_mazePosition.x);
+ int var6 = abs(var4 - scene->_mazePosition.y);
+
+ if ((scene->_shuttle._frame % 2) != 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
}
- int var8 = (scene->_action1._field1E * 2 + scene->_field1276);
- if (var8 > 7)
- var8 = 1;
- else if (var8 < 1)
- var8 = 7;
-
- switch (var8) {
- case 0:
- if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 23) && (si != 24) && (si != 4) && (si != 11))
+ // Get the new direction starting on
+ int direction = (scene->_action1._direction * 2 + scene->_mazeDirection);
+ if (direction > MAZEDIR_NORTHWEST)
+ direction = MAZEDIR_NORTH;
+ else if (direction < MAZEDIR_NORTH)
+ direction = MAZEDIR_WEST;
+
+ // Check whether movement is allowed in that direction. If so, then
+ // movement is started again
+ switch (direction) {
+ case MAZEDIR_NORTH:
+ if ( ((cellId != 2) && (cellId != 3) && (cellId != 6) && (cellId != 1) && (cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 11))
|| (var6 != 0)) {
- if ((si != 25) && (si != 26) && (si != 5) && (si != 14) && (si != 15))
- _field20 = 0;
+ if ((cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 14) && (cellId != 15))
+ _field20 = false;
else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
- _field20 = 0;
+ _field20 = false;
else
- _field20 = 1;
+ _field20 = true;
} else
- _field20 = 1;
+ _field20 = true;
break;
- case 2:
- if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 26) && (si != 24) && (si != 15) && (si != 6) && (si != 31))
+ case MAZEDIR_EAST:
+ if ( ((cellId != 12) && (cellId != 13) && (cellId != 11) && (cellId != 16) && (cellId != 26) && (cellId != 24) && (cellId != 15) && (cellId != 6) && (cellId != 31))
|| (di != 0)) {
- if ((si != 25) && (si != 23) && (si != 14) && (si != 5) && (si != 4))
- _field20 = 0;
+ if ((cellId != 25) && (cellId != 23) && (cellId != 14) && (cellId != 5) && (cellId != 4))
+ _field20 = false;
else if ((di != 0) || (var6 <= 3)) // useless, skipped: "|| (var6 == 0)"
- _field20 = 0;
+ _field20 = false;
else
- _field20 = 1;
+ _field20 = true;
} else
- _field20 = 1;
+ _field20 = true;
break;
- case 4:
- if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 25) && (si != 26) && (si != 5) && (si != 16) && (si != 31))
+ case MAZEDIR_SOUTH:
+ if ( ((cellId != 2) && (cellId != 3) && (cellId != 6) && (cellId != 1) && (cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 16) && (cellId != 31))
|| (var6 != 0)) {
- if ((si != 23) && (si != 24) && (si != 4) && (si != 14) && (si != 15))
- _field20 = 0;
+ if ((cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15))
+ _field20 = false;
else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
- _field20 = 0;
+ _field20 = false;
else
- _field20 = 1;
+ _field20 = true;
} else
- _field20 = 1;
+ _field20 = true;
break;
- case 6:
- if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 25) && (si != 23) && (si != 14) && (si != 1) && (si != 31))
+ case MAZEDIR_WEST:
+ if ( ((cellId != 12) && (cellId != 13) && (cellId != 11) && (cellId != 16) && (cellId != 25) && (cellId != 23) && (cellId != 14) && (cellId != 1) && (cellId != 31))
|| (var6 != 0)) {
- if ((si != 26) && (si != 24) && (si != 15) && (si != 5) && (si != 4))
- _field20 = 0;
+ if ((cellId != 26) && (cellId != 24) && (cellId != 15) && (cellId != 5) && (cellId != 4))
+ _field20 = false;
else if ((var6 <= 0) || (di != 0)) // useless, skipped: "|| (var6 == 0)"
- _field20 = 0;
+ _field20 = false;
else
- _field20 = 1;
+ _field20 = true;
} else
- _field20 = 1;
+ _field20 = true;
default:
break;
}
}
// No break on purpose
case 2: {
- scene->_actor8.setPosition(Common::Point(160, 73));
- scene->_actor8._moveDiff.x = 160 - scene->_field126E;
- scene->_fieldAF8 = 160 - ((_field1E * 2) * 160);
- Common::Point pt(scene->_fieldAF8, 73);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ scene->_tunnelVertCircle._moveDiff.x = 160 - scene->_mazeChangeAmount;
+ scene->_moverVertX = 160 - ((_direction * 2) * 160);
+ Common::Point pt(scene->_moverVertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, this);
+ scene->_tunnelVertCircle.addMover(mover, &pt, this);
- scene->_actor9.setPosition(Common::Point(160 + ((_field1E * 2) * 160), 73));
- scene->_actor9._moveDiff.x = 160 - scene->_field126E;
- scene->_fieldB9E = 160;
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_tunnelHorzCircle.setPosition(Common::Point(160 + ((_direction * 2) * 160), 73));
+ scene->_tunnelHorzCircle._moveDiff.x = 160 - scene->_mazeChangeAmount;
+ scene->_moverHorzX = 160;
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
}
break;
case 5:
- scene->_actor1._frameChange = _field1E;
- scene->_field1276 = scene->_actor1.changeFrame();
- scene->_actor1.setFrame(scene->_field1276);
+ scene->_shuttle._frameChange = _direction;
+ scene->_mazeDirection = scene->_shuttle.changeFrame();
+ scene->_shuttle.setFrame(scene->_mazeDirection);
setDelay(1);
break;
case 6:
- scene->_actor8.setPosition(Common::Point(160, 73));
- if (_field20 == 0)
- scene->_actor8.setStrip(1);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ if (!_field20)
+ scene->_tunnelVertCircle.setStrip(1);
else
- scene->_actor8.setStrip(2);
- scene->_actor8.fixPriority(1);
+ scene->_tunnelVertCircle.setStrip(2);
+ scene->_tunnelVertCircle.fixPriority(1);
- scene->_actor9.setPosition(Common::Point(-160, 73));
- scene->_actor9.setStrip(9);
- scene->_actor9.fixPriority(11);
- scene->_actor9.hide();
+ scene->_tunnelHorzCircle.setPosition(Common::Point(-160, 73));
+ scene->_tunnelHorzCircle.setStrip(9);
+ scene->_tunnelHorzCircle.fixPriority(11);
+ scene->_tunnelHorzCircle.hide();
setDelay(1);
break;
case 7:
- if ((scene->_actor1._frame % 2) == 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_field1276 = scene->_actor1.changeFrame();
- scene->_actor1.setFrame(scene->_field1276);
+ if ((scene->_shuttle._frame % 2) == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_mazeDirection = scene->_shuttle.changeFrame();
+ scene->_shuttle.setFrame(scene->_mazeDirection);
}
setDelay(1);
break;
case 8: {
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- scene->_field1286 = 1;
- if ((scene->_actor1._frame % 2) == 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_directionChangesEnabled = true;
+ if ((scene->_shuttle._frame % 2) == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
}
- // All the var_8 initialization was missing in the original
+ // CHECKME: All the var_8 initialization was missing in the original
// but it's clearly a cut and paste error from case 4.
// The following code allows the switch to work properly.
- warning("Checkme: fix for dead code");
- int var_8 = (_field1E * 2 + scene->_field1276);
+ int var_8 = (_direction * 2 + scene->_mazeDirection);
if (var_8 > 7)
var_8 = 1;
else if (var_8 < 1)
@@ -3353,57 +3223,57 @@ void Scene3500::Action1::signal() {
case 0:
// No break on purpose
case 4:
- scene->_field127A = scene->_unkObj1.sub1097C9(scene->_field127A + 70) - 70;
+ scene->_mazePosition.x = scene->_mazeUI.cellFromX(scene->_mazePosition.x + 70) - 70;
break;
case 2:
// No break on purpose
case 6:
- scene->_field127C = scene->_unkObj1.sub1097EF(scene->_field127C + 46) - 46;
+ scene->_mazePosition.y = scene->_mazeUI.cellFromY(scene->_mazePosition.y + 46) - 46;
break;
default:
break;
}
- scene->_actor5.hide();
- scene->_actor6.hide();
- _field24 = 0;
- if (_field20 == 0) {
- scene->_actor7.sub1094ED();
- if (scene->_field126E == scene->_field1270)
+ scene->_symbolLeft.hide();
+ scene->_symbolRight.hide();
+ _field24 = false;
+ if (!_field20) {
+ scene->_throttle.updateSpeed();
+ if (scene->_mazeChangeAmount == scene->_speed)
scene->_aSound1.play(276);
}
break;
}
case 10: {
- scene->_fieldAF8 = 160;
+ scene->_moverVertX = 160;
Common::Point pt(160, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_fieldB9E = 160 - (_field1E * 2 * 160);
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_moverHorzX = 160 - (_direction * 2 * 160);
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
_actionIndex = 6;
}
break;
case 11: {
- scene->_actor8.setStrip(2);
- scene->_actor8.setPosition(Common::Point(160, 73));
- scene->_fieldAF8 = 160 - (_field1E * 2 * 160);
- Common::Point pt(scene->_fieldAF8, 73);
+ scene->_tunnelVertCircle.setStrip(2);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ scene->_moverVertX = 160 - (_direction * 2 * 160);
+ Common::Point pt(scene->_moverVertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
- scene->_actor8.fixPriority(11);
- if (_field20 == 0)
- scene->_actor9.setStrip(1);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.fixPriority(11);
+ if (!_field20)
+ scene->_tunnelHorzCircle.setStrip(1);
else
- scene->_actor9.setStrip(2);
- scene->_actor9.setPosition(Common::Point(160 - (_field1E * 2 * 160), 73));
- scene->_fieldB9E = 160;
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_tunnelHorzCircle.setStrip(2);
+ scene->_tunnelHorzCircle.setPosition(Common::Point(160 - (_direction * 2 * 160), 73));
+ scene->_moverHorzX = 160;
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
- scene->_actor9.fixPriority(1);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.fixPriority(1);
_actionIndex = 5;
}
break;
@@ -3416,20 +3286,33 @@ void Scene3500::Action1::dispatch() {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
Action::dispatch();
- if ((_actionIndex == 1) && (scene->_field126E <= 4)) {
+ if ((_actionIndex == 1) && (scene->_mazeChangeAmount <= 4)) {
scene->_rotation->_idxChange = 0;
signal();
}
}
-void Scene3500::Action2::sub10831F(int arg1) {
+/*--------------------------------------------------------------------------*/
+
+Scene3500::Action2::Action2() {
+ _direction = 0;
+}
+
+void Scene3500::Action2::synchronize(Serializer &s) {
+ Action::synchronize(s);
+
+ s.syncAsSint16LE(_direction);
+}
+
+void Scene3500::Action2::handleVertButton(int direction) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- _field1E = arg1;
- if (_field1E == -1)
- scene->_actor3.setFrame2(3);
+ // Directions : 2 == up, -1 == down
+ _direction = direction;
+ if (_direction == -1)
+ scene->_horizontalSpeedDisplay.setFrame2(3);
else
- scene->_actor3.setFrame2(1);
+ scene->_horizontalSpeedDisplay.setFrame2(1);
setActionIndex(0);
}
@@ -3437,57 +3320,57 @@ void Scene3500::Action2::sub10831F(int arg1) {
void Scene3500::Action2::signal() {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- int si;
- int di;
+ int vertX;
+ int horzX;
switch (_actionIndex++) {
case 0: {
- if (scene->_actor8._mover) {
- si = scene->_fieldAF8;
- di = scene->_fieldB9E;
+ if (scene->_tunnelVertCircle._mover) {
+ vertX = scene->_moverVertX;
+ horzX = scene->_moverHorzX;
} else {
- scene->_fieldAF8 = scene->_actor8._position.x;
- si = scene->_fieldAF8;
- scene->_fieldB9E = scene->_actor9._position.y;
- di = scene->_fieldB9E;
+ scene->_moverVertX = scene->_tunnelVertCircle._position.x;
+ vertX = scene->_moverVertX;
+ scene->_moverHorzX = scene->_tunnelHorzCircle._position.y;
+ horzX = scene->_moverHorzX;
}
- scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2);
- Common::Point pt(si, 73 - (_field1E * 12));
+ scene->_tunnelVertCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt(vertX, 73 - (_direction * 12));
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2);
- Common::Point pt2(di, 73 - (_field1E * 12));
+ scene->_tunnelHorzCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt2(horzX, 73 - (_direction * 12));
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
- scene->_field126E = (scene->_field126E / 2) + (scene->_field126E % 2);
- setDelay(17 - scene->_field126E);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
+ scene->_mazeChangeAmount = (scene->_mazeChangeAmount / 2) + (scene->_mazeChangeAmount % 2);
+ setDelay(17 - scene->_mazeChangeAmount);
}
break;
case 1: {
R2_GLOBALS._sound2.play(339);
- if (scene->_actor8._mover) {
- si = scene->_fieldAF8;
- di = scene->_fieldB9E;
+ if (scene->_tunnelVertCircle._mover) {
+ vertX = scene->_moverVertX;
+ horzX = scene->_moverHorzX;
} else {
- si = scene->_actor8._position.x;
- di = scene->_actor9._position.x;
+ vertX = scene->_tunnelVertCircle._position.x;
+ horzX = scene->_tunnelHorzCircle._position.x;
}
- scene->_actor7.sub1094ED();
+ scene->_throttle.updateSpeed();
- scene->_actor8._moveDiff.y = 9 - (scene->_field126E / 2);
- Common::Point pt(si, 73);
+ scene->_tunnelVertCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt(vertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_actor9._moveDiff.y = 9 - (scene->_field126E / 2);
- Common::Point pt2(di, 73);
+ scene->_tunnelHorzCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt2(horzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
- scene->_actor3.setFrame2(2);
+ scene->_horizontalSpeedDisplay.setFrame2(2);
}
break;
default:
@@ -3495,88 +3378,208 @@ void Scene3500::Action2::signal() {
}
}
-bool Scene3500::Item4::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+Scene3500::DirectionButton::DirectionButton() {
+ _movementId = 0;
+}
+
+void Scene3500::DirectionButton::synchronize(Serializer &s) {
+ NamedHotspot::synchronize(s);
+
+ s.syncAsSint16LE(_movementId);
+}
+
+bool Scene3500::DirectionButton::startAction(CursorType action, Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled) {
return true;
-
- if (scene->_field1286 != 4)
+ } else if (action == CURSOR_USE) {
+ R2_GLOBALS._sound2.play(14, nullptr, 63);
+ scene->doMovement(_movementId);
+ return true;
+ } else {
return SceneHotspot::startAction(action, event);
+ }
+}
- R2_GLOBALS._sound2.play(14);
- scene->sub107F71(_field34);
+/*--------------------------------------------------------------------------*/
- return true;
+Scene3500::Throttle::Throttle() {
+ _deltaX = 1;
+ _deltaY = 0;
+ _slideDeltaY = 0;
+ _deltaMouseY = 0;
+}
+
+void Scene3500::Throttle::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_pos.x);
+ s.syncAsSint16LE(_pos.y);
+ s.syncAsSint16LE(_deltaX);
+ s.syncAsSint16LE(_deltaY);
+ s.syncAsSint16LE(_slideDeltaY);
+ s.syncAsSint16LE(_deltaMouseY);
+}
+
+void Scene3500::Throttle::init(int xp, int yp, int dx, int dy, int speed) {
+ _deltaMouseY = 0;
+ _pos = Common::Point(xp, yp);
+ _deltaX = dx;
+ _deltaY = dy;
+ _slideDeltaY = _deltaY / _deltaX;
+
+ postInit();
+ setup(1050, 3, 1);
+ fixPriority(255);
+ setSpeed(speed);
+}
+
+void Scene3500::Throttle::updateSpeed() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_speed = _position.x - _pos.x;
+}
+
+void Scene3500::Throttle::setSpeed(int arg1){
+ changePosition(Common::Point(_pos.x + arg1, _pos.y - (_slideDeltaY * arg1)));
+}
+
+void Scene3500::Throttle::changePosition(const Common::Point &pt) {
+ setPosition(pt);
}
-void Scene3500::Actor7::process(Event &event) {
+void Scene3500::Throttle::process(Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled)
return;
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
- _fieldAE = 1 + event.mousePos.y - _position.y;
+ _deltaMouseY = 1 + event.mousePos.y - _position.y;
event.eventType = EVENT_NONE;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
- _fieldAE = 0;
+ if ((event.eventType == EVENT_BUTTON_UP) && (_deltaMouseY != 0)) {
+ _deltaMouseY = 0;
event.handled = true;
- if (scene->_action1._field24 == 0)
- sub1094ED();
+ if (!scene->_action1._field24)
+ updateSpeed();
}
- if (_fieldAE == 0)
+ if (_deltaMouseY == 0)
return;
R2_GLOBALS._sound2.play(338);
event.handled = true;
- int cx = event.mousePos.y - _fieldAE + 1;
- if (_fieldA6 >= cx) {
- if (_fieldA6 - _fieldAA <= cx)
- sub109693(Common::Point(((_fieldA6 - cx) / 2) + _fieldA4 + ((_fieldA6 - cx) % 2), cx));
+ int cx = event.mousePos.y - _deltaMouseY + 1;
+ if (_pos.y >= cx) {
+ if (_pos.y - _deltaY <= cx)
+ changePosition(Common::Point(((_pos.y - cx) / 2) + _pos.x + ((_pos.y - cx) % 2), cx));
else
- sub109693(Common::Point(_fieldA4 + _fieldA8, _fieldA6 - _fieldAA));
+ changePosition(Common::Point(_pos.x + _deltaX, _pos.y - _deltaY));
} else {
- sub109693(Common::Point(_fieldA4, _fieldA6));
+ changePosition(Common::Point(_pos.x, _pos.y));
}
}
-bool Scene3500::Actor7::startAction(CursorType action, Event &event) {
+bool Scene3500::Throttle::startAction(CursorType action, Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled) {
return true;
-
- if (scene->_field1286 == 4)
+ } else if (action == CURSOR_USE) {
return false;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
- return SceneActor::startAction(action, event);
+/*--------------------------------------------------------------------------*/
+
+int Scene3500::MazeUI3500::cellFromX(int x) {
+ return (_cellSize.x / 2) + x - (x % _cellSize.x);
+}
+
+int Scene3500::MazeUI3500::cellFromY(int y) {
+ return (_cellSize.y / 2) + y - (y % _cellSize.y) - 1;
+}
+
+int Scene3500::MazeUI3500::getCellFromMapXY(Common::Point pt) {
+ int cellX = pt.x / _cellSize.x;
+ int cellY = pt.y / _cellSize.y;
+
+ if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y)) {
+ return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2);
+ } else
+ return -1;
+}
+
+bool Scene3500::MazeUI3500::setMazePosition2(Common::Point &p) {
+ bool retVal = setMazePosition(p);
+ p = _mapOffset;
+
+ return retVal;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene3500::Scene3500() {
+ _moverVertX = 0;
+ _moverHorzX = 0;
+ _rotation = NULL;
+ _mazeChangeAmount = 0;
+ _speed = 0;
+ _field1272 = false;
+ _mazeDirection = MAZEDIR_NONE;
+ _nextMove = 0;
+ _mazePosition.x = 0;
+ _mazePosition.y = 0;
+ _field1282 = true; // Set to true in fixup()
+ _field1284 = 0;
+ _directionChangesEnabled = false;
+}
+
+void Scene3500::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+
+ s.syncAsSint16LE(_moverVertX);
+ s.syncAsSint16LE(_moverHorzX);
+ s.syncAsSint16LE(_mazeChangeAmount);
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_field1272);
+ s.syncAsSint16LE(_mazeDirection);
+ s.syncAsSint16LE(_nextMove);
+ s.syncAsSint16LE(_mazePosition.x);
+ s.syncAsSint16LE(_mazePosition.y);
+ s.syncAsSint16LE(_field1282);
+ s.syncAsSint16LE(_field1284);
+ s.syncAsSint16LE(_directionChangesEnabled);
}
void Scene3500::postInit(SceneObjectList *OwnerList) {
byte tmpPal[768];
- Rect tmpRect;
loadScene(1050);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.set(0, 0, 320, 200);
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
R2_GLOBALS._sound1.play(305);
R2_GLOBALS._player._characterIndex = R2_QUINN;
- R2_GLOBALS._player._characterScene[1] = 3500;
- R2_GLOBALS._player._characterScene[2] = 3500;
- R2_GLOBALS._player._characterScene[3] = 3500;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3500;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3500;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3500;
_field1284 = 0;
- _field1282 = 0;
- _field1278 = 0;
- _field1272 = 1;
- _field1270 = 4;
- _field126E = 4;
- _field127A = 860;
- _field127C = 891;
+ _field1282 = false;
+ _nextMove = 0;
+ _field1272 = true;
+ _speed = 4;
+ _mazeChangeAmount = 4;
+ _mazePosition = Common::Point(860, 891);
_rotation = R2_GLOBALS._scenePalette.addRotation(240, 254, -1);
_rotation->setDelay(0);
_rotation->_idxChange = 1;
@@ -3598,81 +3601,78 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._scenePalette._palette[(3 * i) + 2] = tmpPal[(3 * i) + 2];
}
- _actor7.sub109466(38, 165, 16, 32, _field1270);
- _actor7.setDetails(3500, 6, 7, -1, 1, (SceneItem *)NULL);
+ _throttle.init(38, 165, 16, 32, _speed);
+ _throttle.setDetails(3500, 6, 7, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._sound1.play(276);
- _item4._field34 = 88;
- _item4.setDetails(88, 3500, 18, 10, -1);
-
- _item5._field34 = 112;
- _item5.setDetails(112, 3500, 9, 10, -1);
-
- _item6._field34 = 104;
- _item6.setDetails(104, 3500, 15, 10, -1);
-
- _item7._field34 = 96;
- _item7.setDetails(96, 3500, 12, 10, -1);
-
- _actor8.postInit();
- _actor8.setup(10501, 1, 1);
- _actor8.setPosition(Common::Point(160, 73));
- _actor8.fixPriority(1);
-
- _actor9.postInit();
- _actor9.setup(1050, 2, 1);
- _actor9.setPosition(Common::Point(-160, 73));
- _actor9.fixPriority(11);
- _actor9.hide();
-
- _item2.setDetails(27, 3500, 21, -1, -1);
- _item3.setDetails(Rect(160, 89, 299, 182), 3500, 3, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL);
-
- _actor1.postInit();
- _field1276 = 1;
- _actor1.setup(1004, 1, _field1276);
- _actor1.setPosition(Common::Point(230, 135));
- _actor1.fixPriority(200);
- _actor1._frameChange = 1;
-
- _actor5.postInit();
- _actor5.setup(1004, 3, 1);
- _actor5.setPosition(Common::Point(117, 163));
- _actor5.fixPriority(200);
- _actor5.hide();
-
- _actor4.postInit();
- _actor4.setup(1004, 3, 2);
- _actor4.setPosition(Common::Point(126, 163));
- _actor4.fixPriority(200);
-
- _actor6.postInit();
- _actor6.setup(1004, 3, 3);
- _actor6.setPosition(Common::Point(135, 163));
- _actor6.fixPriority(200);
- _actor6.hide();
-
- _actor2.postInit();
- _actor2.setup(1004, 4, _field126E + 1);
- _actor2.setPosition(Common::Point(126, 137));
- _actor2.fixPriority(200);
-
- _actor3.postInit();
- _actor3.setup(1004, 5, 2);
- _actor3.setPosition(Common::Point(126, 108));
- _actor3.fixPriority(200);
-
- tmpRect.set(160, 89, 299, 182);
- _unkObj1.sub9EDE8(tmpRect);
- _unkObj1.sub51AE9(2);
- _unkObj1.sub51AFD(Common::Point(_field127A, _field127C));
-
- _action1._field24 = 0;
- warning("gfx_set_pane_p()");
- _unkObj1.sub51B02();
- warning("gfx_set_pane_p()");
- _field1286 = 1;
+ _pitchDown._movementId = 88;
+ _pitchDown.setDetails(88, 3500, 18, 10, -1);
+
+ _turnLeft._movementId = 112;
+ _turnLeft.setDetails(112, 3500, 9, 10, -1);
+
+ _pitchUp._movementId = 104;
+ _pitchUp.setDetails(104, 3500, 15, 10, -1);
+
+ _turnRight._movementId = 96;
+ _turnRight.setDetails(96, 3500, 12, 10, -1);
+
+ _tunnelVertCircle.postInit();
+ _tunnelVertCircle.setup(1050, 1, 1);
+ _tunnelVertCircle.setPosition(Common::Point(160, 73));
+ _tunnelVertCircle.fixPriority(1);
+
+ _tunnelHorzCircle.postInit();
+ _tunnelHorzCircle.setup(1050, 2, 1);
+ _tunnelHorzCircle.setPosition(Common::Point(-160, 73));
+ _tunnelHorzCircle.fixPriority(11);
+ _tunnelHorzCircle.hide();
+
+ _outsideView.setDetails(27, 3500, 21, -1, -1);
+ _mapScreen.setDetails(Rect(160, 89, 299, 182), 3500, 3, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL);
+
+ _shuttle.postInit();
+ _mazeDirection = MAZEDIR_NORTH;
+ _shuttle.setup(1004, 1, _mazeDirection);
+ _shuttle.setPosition(Common::Point(230, 135));
+ _shuttle.fixPriority(200);
+ _shuttle._frameChange = 1;
+
+ _symbolLeft.postInit();
+ _symbolLeft.setup(1004, 3, 1);
+ _symbolLeft.setPosition(Common::Point(117, 163));
+ _symbolLeft.fixPriority(200);
+ _symbolLeft.hide();
+
+ _symbolVertical.postInit();
+ _symbolVertical.setup(1004, 3, 2);
+ _symbolVertical.setPosition(Common::Point(126, 163));
+ _symbolVertical.fixPriority(200);
+
+ _symbolRight.postInit();
+ _symbolRight.setup(1004, 3, 3);
+ _symbolRight.setPosition(Common::Point(135, 163));
+ _symbolRight.fixPriority(200);
+ _symbolRight.hide();
+
+ _verticalSpeedDisplay.postInit();
+ _verticalSpeedDisplay.setup(1004, 4, _mazeChangeAmount + 1);
+ _verticalSpeedDisplay.setPosition(Common::Point(126, 137));
+ _verticalSpeedDisplay.fixPriority(200);
+
+ _horizontalSpeedDisplay.postInit();
+ _horizontalSpeedDisplay.setup(1004, 5, 2);
+ _horizontalSpeedDisplay.setPosition(Common::Point(126, 108));
+ _horizontalSpeedDisplay.fixPriority(200);
+
+ _mazeUI.setDisplayBounds(Rect(160, 89, 299, 182));
+ _mazeUI.load(2);
+ _mazeUI.setMazePosition(_mazePosition);
+
+ _action1._field24 = false;
+ _mazeUI.draw();
+ _directionChangesEnabled = true;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
@@ -3681,8 +3681,100 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._canWalk = false;
}
+void Scene3500::doMovement(int id) {
+ switch (id) {
+ case -1:
+ _throttle.updateSpeed();
+ if (_speed != 0) {
+ _speed--;
+ _throttle.setSpeed(_speed);
+ }
+ if (_action1._field24)
+ _speed = 0;
+ break;
+ case 1:
+ _throttle.updateSpeed();
+ if (_speed < 16) {
+ ++_speed;
+ _throttle.setSpeed(_speed);
+ }
+ if (_action1._field24)
+ _speed = 0;
+ break;
+ case 88:
+ // Up button has been pressed
+ // The original was doing a double check on action, only one is here.
+ if (!_action || (!_action1._field24)) {
+ _action2.handleVertButton(2);
+ if (_action && ((_action2.getActionIndex() != 0) || (_action2._direction != 2))) {
+ _action2.signal();
+ } else {
+ _tunnelHorzCircle.setAction(&_action2, &_tunnelHorzCircle, NULL);
+ }
+ }
+ break;
+ case 96:
+ // Right button has been pressed
+ if (!_action || !_action1._field24 || (_action1._direction == 1)) {
+ if (_action && (_nextMove == 0) && (_action1._field24)) {
+ _nextMove = id;
+ } else if (_action && (!_action1._field24)) {
+ _action1.handleHorzButton(1);
+ _action1.signal();
+ } else if (!_action) {
+ _action1.handleHorzButton(1);
+ setAction(&_action1, &_shuttle, NULL);
+ }
+
+ } else {
+ if (_nextMove != 0)
+ _nextMove = 0;
+
+ _action1.turnShuttle(false);
+ }
+ break;
+ case 104:
+ // Down button has been pressed
+ if (!_action || (!_action1._field24)) {
+ _action2.handleVertButton(-1);
+ if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._direction != -1))) {
+ _action2.signal();
+ } else {
+ _tunnelHorzCircle.setAction(&_action2, &_tunnelHorzCircle, NULL);
+ }
+ }
+ break;
+ case 112:
+ // Left button has been pressed
+ if (!_action || !_action1._field24 || (_action1._direction == 1)) {
+ if (_action && (_nextMove == 0) && (_action1._field24)) {
+ _nextMove = id;
+ } else if (_action && (!_action1._field24)) {
+ _action1.handleHorzButton(-1);
+ _action1.signal();
+ } else if (!_action) {
+ _action1.handleHorzButton(-1);
+ setAction(&_action1, &_shuttle, NULL);
+ }
+
+ } else {
+ if (_nextMove != 0)
+ _nextMove = 0;
+
+ _action1.turnShuttle(false);
+ }
+ break;
+ default:
+ _speed = id;
+ _throttle.setSpeed(id);
+ if (_action1._field24) {
+ _speed = 0;
+ }
+ break;
+ }
+}
+
void Scene3500::remove() {
- _rotation->remove();
R2_GLOBALS._sound2.fadeOut2(NULL);
SceneExt::remove();
}
@@ -3690,75 +3782,69 @@ void Scene3500::remove() {
void Scene3500::signal() {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _field1286 = 1;
+ _directionChangesEnabled = true;
}
void Scene3500::process(Event &event) {
- if (_field1286 == 0)
+ if (!_directionChangesEnabled)
return;
if (event.eventType == EVENT_KEYPRESS) {
switch (event.kbd.keycode) {
- case Common::KEYCODE_1:
- warning("FIXME: keycode = 0x4700");
+ case Common::KEYCODE_KP7:
R2_GLOBALS._sound2.play(338);
- sub107F71(16);
+ doMovement(16);
event.handled = true;
break;
- case Common::KEYCODE_2:
- warning("FIXME: keycode = 0x4800");
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(88);
+ doMovement(88);
event.handled = true;
break;
- case Common::KEYCODE_3:
- warning("FIXME: keycode = 0x4900");
- if (_field1270 < 16)
+ case Common::KEYCODE_KP9:
+ if (_speed < 16)
R2_GLOBALS._sound2.play(338);
- sub107F71(1);
+ doMovement(1);
event.handled = true;
break;
- case Common::KEYCODE_4:
- warning("FIXME: keycode = 0x4B00");
+ case Common::KEYCODE_KP4:
+ case Common::KEYCODE_LEFT:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(112);
+ doMovement(112);
event.handled = true;
break;
- case Common::KEYCODE_5:
- warning("FIXME: keycode = 0x4D00");
+ case Common::KEYCODE_KP6:
+ case Common::KEYCODE_RIGHT:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(96);
+ doMovement(96);
event.handled = true;
break;
- case Common::KEYCODE_6:
- warning("FIXME: keycode = 0x4F00");
+ case Common::KEYCODE_KP1:
R2_GLOBALS._sound2.play(338);
- sub107F71(0);
+ doMovement(0);
event.handled = true;
break;
- case Common::KEYCODE_7:
- warning("FIXME: keycode = 0x5000");
+ case Common::KEYCODE_KP2:
+ case Common::KEYCODE_DOWN:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(104);
+ doMovement(104);
event.handled = true;
break;
- case Common::KEYCODE_8:
- warning("FIXME: keycode = 0x5100");
- if (_field1270 != 0)
+ case Common::KEYCODE_KP3:
+ if (_speed != 0)
R2_GLOBALS._sound2.play(338);
- sub107F71(-1);
+ doMovement(-1);
event.handled = true;
break;
- case Common::KEYCODE_9:
- warning("FIXME: keycode = 0x5200");
+ case Common::KEYCODE_KP0:
R2_GLOBALS._sound2.play(338);
- sub107F71(8);
+ doMovement(8);
event.handled = true;
break;
- case Common::KEYCODE_0:
- warning("FIXME: keycode = 0x5300");
+ case Common::KEYCODE_KP_PERIOD:
R2_GLOBALS._sound2.play(338);
- sub107F71(4);
+ doMovement(4);
event.handled = true;
break;
default:
@@ -3767,19 +3853,19 @@ void Scene3500::process(Event &event) {
}
if (!event.handled)
- _actor7.process(event);
+ _throttle.process(event);
if (!event.handled)
- _item4.process(event);
+ _pitchDown.process(event);
if (!event.handled)
- _item5.process(event);
+ _turnLeft.process(event);
if (!event.handled)
- _item6.process(event);
+ _pitchUp.process(event);
if (!event.handled)
- _item7.process(event);
+ _turnRight.process(event);
Scene::process(event);
}
@@ -3787,104 +3873,105 @@ void Scene3500::process(Event &event) {
void Scene3500::dispatch() {
Rect tmpRect;
Scene::dispatch();
- if (((_actor1._frame % 2) == 0) && (_action1._field24 == 0)) {
- _actor1.setFrame(_actor1.changeFrame());
- _field1276 = _actor1._frame;
+
+ if (((_shuttle._frame % 2) == 0) && (!_action1._field24)) {
+ _shuttle.setFrame(_shuttle.changeFrame());
+ _mazeDirection = _shuttle._frame;
}
- int oldField1278;
- if ((_field1278 != 0) && (_action1._field24 == 0)) {
- oldField1278 = _field1278;
- _field1278 = 0;
- sub107F71(oldField1278);
+
+ if ((_nextMove != 0) && (!_action1._field24)) {
+ int move = _nextMove;
+ _nextMove = 0;
+ doMovement(move);
}
if (!_rotation)
return;
- int var_field127A = 0;
- int di = 0;
- int var_4 = 0;
- int var_6 = 0;
- int var_8 = 0;
- int var_a = 0;
- int dx = 0;
- int tmpVar = 0;
+ int newMazeX = 0;
+ int newMazeY = 0;
+ int mazePosX = 0;
+ int mazePosY = 0;
+ int deltaX = 0;
+ int deltaY = 0;
+ int tmpCellId = 0;
+ int cellId = 0;
- if ((_field126E == 0) && (_field1282 == 0)) {
+ if ((_mazeChangeAmount == 0) && !_field1282) {
if (_field1284 == 2)
R2_GLOBALS._sceneManager.changeScene(1000);
} else {
- _field1282 = 0;
+ _field1282 = false;
tmpRect.set(160, 89, 299, 182);
- var_field127A = _field127A;
- di = _field127C;
- var_4 = _unkObj1.sub1097C9(70) - 70;
- var_6 = _unkObj1.sub1097EF(_field127C + 46) - 46;
- var_8 = abs(var_4 - var_field127A);
- var_a = abs(var_6 - di);
- dx = 0;
-
- switch (_field1276) {
- case 0:
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, 46));
- if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1))
- || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) {
+ newMazeX = _mazePosition.x;
+ newMazeY = _mazePosition.y;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ mazePosY = _mazeUI.cellFromY(_mazePosition.y + 46) - 46;
+ deltaX = abs(mazePosX - newMazeX);
+ deltaY = abs(mazePosY - newMazeY);
+ tmpCellId = 0;
+
+ switch (_mazeDirection) {
+ case MAZEDIR_NORTH:
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1)) ||
+ ((cellId == 25 || cellId == 26 || cellId == 5 || cellId == 14 || cellId == 15) && deltaX > 3)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _unkObj1.sub1097EF(di + 46) - 46;
- di = _field127C - _field126E;
- dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (tmpVar != dx)) {
- di = var_6;
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ newMazeY = _mazePosition.y - _mazeChangeAmount;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 11) && (tmpVar != dx)) {
- di = var_6 + 3;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 11) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY + 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _unkObj1.sub1097EF(di + 46) - 46;
- var_a = abs(var_6 - di);
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
-
- if ( (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4)) && (di <= var_6) && (_field127C>= var_6))
- || (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E > 3) && (_action1._field24 != 0)) ) {
- di = var_6;
- if ((tmpVar != 25) && (tmpVar != 26) && (tmpVar != 5) && (tmpVar != 14) && (tmpVar == 15))
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ deltaY = abs(mazePosY - newMazeY);
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+
+ if ( (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (newMazeY <= mazePosY) && (_mazePosition.y>= mazePosY))
+ || (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= deltaY) && (_mazeChangeAmount > 3) && (_action1._field24 != 0)) ) {
+ newMazeY = mazePosY;
+ if ((cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 14) && (cellId == 15))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 11) && (var_6 + 3 >= di) && (_field127C >= var_6 + 3)) {
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 11) && (mazePosY + 3 >= newMazeY) && (_mazePosition.y >= mazePosY + 3)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) {
- var_field127A = var_4;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (deltaX != 0) && (deltaX <= 3)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -3892,65 +3979,65 @@ void Scene3500::dispatch() {
}
}
break;
- case 2:
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31))
- || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) {
+ case MAZEDIR_EAST:
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31))
+ || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (deltaY > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
- var_field127A = _field127A + _field126E;
- dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (tmpVar != dx)) {
- var_field127A = var_4;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ newMazeX = _mazePosition.x + _mazeChangeAmount;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 6) && (tmpVar != dx)) {
- var_field127A = var_4 - 5;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 6) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX - 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
- var_8 = abs(var_field127A - var_4);
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, tmpVar + 46));
- if ( (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15)) && (var_field127A >= var_4) && (_field127A <= var_4))
- || (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) {
- var_field127A = var_4;
- if ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4))
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ deltaX = abs(newMazeX - mazePosX);
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (newMazeX >= mazePosX) && (_mazePosition.x <= mazePosX))
+ || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= deltaX) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ) {
+ newMazeX = mazePosX;
+ if ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 6) && (var_4 - 5 <= var_field127A) && (_field127A <= var_4 - 5)) {
- var_field127A = var_4 - 5;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 6) && (mazePosX - 5 <= newMazeX) && (_mazePosition.x <= mazePosX - 5)) {
+ newMazeX = mazePosX - 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) {
- di = var_6;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (deltaY != 0) && (deltaY <= 3)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -3958,84 +4045,87 @@ void Scene3500::dispatch() {
}
}
break;
- case 4:
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if ( ((tmpVar == 2) || (tmpVar == 3) || (tmpVar == 6) || (tmpVar == 1))
- || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 > 3)) ) {
+ case MAZEDIR_SOUTH:
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( ((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1))
+ || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (deltaX > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _unkObj1.sub1097EF(di + 46) - 46;
- di = _field127C + _field126E;
- dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (tmpVar == dx)) {
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ newMazeY = _mazePosition.y + _mazeChangeAmount;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+
+ if (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (cellId != tmpCellId)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 16) && (tmpVar == dx)) {
- di = var_6 - 3;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 16) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY - 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 31) && (tmpVar == dx)) {
- di = var_6 + 4;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 31) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY + 4;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _unkObj1.sub1097EF(di + 46) - 46;
- var_a = abs(di - var_6);
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if ( (((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5)) && (di >= var_6) && (_field127C <= var_6))
- || (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (_field126E >= var_a) && (_field126E <= 3) && (_action1._field24 != 0)) ){
- if ((tmpVar != 23) && (tmpVar != 24) && (tmpVar != 4) && (tmpVar != 14) && (tmpVar != 15))
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ deltaY = abs(newMazeY - mazePosY);
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (newMazeY >= mazePosY) && (_mazePosition.y <= mazePosY))
+ || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= deltaY) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ){
+ newMazeY = mazePosY;
+
+ if ((cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 16) && (var_6 - 3 <= di) && (_field127C <= var_6 - 3)) {
- di = var_6 - 3;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 16) && (mazePosY - 3 <= newMazeY) && (_mazePosition.y <= mazePosY - 3)) {
+ newMazeY = mazePosY - 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 31) && (var_6 + 4 <= di) && (_field127C <= var_6 + 4)) {
- di = var_6 + 4;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 31) && (mazePosY + 4 <= newMazeY) && (_mazePosition.y <= mazePosY + 4)) {
+ newMazeY = mazePosY + 4;
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- if ((var_field127A == 660) && (_field126E + 306 <= di) && (di <= 307))
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ if ((newMazeX == 660) && (_mazeChangeAmount + 306 <= newMazeY) && (newMazeY <= 307))
++_field1284;
else
R2_GLOBALS._sound2.play(339);
- } else if (((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)) && (var_8 != 0) && (var_8 <= 3)) {
- var_field127A = var_4;
+ } else if (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (deltaX != 0) && (deltaX <= 3)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -4043,65 +4133,65 @@ void Scene3500::dispatch() {
}
}
break;
- case 6:
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if ( ((tmpVar == 12) || (tmpVar == 13) || (tmpVar == 11) || (tmpVar == 16) || (tmpVar == 31))
- || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a > 3)) ) {
+ case MAZEDIR_WEST:
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31))
+ || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (deltaY > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
- var_field127A = _field127A - _field126E;
- dx = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (tmpVar != dx)) {
- var_field127A = var_4;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ newMazeX = _mazePosition.x - _mazeChangeAmount;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 1) && (tmpVar != dx)) {
- var_field127A = var_4 + 5;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 1) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX + 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _unkObj1.sub1097C9(var_field127A + 70) - 70;
- var_8 = abs(var_4 - var_field127A);
- tmpVar = _unkObj1.sub109C09(Common::Point(var_field127A + 70, di + 46));
- if ( (((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14)) && (var_field127A <= var_4) && (_field127A >= var_4))
- || (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (_field126E >= var_8) && (_field126E <= 3) && (_action1._field24 != 0)) ) {
- var_field127A = var_4;
- if ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4))
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ deltaX = abs(mazePosX - newMazeX);
+ cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if ( (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (newMazeX <= mazePosX) && (_mazePosition.x >= mazePosX))
+ || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= deltaX) && (_mazeChangeAmount <= 3) && (_action1._field24)) ) {
+ newMazeX = mazePosX;
+ if ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((tmpVar == 1) && (var_field127A >= var_4 + 5) && (_field127A >= var_4 + 5)) {
- var_field127A = var_4 + 5;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 1) && (newMazeX >= mazePosX + 5) && (_mazePosition.x >= mazePosX + 5)) {
+ newMazeX = mazePosX + 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
- _field126E = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4)) && (var_a != 0) && (var_a <= 3)) {
- di = var_6;
+ _speed = 0;
+ _mazeChangeAmount = 0;
+ _field1272 = false;
+ if (!_action1._field24)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (deltaY != 0) && (deltaY <= 3)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -4114,101 +4204,94 @@ void Scene3500::dispatch() {
}
if (_field1284 < 2) {
- _field127A = var_field127A;
- _field127C = di;
- if (_unkObj1.sub109C5E(_field127A, _field127C) != 0) {
- _field1272 = 0;
- _field126E = 0;
- _field1270 = 0;
+ _mazePosition.x = newMazeX;
+ _mazePosition.y = newMazeY;
+ if (_mazeUI.setMazePosition2(_mazePosition) != 0) {
+ _field1272 = false;
+ _mazeChangeAmount = 0;
+ _speed = 0;
_rotation->setDelay(0);
_rotation->_idxChange = 0;
}
- warning("gfx_set_pane_p");
- _unkObj1.sub51B02();
+
+ _mazeUI.draw();
if (_field1284 != 0)
++_field1284;
}
}
- if (_field1272 == 0) {
- if (_field126E != _field1270) {
- if (_field126E >= _field1270) {
- if (_field126E == 1) {
- if (_action1._field24 != 0) {
- if ( ((_field1276 == 1) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 25) || (tmpVar == 26) || (tmpVar == 5) || (tmpVar == 14) || (tmpVar == 15)))
- || ((_field1276 == 3) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 25) || (tmpVar == 23) || (tmpVar == 14) || (tmpVar == 5) || (tmpVar == 4)))
- || ((_field1276 == 5) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((tmpVar == 23) || (tmpVar == 24) || (tmpVar == 4) || (tmpVar == 14) || (tmpVar == 15)))
- || ((_field1276 == 7) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((tmpVar == 26) || (tmpVar == 24) || (tmpVar == 15) || (tmpVar == 5) || (tmpVar == 4))) ){
- _field126E = 1;
+ if (!_field1272) {
+ if (_mazeChangeAmount != _speed) {
+ if (_mazeChangeAmount >= _speed) {
+ if (_mazeChangeAmount == 1) {
+ if (_action1._field24) {
+ if ( ((_mazeDirection == 1) && (deltaX == 0) && (deltaY != 0) && (deltaY <= 3) && ((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)))
+ || ((_mazeDirection == 3) && (deltaY == 0) && (deltaX != 0) && (deltaX <= 3) && ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)))
+ || ((_mazeDirection == 5) && (deltaX == 0) && (deltaY != 0) && (deltaY <= 3) && ((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)))
+ || ((_mazeDirection == 7) && (deltaY == 0) && (deltaX != 0) && (deltaX <= 3) && ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))) ){
+ _mazeChangeAmount = 1;
} else
- _field126E--;
+ _mazeChangeAmount--;
} else
- _field126E--;
+ _mazeChangeAmount--;
} else
- _field126E--;
+ _mazeChangeAmount--;
} else
- ++_field126E;
- _field1272 = 1;
+ ++_mazeChangeAmount;
+ _field1272 = true;
}
- _actor2.setFrame2(_field126E);
+ _verticalSpeedDisplay.setFrame2(_mazeChangeAmount + 1);
}
- if (_field1272 == 1) {
- if (_field126E == 0)
+ if (_field1272) {
+ if (_mazeChangeAmount == 0)
_rotation->_idxChange = 0;
- else if (_field126E > 8)
+ else if (_mazeChangeAmount > 8)
_rotation->_idxChange = 2;
else
_rotation->_idxChange = 1;
- }
- if (_field1272 != 0)
- _field1272--;
+ _field1272 = false;
+ }
- if (_field126E != 0) {
+ if (_mazeChangeAmount != 0) {
R2_GLOBALS._player._uiEnabled = false;
- if (_field126E != _field1270)
+ if (_mazeChangeAmount != _speed)
_aSound1.play(276);
} else {
R2_GLOBALS._player._uiEnabled = true;
_aSound1.fadeOut2(NULL);
}
-
- if (_rotation->_currIndex != _field1274)
- _field1274 = _rotation->_currIndex;
}
/*--------------------------------------------------------------------------
- * Scene 3600 -
+ * Scene 3600 - Cutscene - walking at gunpoint
*
*--------------------------------------------------------------------------*/
+
Scene3600::Scene3600() {
- _field2548 = 0;
- _field254A = 0;
- _field254C = 0;
- _field254E = 0;
- _field2550 = false;
+ _tealDead = false;
+ _lightEntered = false;
+ _ghoulTeleported = false;
}
void Scene3600::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field2548);
- s.syncAsSint16LE(_field254A);
- s.syncAsSint16LE(_field254C);
- s.syncAsSint16LE(_field254E);
- s.syncAsSint16LE(_field2550);
+ s.syncAsSint16LE(_tealDead);
+ s.syncAsSint16LE(_lightEntered);
+ s.syncAsSint16LE(_ghoulTeleported);
}
Scene3600::Action3600::Action3600() {
- _field1E = 0;
- _field20 = 0;
+ _field1E = false;
+ _fadePct = 0;
}
void Scene3600::Action3600::synchronize(Serializer &s) {
Action::synchronize(s);
s.syncAsSint16LE(_field1E);
- s.syncAsSint16LE(_field20);
+ s.syncAsSint16LE(_fadePct);
}
void Scene3600::Action3600::signal() {
@@ -4220,17 +4303,17 @@ void Scene3600::Action3600::signal() {
setDelay(60);
break;
case 1:
- if (_field1E == 0) {
- _field1E = 1;
- scene->_actor2.setAction(NULL);
+ if (!_field1E) {
+ _field1E = true;
+ scene->_steppingDisk.setAction(NULL);
R2_GLOBALS._sound2.play(330, NULL, 0);
R2_GLOBALS._sound2.fade(127, 5, 10, false, NULL);
}
+
setDelay(1);
- warning("TODO: Palette fader using parameter 2 = 256");
- R2_GLOBALS._scenePalette.fade((const byte *)&scene->_palette1._palette, true, _field20);
- if (_field20 > 0)
- _field20 -= 2;
+ R2_GLOBALS._scenePalette.fade((const byte *)&scene->_palette1._palette, true, _fadePct);
+ if (_fadePct > 0)
+ _fadePct -= 2;
break;
case 2:
R2_GLOBALS._sound2.stop();
@@ -4255,14 +4338,14 @@ void Scene3600::Action2::signal() {
R2_GLOBALS._events.proc1();
R2_GLOBALS._player.enableControl();
_actionIndex = 3619;
- scene->_actor13._state = 0;
+ scene->_protector._state = 0;
// No break on purpose
case 3619: {
++_actionIndex;
- scene->_actor13.setup(3127, 2, 1);
- scene->_actor13.animate(ANIM_MODE_1, NULL);
+ scene->_protector.setup(3127, 2, 1);
+ scene->_protector.animate(ANIM_MODE_1, NULL);
NpcMover *mover = new NpcMover();
- scene->_actor13.addMover(mover, &scene->_actor13._field8A, scene);
+ scene->_protector.addMover(mover, &scene->_protector._actorDestPos, scene);
}
break;
default:
@@ -4272,25 +4355,25 @@ void Scene3600::Action2::signal() {
}
}
-bool Scene3600::Item5::startAction(CursorType action, Event &event) {
+bool Scene3600::LightShaft::startAction(CursorType action, Event &event) {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- if ((action != CURSOR_USE) || (scene->_action1._field1E == 0))
+ if ((action != CURSOR_USE) || !scene->_action1._field1E)
return SceneItem::startAction(action, event);
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3624;
- scene->_actor10.setStrip2(-1);
- scene->_actor11.setStrip2(-1);
- scene->_actor12.setStrip2(-1);
- scene->_actor4.setStrip2(-1);
+ scene->_quinn.setStrip2(-1);
+ scene->_seeker.setStrip2(-1);
+ scene->_miranda.setStrip2(-1);
+ scene->_webbster.setStrip2(-1);
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player.setAction(&scene->_sequenceManager3, scene, 3611, &R2_GLOBALS._player, NULL);
- else if (R2_GLOBALS._player._characterIndex == 3)
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._player.setAction(&scene->_sequenceManager4, scene, 3612, &R2_GLOBALS._player, NULL);
else
R2_GLOBALS._player.setAction(&scene->_sequenceManager2, scene, 3610, &R2_GLOBALS._player, NULL);
@@ -4298,25 +4381,25 @@ bool Scene3600::Item5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
+bool Scene3600::Protector::startAction(CursorType action, Event &event) {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
switch(action) {
case CURSOR_TALK:
- if (!_action)
+ if (_action)
return SceneActor::startAction(action, event);
scene->_protectorSpeaker._displayMode = 1;
if (!R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- if (!scene->_actor10._mover)
- scene->_actor10.addMover(NULL);
- if (!scene->_actor11._mover)
- scene->_actor11.addMover(NULL);
- if (!scene->_actor12._mover)
- scene->_actor12.addMover(NULL);
- if (!scene->_actor4._mover)
- scene->_actor4.addMover(NULL);
+ if (!scene->_quinn._mover)
+ scene->_quinn.addMover(NULL);
+ if (!scene->_seeker._mover)
+ scene->_seeker.addMover(NULL);
+ if (!scene->_miranda._mover)
+ scene->_miranda.addMover(NULL);
+ if (!scene->_webbster._mover)
+ scene->_webbster.addMover(NULL);
setup(3127, 2, 1);
scene->_sceneMode = 3327;
@@ -4330,6 +4413,7 @@ bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
R2_GLOBALS._sound3.play(43);
else
R2_GLOBALS._sound3.play(99);
+
if (_state != 0) {
_state = 1;
setup(3128, 1, 1);
@@ -4353,16 +4437,13 @@ bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
void Scene3600::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 3600) {
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
} else {
- R2_GLOBALS._scrollFollower = &_actor2;
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
- R2_GLOBALS._v558B6.set(25, 0, 260, 200);
+ R2_GLOBALS._scrollFollower = &_steppingDisk;
+ _sceneBounds = Rect(160, 0, 480, 200);
}
loadScene(3600);
SceneExt::postInit();
- _field254C = 0;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4373,186 +4454,183 @@ void Scene3600::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_protectorSpeaker);
setZoomPercents(142, 80, 167, 105);
- R2_GLOBALS._player._characterScene[1] = 3600;
- R2_GLOBALS._player._characterScene[2] = 3600;
- R2_GLOBALS._player._characterScene[3] = 3600;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3600;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3600;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3600;
- _item2.setDetails(33, 3600, 6, -1, -1);
- _item3.setDetails(Rect(3, 3, 22, 45), 3600, 9, -1, -1, 1, NULL);
- _item4.setDetails(Rect(449, 3, 475, 45), 3600, 9, -1, -1, 1, NULL);
+ _console.setDetails(33, 3600, 6, -1, -1);
+ _tapestry1.setDetails(Rect(3, 3, 22, 45), 3600, 9, -1, -1, 1, NULL);
+ _tapestry2.setDetails(Rect(449, 3, 475, 45), 3600, 9, -1, -1, 1, NULL);
- _actor10.postInit();
- _actor10._moveDiff = Common::Point(3, 2);
- _actor10.changeZoom(-1);
- _actor10._effect = 1;
+ _quinn.postInit();
+ _quinn._moveDiff = Common::Point(3, 2);
+ _quinn.changeZoom(-1);
+ _quinn._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex != 1)
- _actor10.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ _quinn.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
- _actor11.postInit();
- _actor11._numFrames = 7;
- _actor11._moveDiff = Common::Point(5, 3);
- _actor11.changeZoom(-1);
- _actor11._effect = 1;
+ _seeker.postInit();
+ _seeker._numFrames = 7;
+ _seeker._moveDiff = Common::Point(5, 3);
+ _seeker.changeZoom(-1);
+ _seeker._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex != 2)
- _actor11.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
- _actor12.postInit();
- _actor12._moveDiff = Common::Point(3, 2);
- _actor12.changeZoom(-1);
- _actor12._effect = 1;
+ _miranda.postInit();
+ _miranda._moveDiff = Common::Point(3, 2);
+ _miranda.changeZoom(-1);
+ _miranda._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex != 3)
- _actor12.setDetails(9003, 1, -1, -1, 1, (SceneItem *) NULL);
+ _miranda.setDetails(9003, 1, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor4.postInit();
- _actor4._numFrames = 7;
- _actor4._moveDiff = Common::Point(5, 3);
- _actor4.changeZoom(-1);
- _actor4._effect = 1;
- _actor4.setDetails(3600, 27, -1, -1, 1, (SceneItem *) NULL);
+ _webbster.postInit();
+ _webbster._numFrames = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setDetails(3600, 27, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5._numFrames = 7;
- _actor5._moveDiff = Common::Point(3, 2);
- _actor5.changeZoom(-1);
- _actor5._effect = 1;
- _actor5.setDetails(3600, 12, -1, -1, 1, (SceneItem *) NULL);
+ _teal.postInit();
+ _teal._numFrames = 7;
+ _teal._moveDiff = Common::Point(3, 2);
+ _teal.changeZoom(-1);
+ _teal._effect = EFFECT_SHADED;
+ _teal.setDetails(3600, 12, -1, -1, 1, (SceneItem *) NULL);
_palette1.loadPalette(0);
_palette1.loadPalette(3601);
if (R2_GLOBALS._sceneManager._previousScene == 3600) {
- _item5._sceneRegionId = 200;
- _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
- _field254A = 1;
- _field2548 = 1;
+ _lightShaft._sceneRegionId = 200;
+ _lightShaft.setDetails(3600, 30, -1, -1, 5, &_webbster);
+ _tealDead = true;
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._walkRegions.enableRegion(14);
- R2_GLOBALS._walkRegions.enableRegion(15);
- R2_GLOBALS._walkRegions.enableRegion(16);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(14);
+ R2_GLOBALS._walkRegions.disableRegion(15);
+ R2_GLOBALS._walkRegions.disableRegion(16);
- _actor10.setup(10, 5, 11);
- _actor10.animate(ANIM_MODE_1, NULL);
+ _quinn.setup(10, 5, 11);
+ _quinn.animate(ANIM_MODE_1, NULL);
- _actor11.setup(20, 5, 11);
- _actor11.animate(ANIM_MODE_1, NULL);
+ _seeker.setup(20, 5, 11);
+ _seeker.animate(ANIM_MODE_1, NULL);
- _actor12.setup(30, 5, 11);
- _actor12.animate(ANIM_MODE_1, NULL);
+ _miranda.setup(30, 5, 11);
+ _miranda.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor10.setPosition(Common::Point(76, 148));
- _actor11.setPosition(Common::Point(134, 148));
- _actor12.setPosition(Common::Point(100, 148));
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _quinn.setPosition(Common::Point(76, 148));
+ _seeker.setPosition(Common::Point(134, 148));
+ _miranda.setPosition(Common::Point(100, 148));
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- R2_GLOBALS._player.setup(20, _actor11._strip, 1);
- R2_GLOBALS._player.setPosition(_actor11._position);
- _actor11.hide();
- } else if (R2_GLOBALS._player._characterIndex == 3) {
- _actor10.setPosition(Common::Point(110, 148));
- _actor11.setPosition(Common::Point(76, 148));
- _actor12.setPosition(Common::Point(134, 148));
+ R2_GLOBALS._player.setup(20, _seeker._strip, 1);
+ R2_GLOBALS._player.setPosition(_seeker._position);
+ _seeker.hide();
+ } else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
+ _quinn.setPosition(Common::Point(110, 148));
+ _seeker.setPosition(Common::Point(76, 148));
+ _miranda.setPosition(Common::Point(134, 148));
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(30, _actor12._strip, 1);
- R2_GLOBALS._player.setPosition(_actor12._position);
- _actor12.hide();
+ R2_GLOBALS._player.setup(30, _miranda._strip, 1);
+ R2_GLOBALS._player.setPosition(_miranda._position);
+ _miranda.hide();
} else {
- _actor10.setPosition(Common::Point(134, 148));
- _actor11.setPosition(Common::Point(76, 148));
- _actor12.setPosition(Common::Point(110, 148));
+ _quinn.setPosition(Common::Point(134, 148));
+ _seeker.setPosition(Common::Point(76, 148));
+ _miranda.setPosition(Common::Point(110, 148));
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(10, _actor10._strip, 1);
- R2_GLOBALS._player.setPosition(_actor10._position);
- _actor10.hide();
+ R2_GLOBALS._player.setup(10, _quinn._strip, 1);
+ R2_GLOBALS._player.setPosition(_quinn._position);
+ _quinn.hide();
}
- _actor4.setPosition(Common::Point(47, 149));
- _actor4.setup(40, 1, 11);
- _actor4.animate(ANIM_MODE_1, NULL);
+ _webbster.setPosition(Common::Point(47, 149));
+ _webbster.setup(40, 1, 11);
+ _webbster.animate(ANIM_MODE_1, NULL);
- _actor5.setPosition(Common::Point(367, 148));
- _actor5.setup(3601, 7, 5);
+ _teal.setPosition(Common::Point(367, 148));
+ _teal.setup(3601, 7, 5);
if (!R2_GLOBALS.getFlag(71)) {
- _actor13.postInit();
- _actor13._state = 0;
- _actor13._field8A = Common::Point(226, 152);
- _actor13._moveDiff = Common::Point(3, 2);
- _actor13.setPosition(Common::Point(284, 152));
- _actor13.setup(3127, 2, 1);
- _actor13.changeZoom(-1);
- _actor13.setDetails(3600, 15, -1, 17, 1, (SceneItem *) NULL);
+ _protector.postInit();
+ _protector._state = 0;
+ _protector._actorDestPos = Common::Point(226, 152);
+ _protector._moveDiff = Common::Point(3, 2);
+ _protector.setPosition(Common::Point(284, 152));
+ _protector.setup(3127, 2, 1);
+ _protector.changeZoom(-1);
+ _protector.setDetails(3600, 15, -1, 17, 1, (SceneItem *) NULL);
}
R2_GLOBALS._sound2.play(330);
- _actor3.postInit();
- _actor3.setPosition(Common::Point(84, 156));
- _actor3.fixPriority(158);
- _actor3.setup(3601, 5, 1);
- _actor3.animate(ANIM_MODE_2, NULL);
-
- _action1._field1E = 1;
- _action1._field20 = 0;
+ _consoleLights.postInit();
+ _consoleLights.setPosition(Common::Point(84, 156));
+ _consoleLights.fixPriority(158);
+ _consoleLights.setup(3601, 5, 1);
+ _consoleLights.animate(ANIM_MODE_2, NULL);
+
+ _action1._field1E = true;
+ _action1._fadePct = 0;
_action1.setActionIndex(1);
- _actor3.setAction(&_action1);
+ _consoleLights.setAction(&_action1);
_sceneMode = 3623;
g_globals->_events.setCursor(CURSOR_ARROW);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
- _field254A = 0;
- _field2548 = 0;
+ _tealDead = false;
- R2_GLOBALS._walkRegions.enableRegion(17);
- R2_GLOBALS._walkRegions.enableRegion(18);
+ R2_GLOBALS._walkRegions.disableRegion(17);
+ R2_GLOBALS._walkRegions.disableRegion(18);
- _actor10.setPosition(Common::Point(393, 148));
- _actor11.setPosition(Common::Point(364, 153));
- _actor12.setPosition(Common::Point(413, 164));
+ _quinn.setPosition(Common::Point(393, 148));
+ _seeker.setPosition(Common::Point(364, 153));
+ _miranda.setPosition(Common::Point(413, 164));
R2_GLOBALS._player.hide();
- _actor4.setPosition(Common::Point(373, 164));
+ _webbster.setPosition(Common::Point(373, 164));
- _actor5.setup(3403, 8, 11);
- _actor5.setPosition(Common::Point(403, 155));
+ _teal.setup(3403, 8, 11);
+ _teal.setPosition(Common::Point(403, 155));
- _actor12.setup(3403, 7, 1);
+ _protector.setup(3403, 7, 1);
+ _protector.setPosition(Common::Point(405, 155));
- _actor13.setPosition(Common::Point(405, 155));
+ _steppingDisk.postInit();
+ _steppingDisk.setup(3600, 2, 1);
+ _steppingDisk.setPosition(Common::Point(403, 161));
+ _steppingDisk.fixPriority(149);
+ _steppingDisk.changeZoom(-1);
- _actor2.postInit();
- _actor2.setup(3600, 2, 1);
- _actor2.setPosition(Common::Point(403, 161));
- _actor2.fixPriority(149);
- _actor2.changeZoom(-1);
-
- _action1._field1E = 0;
- _action1._field20 = 90;
+ _action1._field1E = false;
+ _action1._fadePct = 90;
_sceneMode = 3600;
- setAction(&_sequenceManager1, this, 3600, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, &_actor2, NULL);
- _field254E = 0;
+ setAction(&_sequenceManager1, this, 3600, &_seeker, &_quinn, &_miranda,
+ &_webbster, &_teal, &_steppingDisk, NULL);
}
- _field254E = 0;
- _field2550 = R2_GLOBALS.getFlag(71);
+ _lightEntered = false;
+ _ghoulTeleported = R2_GLOBALS.getFlag(71);
R2_GLOBALS._sound1.play(326);
- _item1.setDetails(Rect(0, 0, 480, 200), 3600, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 3600, 0, -1, -1, 1, NULL);
}
void Scene3600::remove() {
- _actor3.animate(ANIM_MODE_NONE, NULL);
- _actor3.setAction(NULL);
+ _consoleLights.animate(ANIM_MODE_NONE, NULL);
+ _consoleLights.setAction(NULL);
R2_GLOBALS._sound2.fadeOut2(NULL);
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
@@ -4562,136 +4640,143 @@ void Scene3600::remove() {
void Scene3600::signal() {
switch (_sceneMode) {
case 3320:
- warning("STUB: sub_1D227()");
- R2_GLOBALS._walkRegions.enableRegion(14);
- R2_GLOBALS._scrollFollower = &_actor11;
+ // Move to the console
+ R2_GLOBALS._walkRegions.disableRegion(14);
+ R2_GLOBALS._scrollFollower = &_seeker;
_tealSpeaker._object1.hide();
- _actor5.show();
- _actor5.setStrip(2);
- if (R2_GLOBALS._player._characterIndex == 2)
+ _teal.show();
+ _teal.setStrip(2);
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_sceneMode = 3602;
- else if (R2_GLOBALS._player._characterIndex == 3)
+ else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_sceneMode = 3603;
else
_sceneMode = 3601;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_seeker, &_quinn,
+ &_miranda, &_webbster, &_teal, NULL);
break;
case 3321:
- warning("STUB: sub_1D227()");
+ // Teal activates console
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- _tealSpeaker.proc16();
- _actor5.show();
- _actor5.setStrip(1);
- _actor3.postInit();
+ _tealSpeaker.stopSpeaking();
+ _teal.show();
+ _teal.setStrip(1);
+ _consoleLights.postInit();
_sceneMode = 3604;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor3, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_teal, &_consoleLights,
+ &_quinn, &_seeker, &_miranda, &_webbster, NULL);
break;
case 3322:
- warning("STUB: sub_1D227()");
- _quinnSpeaker.proc16();
+ // Teal walks toward the teleport pod, the goule protector appears
+ _quinnSpeaker.stopSpeaking();
_quinnSpeaker._displayMode = 1;
- _tealSpeaker.proc16();
+ _tealSpeaker.stopSpeaking();
_tealSpeaker._displayMode = 7;
- R2_GLOBALS._scrollFollower = &_actor5;
+ R2_GLOBALS._scrollFollower = &_teal;
_sceneMode = 3605;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor13, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_teal, &_protector, &_steppingDisk, NULL);
break;
case 3323:
- if (_field254A == 0)
- _field254A = 1;
+ // Goule protector eats Teal guts then moves
+
+ if (!_tealDead)
+ _tealDead = true;
else {
- warning("STUB: sub_1D227()");
- _protectorSpeaker.proc16();
- _actor13.show();
- _actor13.setup(3258, 6, 1);
+ _protectorSpeaker.stopSpeaking();
+ _protector.show();
+ _protector.setup(3258, 6, 1);
+
_sceneMode = 3607;
- _actor13.setAction(&_sequenceManager1, this, _sceneMode, &_actor13, NULL);
- R2_GLOBALS._v558C2 = 1;
- _protectorSpeaker.proc16();
+ _protector.setAction(&_sequenceManager1, this, _sceneMode, &_protector, NULL);
+
+ _protectorSpeaker.stopSpeaking();
_protectorSpeaker._displayMode = 1;
_quinnSpeaker._displayMode = 1;
- _actor13.show();
+ _protector.show();
+
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- R2_GLOBALS._walkRegions.disableRegion(17);
- R2_GLOBALS._walkRegions.disableRegion(18);
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._walkRegions.enableRegion(14);
- R2_GLOBALS._walkRegions.enableRegion(15);
- R2_GLOBALS._walkRegions.enableRegion(16);
- _actor13.setAction(&_action1);
+ R2_GLOBALS._walkRegions.enableRegion(17);
+ R2_GLOBALS._walkRegions.enableRegion(18);
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.disableRegion(14);
+ R2_GLOBALS._walkRegions.disableRegion(15);
+ R2_GLOBALS._walkRegions.disableRegion(16);
+
+ _consoleLights.setAction(&_action1);
}
break;
case 3324:
// No break on purpose
case 3607:
g_globals->_events.setCursor(CURSOR_ARROW);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _actor13.fixPriority(-1);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
+ _protector.fixPriority(-1);
_sceneMode = 3623;
- _field2548 = 1;
break;
case 3327:
g_globals->_events.setCursor(CURSOR_ARROW);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
_sceneMode = 3623;
break;
case 3450:
+ // Speech of Teal and Quinn
R2_GLOBALS._sound1.stop();
- _actor1.hide();
- _actor6.hide();
- g_globals->gfxManager()._bounds.moveTo(Common::Point(40, 0));
+ _protector3400.hide();
+ _door3400.hide();
+
+ _sceneBounds = Rect(40, 0, SCREEN_WIDTH + 40, SCREEN_HEIGHT);
setZoomPercents(142, 80, 167, 105);
loadScene(3600);
R2_GLOBALS._uiElements.show();
- _item5._sceneRegionId = 200;
- _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
-
- _actor3.show();
- _actor10.show();
- _actor11.show();
- _actor12.show();
- _actor4.show();
- _actor5.show();
-
- _actor5.setPosition(Common::Point(298, 151));
-
- _actor13.postInit();
- _actor13._state = 0;
- _actor13._field8A = Common::Point(226, 152);
- _actor13._moveDiff = Common::Point(5, 3);
- _actor13.setup(3403, 7, 1);
- _actor13.setPosition(Common::Point(405, 155));
- _actor13.changeZoom(-1);
- _actor13.addMover(NULL);
- _actor13.animate(ANIM_MODE_NONE);
- _actor13.hide();
- _actor13.setDetails(3600, 15, -1, 17, 5, &_item5);
-
- _actor2.setup(3600, 2, 1);
- _actor2.setPosition(Common::Point(403, 161));
- _actor2.fixPriority(149);
- _actor2.changeZoom(-1);
- _actor2.show();
+ _lightShaft._sceneRegionId = 200;
+ _lightShaft.setDetails(3600, 30, -1, -1, 5, &_webbster);
+
+ _consoleLights.show();
+ _quinn.show();
+ _seeker.show();
+ _miranda.show();
+ _webbster.show();
+ _teal.show();
+
+ _teal.setPosition(Common::Point(298, 151));
+
+ _protector.postInit();
+ _protector._state = 0;
+ _protector._actorDestPos = Common::Point(226, 152);
+ _protector._moveDiff = Common::Point(5, 3);
+ _protector.setup(3403, 7, 1);
+ _protector.setPosition(Common::Point(405, 155));
+ _protector.changeZoom(-1);
+ _protector.addMover(NULL);
+ _protector.animate(ANIM_MODE_NONE);
+ _protector.hide();
+ _protector.setDetails(3600, 15, -1, 17, 5, &_lightShaft);
+
+ _steppingDisk.setup(3600, 2, 1);
+ _steppingDisk.setPosition(Common::Point(403, 161));
+ _steppingDisk.fixPriority(149);
+ _steppingDisk.changeZoom(-1);
+ _steppingDisk.show();
_quinnSpeaker._displayMode = 2;
_tealSpeaker._displayMode = 2;
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- R2_GLOBALS._player.setup(20, _actor11._strip, 1);
- R2_GLOBALS._player.setPosition(_actor11._position);
- _actor11.hide();
- } else if (R2_GLOBALS._player._characterIndex == 3) {
+ R2_GLOBALS._player.setup(20, _seeker._strip, 1);
+ R2_GLOBALS._player.setPosition(_seeker._position);
+ _seeker.hide();
+ } else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(30, _actor12._strip, 1);
- R2_GLOBALS._player.setPosition(_actor12._position);
- _actor12.hide();
+ R2_GLOBALS._player.setup(30, _miranda._strip, 1);
+ R2_GLOBALS._player.setPosition(_miranda._position);
+ _miranda.hide();
} else {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(10, _actor10._strip, 1);
- R2_GLOBALS._player.setPosition(_actor10._position);
- _actor10.hide();
+ R2_GLOBALS._player.setup(10, _quinn._strip, 1);
+ R2_GLOBALS._player.setPosition(_quinn._position);
+ _quinn.hide();
}
R2_GLOBALS._player.show();
R2_GLOBALS._sound1.play(326);
@@ -4700,6 +4785,7 @@ void Scene3600::signal() {
R2_GLOBALS._sound2.play(329);
break;
case 3600:
+ // First speech by Teal
_sceneMode = 3320;
_stripManager.start(3320, this);
break;
@@ -4708,53 +4794,56 @@ void Scene3600::signal() {
case 3602:
// No break on purpose
case 3603:
- R2_GLOBALS._walkRegions.enableRegion(2);
- R2_GLOBALS._walkRegions.enableRegion(7);
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ // Teal speech near the console
+ R2_GLOBALS._walkRegions.disableRegion(2);
+ R2_GLOBALS._walkRegions.disableRegion(7);
_tealSpeaker._displayMode = 1;
_sceneMode = 3321;
_stripManager.start(3321, this);
break;
case 3604:
+ // Goule Protector forces the door
R2_GLOBALS._sound2.fadeOut2(NULL);
R2_GLOBALS._sound1.stop();
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
- _actor2.hide();
- _actor3.hide();
+ _steppingDisk.hide();
+ _consoleLights.hide();
R2_GLOBALS._player.hide();
- _actor10.hide();
- _actor11.hide();
- _actor12.hide();
- _actor4.hide();
- _actor5.hide();
+ _quinn.hide();
+ _seeker.hide();
+ _miranda.hide();
+ _webbster.hide();
+ _teal.hide();
- g_globals->gfxManager()._bounds.moveTo(Common::Point(60, 0));
+ _sceneBounds = Rect(60, 0, SCREEN_WIDTH + 60, SCREEN_HEIGHT);
setZoomPercents(51, 46, 180, 200);
loadScene(3400);
R2_GLOBALS._uiElements.show();
- _actor1.postInit();
+ _protector3400.postInit();
- _actor2.setup(3403, 1, 1);
- _actor2.setPosition(Common::Point(190, 103));
- _actor2.fixPriority(89);
- _actor2.show();
+ _steppingDisk.setup(3403, 1, 1);
+ _steppingDisk.setPosition(Common::Point(190, 103));
+ _steppingDisk.fixPriority(89);
+ _steppingDisk.show();
- _actor6.postInit();
- _actor6.setup(3400, 1, 6);
- _actor6.setPosition(Common::Point(236, 51));
- _actor6.fixPriority(51);
- R2_GLOBALS._scrollFollower = &_actor6;
+ _door3400.postInit();
+ _door3400.setup(3400, 1, 6);
+ _door3400.setPosition(Common::Point(236, 51));
+ _door3400.fixPriority(51);
+ R2_GLOBALS._scrollFollower = &_door3400;
R2_GLOBALS._sound1.play(323);
_sceneMode = 3450;
- setAction(&_sequenceManager1, this, 3450, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 3450, &_protector3400, &_door3400, NULL);
break;
case 3605:
- _actor13.setup(3258, 4, 1);
- _actor13.setAction(&_sequenceManager1, this, 3606, &_actor5, &_actor13, &_actor2, NULL);
+ // Goule protector jumps on Teal
+ _protector.setup(3258, 4, 1);
+ _protector.setAction(&_sequenceManager1, this, 3606, &_teal, &_protector,
+ &_steppingDisk, NULL);
_sceneMode = 3323;
_stripManager.start(3323, this);
@@ -4762,21 +4851,22 @@ void Scene3600::signal() {
case 3620:
// No break on purpose
case 3623:
- if ((_actor13._position.x == 226) && (_actor13._position.y == 152) && (_action1._field1E != 0) && (_actor13._visage == 3127) && (!R2_GLOBALS.getFlag(71))) {
+ if ((_protector._position.x == 226) && (_protector._position.y == 152)
+ && _action1._field1E && (_protector._visage == 3127) && (!R2_GLOBALS.getFlag(71))) {
R2_GLOBALS._sound2.stop();
R2_GLOBALS._sound2.play(331);
R2_GLOBALS.setFlag(71);
_sceneMode = 3626;
- setAction(&_sequenceManager1, this, 3626, &_actor13, NULL);
+ setAction(&_sequenceManager1, this, 3626, &_protector, NULL);
}
break;
case 3624:
R2_GLOBALS._player.disableControl();
- if ((_field254E != 0) && (_actor10._position.x == 229) && (_actor10._position.y == 154) && (_actor11._position.x == 181) && (_actor11._position.y == 154) && (_actor12._position.x == 207) && (_actor12._position.y == 154) && (_actor4._position.x == 155) && (_actor4._position.y == 154)) {
+ if (_lightEntered && (_quinn._position.x == 229) && (_quinn._position.y == 154) && (_seeker._position.x == 181) && (_seeker._position.y == 154) && (_miranda._position.x == 207) && (_miranda._position.y == 154) && (_webbster._position.x == 155) && (_webbster._position.y == 154)) {
R2_GLOBALS._sound2.stop();
R2_GLOBALS._sound2.play(331);
_sceneMode = 3625;
- setAction(&_sequenceManager1, this, 3625, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 3625, &_quinn, &_seeker, &_miranda, &_webbster, NULL);
}
break;
case 3625:
@@ -4784,7 +4874,7 @@ void Scene3600::signal() {
R2_GLOBALS._sceneManager.changeScene(3700);
break;
case 3626:
- _actor13.setPosition(Common::Point(0, 0));
+ _protector.setPosition(Common::Point(0, 0));
_action1.setActionIndex(2);
if (R2_GLOBALS._events.getCursor() > R2_LAST_INVENT) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
@@ -4801,72 +4891,74 @@ void Scene3600::signal() {
}
void Scene3600::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW) && (event.mousePos.x > 237) && (!R2_GLOBALS.getFlag(71))) {
- SceneItem::display(3600, 17, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7 -999);
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW)
+ && (event.mousePos.x > 237) && (!R2_GLOBALS.getFlag(71))) {
+ SceneItem::display(3600, 17, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
event.handled = true;
}
Scene::process(event);
}
void Scene3600::dispatch() {
- if ((R2_GLOBALS._player.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ if ((R2_GLOBALS._player.getRegionIndex() == 200) && _action1._field1E && !_lightEntered) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- if (_actor13._mover)
- _actor13.addMover(NULL);
+ if (_protector._mover)
+ _protector.addMover(NULL);
+
if (R2_GLOBALS._player._action)
R2_GLOBALS._player.setAction(NULL);
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- _field254C = 0;
- _field254E = 1;
+ _lightEntered = true;
- R2_GLOBALS._walkRegions.disableRegion(2);
- R2_GLOBALS._walkRegions.disableRegion(7);
+ R2_GLOBALS._walkRegions.enableRegion(2);
+ R2_GLOBALS._walkRegions.enableRegion(7);
R2_GLOBALS._player.disableControl();
_sceneMode = 3624;
- _actor10.setStrip(-1);
- _actor11.setStrip(-1);
- _actor12.setStrip(-1);
- _actor4.setStrip(-1);
+ _quinn.setStrip(-1);
+ _seeker.setStrip(-1);
+ _miranda.setStrip(-1);
+ _webbster.setStrip(-1);
R2_GLOBALS._player.hide();
- if (R2_GLOBALS._player._characterIndex == 2) {
- _actor11.setPosition(R2_GLOBALS._player._position);
- _actor11.show();
- } else if (R2_GLOBALS._player._characterIndex == 3) {
- _actor12.setPosition(R2_GLOBALS._player._position);
- _actor12.show();
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _seeker.setPosition(R2_GLOBALS._player._position);
+ _seeker.show();
+ } else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
+ _miranda.setPosition(R2_GLOBALS._player._position);
+ _miranda.show();
} else {
- _actor10.setPosition(R2_GLOBALS._player._position);
- _actor10.show();
+ _quinn.setPosition(R2_GLOBALS._player._position);
+ _quinn.show();
}
- _actor10.setAction(&_sequenceManager2, this, 3610, &_actor10, NULL);
- _actor11.setAction(&_sequenceManager3, this, 3611, &_actor11, NULL);
- _actor12.setAction(&_sequenceManager4, this, 3612, &_actor12, NULL);
- _actor4.setAction(&_sequenceManager1, this, 3613, &_actor4, NULL);
+ _quinn.setAction(&_sequenceManager2, this, 3610, &_quinn, NULL);
+ _seeker.setAction(&_sequenceManager3, this, 3611, &_seeker, NULL);
+ _miranda.setAction(&_sequenceManager4, this, 3612, &_miranda, NULL);
+ _webbster.setAction(&_sequenceManager1, this, 3613, &_webbster, NULL);
}
- if ((_actor13.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ if ((_protector.getRegionIndex() == 200) && _action1._field1E && !_ghoulTeleported) {
R2_GLOBALS._sound2.fadeOut2(NULL);
_sceneMode = 3620;
- _field2550 = 1;
+ _ghoulTeleported = true;
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- if (_actor10._mover)
- _actor10.addMover(NULL);
- if (_actor11._mover)
- _actor11.addMover(NULL);
- if (_actor12._mover)
- _actor12.addMover(NULL);
- if (_actor4._mover)
- _actor4.addMover(NULL);
+ if (_quinn._mover)
+ _quinn.addMover(NULL);
+ if (_seeker._mover)
+ _seeker.addMover(NULL);
+ if (_miranda._mover)
+ _miranda.addMover(NULL);
+ if (_webbster._mover)
+ _webbster.addMover(NULL);
}
+
Scene::dispatch();
}
@@ -4874,10 +4966,13 @@ void Scene3600::dispatch() {
* Scene 3700 - Cutscene - Teleport outside
*
*--------------------------------------------------------------------------*/
+
void Scene3700::postInit(SceneObjectList *OwnerList) {
loadScene(3700);
R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._uiElements._visible = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4885,30 +4980,31 @@ void Scene3700::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_mirandaSpeaker);
- _actor1.postInit();
- _actor1._moveDiff = Common::Point(3, 2);
+ _quinn.postInit();
+ _quinn._moveDiff = Common::Point(3, 2);
- _actor2.postInit();
- _actor2._numFrames = 7;
- _actor2._moveDiff = Common::Point(5, 3);
- _actor2.hide();
+ _seeker.postInit();
+ _seeker._numFrames = 7;
+ _seeker._moveDiff = Common::Point(5, 3);
+ _seeker.hide();
- _actor3.postInit();
- _actor3._moveDiff = Common::Point(3, 2);
- _actor3.hide();
+ _miranda.postInit();
+ _miranda._moveDiff = Common::Point(3, 2);
+ _miranda.hide();
- _actor4.postInit();
- _actor4._numFrames = 7;
- _actor4._moveDiff = Common::Point(5, 3);
- _actor4.hide();
+ _webbster.postInit();
+ _webbster._numFrames = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.hide();
- _actor5.postInit();
+ _teleportPad.postInit();
- R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
R2_GLOBALS._sound1.play(332);
_sceneMode = 3700;
- setAction(&_sequenceManager, this, 3700, &_actor1, &_actor2, &_actor3, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 3700, &_quinn, &_seeker, &_miranda,
+ &_webbster, &_teleportPad, NULL);
}
void Scene3700::remove() {
@@ -4921,13 +5017,12 @@ void Scene3700::signal() {
case 3328:
// No break on purpose
case 3329:
- warning("STUB: sub_1D227()");
_sceneMode = 3701;
- setAction(&_sequenceManager, this, 3701, &_actor2, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 3701, &_seeker, &_miranda, &_webbster, NULL);
break;
case 3700:
- _actor1.setup(10, 6, 1);
- _actor2.setup(20, 5, 1);
+ _quinn.setup(10, 6, 1);
+ _seeker.setup(20, 5, 1);
if (R2_GLOBALS.getFlag(71)) {
_sceneMode = 3329;
_stripManager.start(3329, this);
@@ -4946,45 +5041,47 @@ void Scene3700::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 3800 -
+ * Scene 3800 - Desert
*
*--------------------------------------------------------------------------*/
+
Scene3800::Scene3800() {
- _field412 = 0;
+ _desertDirection = 0;
}
+
void Scene3800::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_desertDirection);
}
-void Scene3800::Exit1::changeScene() {
+void Scene3800::NorthExit::changeScene() {
Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->_field412 = 1;
+ R2_GLOBALS._player.disableControl();
+ scene->_desertDirection = 1;
if (R2_GLOBALS.getFlag(46)) {
- if (scene->_field412 == R2_GLOBALS._v566A9) {
- R2_GLOBALS._v566AA = 3;
- if (R2_GLOBALS._v56A93 + 1 == 0) {
- R2_GLOBALS._v566A8--;
- R2_GLOBALS._v566A9 = 0;
+ if (scene->_desertDirection == R2_GLOBALS._desertCorrectDirection) {
+ R2_GLOBALS._desertPreviousDirection = 3;
+ if (R2_GLOBALS._desertWrongDirCtr + 1 == 0) {
+ R2_GLOBALS._desertStepsRemaining--;
+ R2_GLOBALS._desertCorrectDirection = 0;
} else {
- R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
- R2_GLOBALS._v56A93--;
+ R2_GLOBALS._desertCorrectDirection = R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr];
+ R2_GLOBALS._desertWrongDirCtr--;
}
} else {
- ++R2_GLOBALS._v56A93;
- if (R2_GLOBALS._v56A93 > 999)
- R2_GLOBALS._v56A93 = 999;
- R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
- R2_GLOBALS._v566A9 = 3;
+ ++R2_GLOBALS._desertWrongDirCtr;
+ if (R2_GLOBALS._desertWrongDirCtr > 999)
+ R2_GLOBALS._desertWrongDirCtr = 999;
+ R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr] = R2_GLOBALS._desertCorrectDirection;
+ R2_GLOBALS._desertCorrectDirection = 3;
}
}
- if (R2_GLOBALS._v566A8 == 0)
+ if (R2_GLOBALS._desertStepsRemaining == 0)
scene->_sceneMode = 16;
else
scene->_sceneMode = 11;
@@ -4994,33 +5091,33 @@ void Scene3800::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3800::Exit2::changeScene() {
+void Scene3800::EastExit::changeScene() {
Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->_field412 = 2;
+ scene->_desertDirection = 2;
if (R2_GLOBALS.getFlag(46)) {
- if (scene->_field412 == R2_GLOBALS._v566A9) {
- R2_GLOBALS._v566AA = 4;
- if (R2_GLOBALS._v56A93 + 1 == 0) {
- R2_GLOBALS._v566A8--;
- R2_GLOBALS._v566A9 = 0;
+ if (scene->_desertDirection == R2_GLOBALS._desertCorrectDirection) {
+ R2_GLOBALS._desertPreviousDirection = 4;
+ if (R2_GLOBALS._desertWrongDirCtr + 1 == 0) {
+ R2_GLOBALS._desertStepsRemaining--;
+ R2_GLOBALS._desertCorrectDirection = 0;
} else {
- R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
- R2_GLOBALS._v56A93--;
+ R2_GLOBALS._desertCorrectDirection = R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr];
+ R2_GLOBALS._desertWrongDirCtr--;
}
} else {
- ++R2_GLOBALS._v56A93;
- if (R2_GLOBALS._v56A93 > 999)
- R2_GLOBALS._v56A93 = 999;
- R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
- R2_GLOBALS._v566A9 = 4;
+ ++R2_GLOBALS._desertWrongDirCtr;
+ if (R2_GLOBALS._desertWrongDirCtr > 999)
+ R2_GLOBALS._desertWrongDirCtr = 999;
+ R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr] = R2_GLOBALS._desertCorrectDirection;
+ R2_GLOBALS._desertCorrectDirection = 4;
}
}
- if (R2_GLOBALS._v566A8 == 0)
+ if (R2_GLOBALS._desertStepsRemaining == 0)
scene->_sceneMode = 16;
else
scene->_sceneMode = 12;
@@ -5030,33 +5127,33 @@ void Scene3800::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3800::Exit3::changeScene() {
+void Scene3800::SouthExit::changeScene() {
Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->_field412 = 3;
+ scene->_desertDirection = 3;
if (R2_GLOBALS.getFlag(46)) {
- if (scene->_field412 == R2_GLOBALS._v566A9) {
- R2_GLOBALS._v566AA = 1;
- if (R2_GLOBALS._v56A93 + 1 == 0) {
- R2_GLOBALS._v566A8--;
- R2_GLOBALS._v566A9 = 0;
+ if (scene->_desertDirection == R2_GLOBALS._desertCorrectDirection) {
+ R2_GLOBALS._desertPreviousDirection = 1;
+ if (R2_GLOBALS._desertWrongDirCtr + 1 == 0) {
+ R2_GLOBALS._desertStepsRemaining--;
+ R2_GLOBALS._desertCorrectDirection = 0;
} else {
- R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
- R2_GLOBALS._v56A93--;
+ R2_GLOBALS._desertCorrectDirection = R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr];
+ R2_GLOBALS._desertWrongDirCtr--;
}
} else {
- ++R2_GLOBALS._v56A93;
- if (R2_GLOBALS._v56A93 > 999)
- R2_GLOBALS._v56A93 = 999;
- R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
- R2_GLOBALS._v566A9 = 1;
+ ++R2_GLOBALS._desertWrongDirCtr;
+ if (R2_GLOBALS._desertWrongDirCtr > 999)
+ R2_GLOBALS._desertWrongDirCtr = 999;
+ R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr] = R2_GLOBALS._desertCorrectDirection;
+ R2_GLOBALS._desertCorrectDirection = 1;
}
}
- if (R2_GLOBALS._v566A8 == 0)
+ if (R2_GLOBALS._desertStepsRemaining == 0)
scene->_sceneMode = 16;
else
scene->_sceneMode = 13;
@@ -5066,33 +5163,33 @@ void Scene3800::Exit3::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3800::Exit4::changeScene() {
+void Scene3800::WestExit::changeScene() {
Scene3800 *scene = (Scene3800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- scene->_field412 = 4;
+ scene->_desertDirection = 4;
if (R2_GLOBALS.getFlag(46)) {
- if (scene->_field412 == R2_GLOBALS._v566A9) {
- R2_GLOBALS._v566AA = 2;
- if (R2_GLOBALS._v56A93 + 1 == 0) {
- R2_GLOBALS._v566A8--;
- R2_GLOBALS._v566A9 = 0;
+ if (scene->_desertDirection == R2_GLOBALS._desertCorrectDirection) {
+ R2_GLOBALS._desertPreviousDirection = 2;
+ if (R2_GLOBALS._desertWrongDirCtr + 1 == 0) {
+ R2_GLOBALS._desertStepsRemaining--;
+ R2_GLOBALS._desertCorrectDirection = 0;
} else {
- R2_GLOBALS._v566A9 = R2_GLOBALS._v566AB[R2_GLOBALS._v56A93];
- R2_GLOBALS._v56A93--;
+ R2_GLOBALS._desertCorrectDirection = R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr];
+ R2_GLOBALS._desertWrongDirCtr--;
}
} else {
- ++R2_GLOBALS._v56A93;
- if (R2_GLOBALS._v56A93 > 999)
- R2_GLOBALS._v56A93 = 999;
- R2_GLOBALS._v566AB[R2_GLOBALS._v56A93] = R2_GLOBALS._v566A9;
- R2_GLOBALS._v566A9 = 2;
+ ++R2_GLOBALS._desertWrongDirCtr;
+ if (R2_GLOBALS._desertWrongDirCtr > 999)
+ R2_GLOBALS._desertWrongDirCtr = 999;
+ R2_GLOBALS._desertMovements[R2_GLOBALS._desertWrongDirCtr] = R2_GLOBALS._desertCorrectDirection;
+ R2_GLOBALS._desertCorrectDirection = 2;
}
}
- if (R2_GLOBALS._v566A8 == 0)
+ if (R2_GLOBALS._desertStepsRemaining == 0)
scene->_sceneMode = 16;
else
scene->_sceneMode = 14;
@@ -5102,28 +5199,28 @@ void Scene3800::Exit4::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3800::initScene3800() {
- _exit1._enabled = true;
- _exit2._enabled = true;
- _exit3._enabled = true;
- _exit4._enabled = true;
- _exit1._insideArea = false;
- _exit2._insideArea = false;
- _exit3._insideArea = false;
- _exit4._insideArea = false;
- _exit1._moving = false;
- _exit2._moving = false;
- _exit3._moving = false;
- _exit4._moving = false;
+void Scene3800::initExits() {
+ _northExit._enabled = true;
+ _eastExit._enabled = true;
+ _southExit._enabled = true;
+ _westExit._enabled = true;
+ _northExit._insideArea = false;
+ _eastExit._insideArea = false;
+ _southExit._insideArea = false;
+ _westExit._insideArea = false;
+ _northExit._moving = false;
+ _eastExit._moving = false;
+ _southExit._moving = false;
+ _westExit._moving = false;
- loadScene(R2_GLOBALS._v566A6);
+ loadScene(R2_GLOBALS._maze3800SceneNumb);
R2_GLOBALS._uiElements.draw();
}
-void Scene3800::sub110BBD() {
+void Scene3800::enterArea() {
R2_GLOBALS._player.disableControl();
- switch (_field412) {
+ switch (_desertDirection) {
case 0:
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
@@ -5132,24 +5229,27 @@ void Scene3800::sub110BBD() {
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1.postInit();
- _actor1.fixPriority(10);
- _actor1.changeZoom(-1);
- _actor1.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = this->_field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
+
+ _quinnShadow.postInit();
+ _quinnShadow.fixPriority(10);
+ _quinnShadow.changeZoom(-1);
+ _quinnShadow.setVisage(1110);
+ _quinnShadow._effect = EFFECT_SHADOW_MAP;
+ _quinnShadow._shadowMap = this->_shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_quinnShadow;
+
switch (R2_GLOBALS._sceneManager._previousScene) {
case 2600:
- _object1.postInit();
- _object2.postInit();
- _actor1.hide();
+ _balloon.postInit();
+ _harness.postInit();
+ _quinnShadow.hide();
_sceneMode = 3800;
- setAction(&_sequenceManager1, this, 3800, &R2_GLOBALS._player, &_object1, &_object2, NULL);
+ setAction(&_sequenceManager1, this, 3800, &R2_GLOBALS._player,
+ &_balloon, &_harness, NULL);
break;
case 3900:
_sceneMode = 15;
- switch (R2_GLOBALS._v566AA - 1) {
+ switch (R2_GLOBALS._desertPreviousDirection - 1) {
case 0: {
R2_GLOBALS._player.setPosition(Common::Point(160, 220));
Common::Point pt(160, 160);
@@ -5181,8 +5281,9 @@ void Scene3800::sub110BBD() {
default:
break;
}
+ break;
default:
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
break;
@@ -5224,9 +5325,9 @@ void Scene3800::sub110BBD() {
}
void Scene3800::postInit(SceneObjectList *OwnerList) {
- _field412 = 0;
+ _desertDirection = 0;
- initScene3800();
+ initExits();
SceneExt::postInit();
R2_GLOBALS._sound1.play(231);
@@ -5235,79 +5336,77 @@ void Scene3800::postInit(SceneObjectList *OwnerList) {
setZoomPercents(87, 40, 144, 100);
- _exit1.setDetails(Rect(14, 87, 305, 125), SHADECURSOR_UP, 3800);
- _exit1.setDest(Common::Point(160, 126));
- _exit2.setDetails(Rect(305, 87, 320, 128), EXITCURSOR_E, 3800);
- _exit2.setDest(Common::Point(312, 145));
- _exit3.setDetails(Rect(14, 160, 305, 168), SHADECURSOR_DOWN, 3800);
- _exit3.setDest(Common::Point(160, 165));
- _exit4.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3800);
- _exit4.setDest(Common::Point(7, 145));
+ _northExit.setDetails(Rect(14, 87, 305, 125), SHADECURSOR_UP, 3800);
+ _northExit.setDest(Common::Point(160, 126));
+ _eastExit.setDetails(Rect(305, 87, 320, 168), EXITCURSOR_E, 3800);
+ _eastExit.setDest(Common::Point(312, 145));
+ _southExit.setDetails(Rect(14, 160, 305, 168), SHADECURSOR_DOWN, 3800);
+ _southExit.setDest(Common::Point(160, 165));
+ _westExit.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3800);
+ _westExit.setDest(Common::Point(7, 145));
- _rect1.set(0, 0, 320, 87);
- _item1.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *) NULL);
+ _skylineRect.set(0, 0, 320, 87);
+ _background.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *) NULL);
- sub110BBD();
+ enterArea();
}
void Scene3800::signal() {
switch (_sceneMode) {
case 11:
- R2_GLOBALS._v566A6 += 15;
- if (R2_GLOBALS._v566A6 > 3815)
- R2_GLOBALS._v566A6 -= 20;
- initScene3800();
- sub110BBD();
+ R2_GLOBALS._maze3800SceneNumb += 15;
+ if (R2_GLOBALS._maze3800SceneNumb > 3815)
+ R2_GLOBALS._maze3800SceneNumb -= 20;
+ initExits();
+ enterArea();
break;
case 12:
- R2_GLOBALS._v566A6 += 5;
- if (R2_GLOBALS._v566A6 > 3815)
- R2_GLOBALS._v566A6 = 3800;
- initScene3800();
- sub110BBD();
+ R2_GLOBALS._maze3800SceneNumb += 5;
+ if (R2_GLOBALS._maze3800SceneNumb > 3815)
+ R2_GLOBALS._maze3800SceneNumb = 3800;
+ initExits();
+ enterArea();
break;
case 13:
- R2_GLOBALS._v566A6 -= 15;
- if (R2_GLOBALS._v566A6 < 3800)
- R2_GLOBALS._v566A6 += 20;
- initScene3800();
- sub110BBD();
+ R2_GLOBALS._maze3800SceneNumb -= 15;
+ if (R2_GLOBALS._maze3800SceneNumb < 3800)
+ R2_GLOBALS._maze3800SceneNumb += 20;
+ initExits();
+ enterArea();
break;
case 14:
- R2_GLOBALS._v566A6 -= 5;
- if (R2_GLOBALS._v566A6 < 3800)
- R2_GLOBALS._v566A6 = 3815;
- initScene3800();
- sub110BBD();
+ R2_GLOBALS._maze3800SceneNumb -= 5;
+ if (R2_GLOBALS._maze3800SceneNumb < 3800)
+ R2_GLOBALS._maze3800SceneNumb = 3815;
+ initExits();
+ enterArea();
break;
case 15:
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl();
break;
case 16:
g_globals->_sceneManager.changeScene(3900);
break;
case 3800:
- _actor1.show();
- _object1.remove();
- _object2.remove();
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ _quinnShadow.show();
+ _balloon.remove();
+ _harness.remove();
+ R2_GLOBALS._player.enableControl();
break;
case 3805:
- _exit1._enabled = false;
- _exit2._enabled = false;
- _exit3._enabled = false;
- _exit4._enabled = false;
+ _northExit._enabled = false;
+ _eastExit._enabled = false;
+ _southExit._enabled = false;
+ _westExit._enabled = false;
R2_GLOBALS._player._canWalk = false;
R2_GLOBALS._events.setCursor(CURSOR_USE);
break;
case 3806:
- _exit1._enabled = true;
- _exit2._enabled = true;
- _exit3._enabled = true;
- _exit4._enabled = true;
- R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ _northExit._enabled = true;
+ _eastExit._enabled = true;
+ _southExit._enabled = true;
+ _westExit._enabled = true;
+ R2_GLOBALS._player.enableControl();
break;
default:
break;
@@ -5315,18 +5414,19 @@ 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)
+ && (_skylineRect.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
- case R2_NEGATOR_GUN:
+ case CURSOR_WALK:
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._player.updateAngle(event.mousePos);
break;
- case R2_STEPPING_DISKS:
- SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_LOOK:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
- case R2_ATTRACTOR_UNIT:
- SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_USE:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
event.handled = false;
@@ -5338,17 +5438,18 @@ void Scene3800::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 3900 -
+ * Scene 3900 - Forest Entrance
*
*--------------------------------------------------------------------------*/
-void Scene3900::Exit1::changeScene() {
+
+void Scene3900::NorthExit::changeScene() {
Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A9 = 3;
- R2_GLOBALS._v566AA = 1;
- R2_GLOBALS._v566A8 = 1;
+ R2_GLOBALS._desertCorrectDirection = 3;
+ R2_GLOBALS._desertPreviousDirection = 1;
+ R2_GLOBALS._desertStepsRemaining = 1;
scene->_sceneMode = 14;
Common::Point pt(160, 115);
@@ -5356,14 +5457,14 @@ void Scene3900::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3900::Exit2::changeScene() {
+void Scene3900::EastExit::changeScene() {
Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A9 = 4;
- R2_GLOBALS._v566AA = 2;
- R2_GLOBALS._v566A8 = 1;
+ R2_GLOBALS._desertCorrectDirection = 4;
+ R2_GLOBALS._desertPreviousDirection = 2;
+ R2_GLOBALS._desertStepsRemaining = 1;
scene->_sceneMode = 14;
Common::Point pt(330, 145);
@@ -5371,14 +5472,14 @@ void Scene3900::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3900::Exit3::changeScene() {
+void Scene3900::SouthExit::changeScene() {
Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A9 = 1;
- R2_GLOBALS._v566AA = 3;
- R2_GLOBALS._v566A8 = 1;
+ R2_GLOBALS._desertCorrectDirection = 1;
+ R2_GLOBALS._desertPreviousDirection = 3;
+ R2_GLOBALS._desertStepsRemaining = 1;
scene->_sceneMode = 14;
Common::Point pt(160, 220);
@@ -5386,14 +5487,14 @@ void Scene3900::Exit3::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene3900::Exit4::changeScene() {
+void Scene3900::WestExit::changeScene() {
Scene3900 *scene = (Scene3900 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._v566A9 = 2;
- R2_GLOBALS._v566AA = 4;
- R2_GLOBALS._v566A8 = 1;
+ R2_GLOBALS._desertCorrectDirection = 2;
+ R2_GLOBALS._desertPreviousDirection = 4;
+ R2_GLOBALS._desertStepsRemaining = 1;
scene->_sceneMode = 14;
Common::Point pt(-10, 145);
@@ -5408,7 +5509,7 @@ void Scene3900::Exit5::changeScene() {
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 13;
- if (R2_GLOBALS._v566A9 == 4) {
+ if (R2_GLOBALS._desertCorrectDirection == 4) {
Common::Point pt(-10, 135);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, scene);
@@ -5418,17 +5519,20 @@ void Scene3900::Exit5::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
- R2_GLOBALS._v566A9 = 0;
+ R2_GLOBALS._desertCorrectDirection = 0;
}
void Scene3900::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._v566AA == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700))
+ if ((R2_GLOBALS._desertPreviousDirection == 2)
+ && (R2_GLOBALS._sceneManager._previousScene != 2700))
loadScene(3825);
else
loadScene(3820);
SceneExt::postInit();
+
R2_GLOBALS._sound1.changeSound(231);
setZoomPercents(87, 40, 144, 100);
+
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
@@ -5436,92 +5540,97 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1.postInit();
- _actor1.fixPriority(10);
- _actor1.changeZoom(-1);
- _actor1.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
- if ((R2_GLOBALS._v566AA == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700)) {
+
+ _quinnShadow.postInit();
+ _quinnShadow.fixPriority(10);
+ _quinnShadow.changeZoom(-1);
+ _quinnShadow.setVisage(1110);
+ _quinnShadow._effect = EFFECT_SHADOW_MAP;
+ _quinnShadow._shadowMap = _shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_quinnShadow;
+
+ if ((R2_GLOBALS._desertPreviousDirection == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700)) {
// loadScene(3825);
- R2_GLOBALS._v566AA = 4;
- _exit1.setDetails(Rect(29, 87, 305, 125), SHADECURSOR_UP, 3900);
- _exit3.setDetails(Rect(29, 160, 305, 168), SHADECURSOR_DOWN, 3900);
+ R2_GLOBALS._desertCorrectDirection = 4;
+ _northExit.setDetails(Rect(29, 87, 305, 125), SHADECURSOR_UP, 3900);
+ _southExit.setDetails(Rect(29, 160, 305, 168), SHADECURSOR_DOWN, 3900);
- _exit2.setDetails(Rect(305, 87, 320, 168), EXITCURSOR_E, 3900);
- _exit2.setDest(Common::Point(312, 145));
- _exit2._enabled = true;
- _exit2._insideArea = false;
- _exit2._moving = false;
+ _eastExit.setDetails(Rect(305, 87, 320, 168), EXITCURSOR_E, 3900);
+ _eastExit.setDest(Common::Point(312, 145));
+ _eastExit._enabled = true;
+ _eastExit._insideArea = false;
+ _eastExit._moving = false;
- _exit4._enabled = false;
+ _westExit._enabled = false;
- _exit5.setDetails(Rect(0, 87, 29, 168), EXITCURSOR_W, 3900);
- _exit5.setDest(Common::Point(24, 135));
+ _westEnterForest.setDetails(Rect(0, 87, 29, 168), EXITCURSOR_W, 3900);
+ _westEnterForest.setDest(Common::Point(24, 135));
} else {
// loadScene(3820);
- R2_GLOBALS._v566AA = 2;
- _exit1.setDetails(Rect(14, 87, 290, 125), SHADECURSOR_UP, 3900);
- _exit3.setDetails(Rect(14, 160, 290, 168), SHADECURSOR_DOWN, 3900);
-
+ R2_GLOBALS._desertCorrectDirection = 2;
+ _northExit.setDetails(Rect(14, 87, 290, 125), SHADECURSOR_UP, 3900);
+ _southExit.setDetails(Rect(14, 160, 290, 168), SHADECURSOR_DOWN, 3900);
- _exit2._enabled = false;
+ _eastExit._enabled = false;
- _exit4.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3900);
- _exit4.setDest(Common::Point(7, 145));
- _exit4._enabled = true;
- _exit4._insideArea = false;
- _exit4._moving = false;
+ _westExit.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3900);
+ _westExit.setDest(Common::Point(7, 145));
+ _westExit._enabled = true;
+ _westExit._insideArea = false;
+ _westExit._moving = false;
- _exit5.setDetails(Rect(290, 87, 320, 168), EXITCURSOR_E, 3900);
- _exit5.setDest(Common::Point(295, 135));
+ _westEnterForest.setDetails(Rect(290, 87, 320, 168), EXITCURSOR_E, 3900);
+ _westEnterForest.setDest(Common::Point(295, 135));
}
- _exit5._enabled = true;
- _exit5._insideArea = false;
- _exit5._moving = false;
+ _westEnterForest._enabled = true;
+ _westEnterForest._insideArea = false;
+ _westEnterForest._moving = false;
scalePalette(65, 65, 65);
- _exit1.setDest(Common::Point(160, 126));
- _exit1._enabled = true;
- _exit1._insideArea = false;
- _exit1._moving = false;
+ _northExit.setDest(Common::Point(160, 126));
+ _northExit._enabled = true;
+ _northExit._insideArea = false;
+ _northExit._moving = false;
- _exit3.setDest(Common::Point(160, 165));
- _exit3._enabled = true;
- _exit3._insideArea = false;
- _exit3._moving = false;
+ _southExit.setDest(Common::Point(160, 165));
+ _southExit._enabled = true;
+ _southExit._insideArea = false;
+ _southExit._moving = false;
R2_GLOBALS._uiElements.draw();
- _rect1.set(0, 0, 320, 87);
- _item1.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *)NULL);
+ _skylineRect.set(0, 0, 320, 87);
+ _background.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *)NULL);
if (R2_GLOBALS._sceneManager._previousScene == 3800) {
_sceneMode = 11;
- switch (R2_GLOBALS._v566AA - 1) {
- case 0: {
+ switch (R2_GLOBALS._desertPreviousDirection) {
+ case 1: {
+ // Entering from the north
R2_GLOBALS._player.setPosition(Common::Point(160, 115));
Common::Point pt(160, 120);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
- case 1: {
+ case 2: {
+ // Entering from the east
R2_GLOBALS._player.setPosition(Common::Point(330, 145));
Common::Point pt(300, 145);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
- case 2: {
+ case 3: {
+ // Entering from the south
R2_GLOBALS._player.setPosition(Common::Point(160, 220));
Common::Point pt(160, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
- case 3: {
+ case 4: {
+ // Entering from the west
R2_GLOBALS._player.setPosition(Common::Point(-10, 145));
Common::Point pt(19, 145);
NpcMover *mover = new NpcMover();
@@ -5539,7 +5648,7 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.addMover(mover, &pt, this);
} else {
R2_GLOBALS._player.setPosition(Common::Point(160, 145));
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
}
}
@@ -5548,8 +5657,7 @@ void Scene3900::signal() {
case 11:
// No break on purpose
case 12:
- R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 13:
R2_GLOBALS._sceneManager.changeScene(2700);
@@ -5558,19 +5666,19 @@ void Scene3900::signal() {
R2_GLOBALS._sceneManager.changeScene(3800);
break;
case 3805:
- _exit1._enabled = false;
- _exit2._enabled = false;
- _exit3._enabled = false;
- _exit4._enabled = false;
+ _northExit._enabled = false;
+ _eastExit._enabled = false;
+ _southExit._enabled = false;
+ _westExit._enabled = false;
R2_GLOBALS._player._canWalk = false;
- R2_GLOBALS._events.setCursor(R2_STEPPING_DISKS);
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
break;
case 3806:
- _exit1._enabled = true;
- _exit2._enabled = true;
- _exit3._enabled = true;
- _exit4._enabled = true;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ _northExit._enabled = true;
+ _eastExit._enabled = true;
+ _southExit._enabled = true;
+ _westExit._enabled = true;
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
break;
@@ -5578,18 +5686,19 @@ 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)
+ && (_skylineRect.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
- case R2_NEGATOR_GUN:
+ case CURSOR_WALK:
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._player.updateAngle(event.mousePos);
break;
- case R2_STEPPING_DISKS:
- SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_USE:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
- case R2_ATTRACTOR_UNIT:
- SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_LOOK:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
event.handled = false;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.h b/engines/tsage/ringworld2/ringworld2_scenes3.h
index 44787b9eef..398d09a01e 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.h
@@ -45,16 +45,15 @@ class Scene3100 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
-
- int _field412;
+ bool _fadeSound;
SpeakerGuard _guardSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ NamedHotspot _background;
+ NamedHotspot _hammerHead2;
+ SceneActor _hammerHead;
+ SceneActor _miranda;
+ SceneActor _ghoul;
+ SceneActor _technicians;
+ SceneActor _deadBodies;
Guard _guard;
ASoundExt _sound1;
SequenceManager _sequenceManager;
@@ -68,36 +67,33 @@ public:
};
class Scene3125 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class Background : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item2 : public Item1 {
+ class Table : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item3 : public Item1 {
+ class Computer : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor1 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
public:
-
- int _field412;
- Item1 _item1;
- Actor1 _actor1;
- Item2 _item2;
- Item3 _item3;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SequenceManager _sequenceManager1;
- // Second sequence manager... Unused?
- SequenceManager _sequenceManager2;
+ bool _soundPlayed;
+ Background _background;
+ Door _door;
+ Table _table;
+ Computer _computer;
+ SceneActor _ghoul1;
+ SceneActor _ghoul2;
+ SceneActor _ghoul3;
+ SceneActor _ghoul4;
+ SequenceManager _sequenceManager;
Scene3125();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -107,52 +103,51 @@ public:
};
class Scene3150 : public SceneExt {
- class Item5 : public NamedHotspot {
+ class LightFixture : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item6 : public NamedHotspot {
+ class Toilet : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Water : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class FoodTray : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class ToiletFlush : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class AirVent : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class DoorExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class VentExit : public SceneExit {
public:
virtual void changeScene();
};
public:
-
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Item5 _item5;
- Item6 _item6;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Exit1 _exit1;
- Exit2 _exit2;
+ NamedHotspot _background;
+ NamedHotspot _bed;
+ NamedHotspot _lightFixture2;
+ NamedHotspot _bars;
+ LightFixture _lightFixture;
+ Toilet _toilet;
+ SceneActor _guard;
+ SceneActor _doorBars;
+ SceneActor _bulbOrWire;
+ Water _water;
+ FoodTray _foodTray;
+ ToiletFlush _toiletFlush;
+ AirVent _airVent;
+ DoorExit _doorExit;
+ VentExit _ventExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -161,25 +156,24 @@ public:
};
class Scene3175 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class RoomItem : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor1 : public Actor3 {
+ class Corpse : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
public:
-
- Item1 _item1;
- Item1 _item2;
- Item1 _item3;
- Actor1 _actor1;
- SceneActor _actor2;
- Actor3 _actor3;
+ RoomItem _background;
+ RoomItem _table;
+ RoomItem _autopsies;
+ Door _door;
+ SceneActor _computer;
+ Corpse _corpse;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -191,9 +185,9 @@ public:
SpeakerRocko3200 _rockoSpeaker;
SpeakerJocko3200 _jockoSpeaker;
SpeakerSocko3200 _sockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _rocko;
+ SceneActor _jocko;
+ SceneActor _socko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -204,8 +198,8 @@ class Scene3210 : public SceneExt {
public:
SpeakerCaptain3210 _captainSpeaker;
SpeakerPrivate3210 _privateSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _captain;
+ SceneActor _private;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -216,8 +210,8 @@ class Scene3220 : public SceneExt {
public:
SpeakerRocko3220 _rockoSpeaker;
SpeakerJocko3220 _jockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _rocko;
+ SceneActor _jocko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -228,9 +222,9 @@ class Scene3230 : public SceneExt {
public:
SpeakerRocko3230 _rockoSpeaker;
SpeakerJocko3230 _jockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _rocko;
+ SceneActor _jocko;
+ SceneActor _ghoul;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -242,8 +236,8 @@ public:
SpeakerTeal3240 _tealSpeaker;
SpeakerWebbster3240 _webbsterSpeaker;
SpeakerMiranda _mirandaSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _teal;
+ SceneActor _webbster;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -254,8 +248,8 @@ class Scene3245 : public SceneExt {
public:
SpeakerRalf3245 _ralfSpeaker;
SpeakerTomko3245 _tomkoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _ralf;
+ SceneActor _tomko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -268,22 +262,21 @@ class Scene3250 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
public:
-
- Item _item1;
- Item _item2;
- Item _item3;
- Item _item4;
- Actor _actor1;
- Actor _actor2;
- Actor _actor3;
- Actor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
+ Item _background;
+ Item _tnuctipunShip;
+ Item _floodLights;
+ Item _negator;
+ Door _leftDoor;
+ Door _topDoor;
+ Door _rightDoor;
+ Door _grate;
+ SceneActor _ghoul1;
+ SceneActor _ghoul2;
+ SceneActor _ghoul3;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -293,13 +286,13 @@ public:
class Scene3255 : public SceneExt {
public:
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
+ SceneActor _teal;
+ SceneActor _guard;
+ SceneActor _door;
+ SceneActor _quinn;
+ SceneActor _ghoul1;
+ SceneActor _ghoul2;
+ SceneActor _ghoul3;
SpeakerQuinn3255 _quinnSpeaker;
SpeakerMiranda3255 _mirandaSpeaker;
SequenceManager _sequenceManager;
@@ -310,10 +303,10 @@ public:
};
class Scene3260 : public SceneExt {
- class Actor13 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor14 : public SceneActor {
+ class Toolbox : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
@@ -322,22 +315,21 @@ class Scene3260 : public SceneExt {
void signal();
};
public:
-
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
- SceneActor _actor12;
- Actor13 _actor13;
- Actor14 _actor14;
+ NamedHotspot _background;
+ SceneActor _sceeen1;
+ SceneActor _screen2;
+ SceneActor _screen3;
+ SceneActor _screen4;
+ SceneActor _screen5;
+ SceneActor _screen6;
+ SceneActor _screen7;
+ SceneActor _screen8;
+ SceneActor _screen9;
+ SceneActor _securityConsole;
+ SceneActor _computerConsole;
+ SceneActor _lightingConsole;
+ Door _door;
+ Toolbox _toolbox;
Action1 _action1;
Action1 _action2;
Action1 _action3;
@@ -358,23 +350,23 @@ public:
};
class Scene3275 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class CellExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- SceneActor _actor1;
- Actor2 _actor2;
- Exit1 _exit1;
+ NamedHotspot _background;
+ NamedHotspot _emptyCell1;
+ NamedHotspot _emptyCell2;
+ NamedHotspot _securityBeams1;
+ NamedHotspot _securityBeams2;
+ SceneActor _doorFrame;
+ Door _door;
+ CellExit _cellExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -383,15 +375,15 @@ public:
class Scene3350 : public SceneExt {
public:
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
+ SceneActor _miranda;
+ SceneActor _seeker;
+ SceneActor _webbster;
+ SceneActor _seatedPeople;
+ SceneActor _ship;
+ SceneActor _landedShip;
+ SceneActor _shipShadow;
+ SceneActor _canopy;
+ SceneActor _shipFront;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
@@ -401,53 +393,52 @@ public:
};
class Scene3375 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion1 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Companion2 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Webbster : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class LeftExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class DownExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class RightExit : public SceneExit {
public:
virtual void changeScene();
};
void signalCase3379();
- void subFC696(int sceneMode);
+ void enterArea(int sceneMode);
public:
SpeakerQuinn3375 _quinnSpeaker;
SpeakerSeeker3375 _seekerSpeaker;
SpeakerMiranda3375 _mirandaSpeaker;
SpeakerWebbster3375 _webbsterSpeaker;
- NamedHotspot _item1;
+ NamedHotspot _background;
NamedHotspot _itemArray[13];
- Actor1 _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
+ Companion1 _companion1;
+ Companion2 _companion2;
+ Webbster _webbster;
+ Door _door;
+ LeftExit _leftExit;
+ DownExit _downExit;
+ RightExit _rightExit;
SequenceManager _sequenceManager;
- int _field1488;
- int _field148A[4];
- int _field1492;
+ int _newSceneMode;
+ int _sceneAreas[4];
Scene3375();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -458,20 +449,20 @@ public:
};
class Scene3385 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion1 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Companion2 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Webbster : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -486,16 +477,16 @@ public:
SpeakerSeeker3385 _seekerSpeaker;
SpeakerMiranda3385 _mirandaSpeaker;
SpeakerWebbster3385 _webbsterSpeaker;
- NamedHotspot _item1;
- Actor1 _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Exit1 _exit1;
+ NamedHotspot _background;
+ Companion1 _companion1;
+ Companion2 _companion2;
+ Webbster _webbster;
+ Door _door;
+ SouthExit _southExit;
Action1 _action1;
SequenceManager _sequenceManager;
- int _field11B2;
+ int _playerStrip;
Scene3385();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -505,16 +496,16 @@ public:
};
class Scene3395 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion1 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Companion2 : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Webbster : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Door : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
@@ -528,16 +519,16 @@ public:
SpeakerSeeker3395 _seekerSpeaker;
SpeakerMiranda3395 _mirandaSpeaker;
SpeakerWebbster3395 _webbsterSpeaker;
- NamedHotspot _item1;
+ NamedHotspot _background;
NamedHotspot _itemArray[13];
- Actor1 _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
+ Companion1 _companion1;
+ Companion2 _companion2;
+ Webbster _webbster;
+ Door _door;
Action1 _action1;
SequenceManager _sequenceManager;
- int _field142E;
+ int _playerStrip;
Scene3395();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -553,16 +544,15 @@ public:
SpeakerMiranda3400 _mirandaSpeaker;
SpeakerWebbster3400 _webbsterSpeaker;
SpeakerTeal3400 _tealSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
+ SceneActor _companion1;
+ SceneActor _companion2;
+ SceneActor _webbster;
+ SceneActor _teal;
+ SceneActor _door;
+ SceneActor _manholeCover;
+ SceneActor _sapphire;
SequenceManager _sequenceManager;
- int16 _field157C;
+ bool _soundFaded;
Scene3400();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -574,114 +564,105 @@ public:
class Scene3500 : public SceneExt {
class Action1: public Action {
public:
- int _field1E;
- int _field20;
- int _field22;
- int _field24;
+ int _direction;
+ bool _field20;
+ int _field22; // CHECKME: Useless field
+ bool _field24;
Action1();
virtual void synchronize(Serializer &s);
- void sub108670(int arg1);
- void sub108732(int arg1);
+ void handleHorzButton(int direction);
+ void turnShuttle(bool arg1);
virtual void signal();
virtual void dispatch();
};
class Action2: public Action {
public:
- int _field1E;
+ int _direction;
Action2();
virtual void synchronize(Serializer &s);
- void sub10831F(int arg1);
+ void handleVertButton(int direction);
virtual void signal();
};
- class Item4 : public NamedHotspot {
+ class DirectionButton : public NamedHotspot {
public:
- int _field34;
+ int _movementId;
- Item4();
+ DirectionButton();
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Throttle : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
- int _fieldAA;
- int _fieldAC;
- int _fieldAE;
+ Common::Point _pos;
+ int _deltaX;
+ int _deltaY;
+ int _slideDeltaY;
+ int _deltaMouseY;
- Actor7();
+ Throttle();
virtual void synchronize(Serializer &s);
- void sub109466(int arg1, int arg2, int arg3, int arg4, int arg5);
- void sub1094ED();
- void sub109663(int arg1);
- void sub109693(Common::Point Pt);
+ void init(int xp, int yp, int dx, int dy, int speed);
+ void updateSpeed();
+ void setSpeed(int arg1);
+ void changePosition(const Common::Point &pt);
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
- public:
- // TODO: double check if nothing specific is present, then remove this class
- };
-
- class UnkObject3500 : public UnkObject1200 {
+ class MazeUI3500 : public MazeUI {
public:
- int sub1097C9(int arg1);
- int sub1097EF(int arg1);
- int sub109C09(Common::Point pt);
- int sub109C5E(int &x, int &y);
+ int cellFromX(int arg1);
+ int cellFromY(int arg1);
+ int getCellFromMapXY(Common::Point pt);
+ bool setMazePosition2(Common::Point &p);
};
public:
Action1 _action1;
Action2 _action2;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- Item4 _item4;
- Item4 _item5;
- Item4 _item6;
- Item4 _item7;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- Actor8 _actor9;
+ NamedHotspot _background;
+ NamedHotspot _outsideView;
+ NamedHotspot _mapScreen;
+ DirectionButton _pitchDown;
+ DirectionButton _turnLeft;
+ DirectionButton _pitchUp;
+ DirectionButton _turnRight;
+ // Glyph of vessel on top of the maze ui
+ SceneActor _shuttle;
+ SceneActor _verticalSpeedDisplay;
+ SceneActor _horizontalSpeedDisplay;
+ SceneActor _symbolVertical;
+ SceneActor _symbolLeft;
+ SceneActor _symbolRight;
+ Throttle _throttle;
+ SceneActor _tunnelVertCircle;
+ SceneActor _tunnelHorzCircle;
ASoundExt _aSound1;
- UnkObject3500 _unkObj1;
+ MazeUI3500 _mazeUI;
SequenceManager _sequenceManager;
- int _fieldAF8;
- int _fieldB9E;
+ int _moverVertX;
+ int _moverHorzX;
PaletteRotation *_rotation;
- int _field126E;
- int _field1270;
- int _field1272;
- int _field1274;
- int _field1276;
- int _field1278;
- int _field127A;
- int _field127C;
- int _field127E;
- int _field1280;
- int _field1282;
+ int _mazeChangeAmount;
+ int _speed;
+ bool _field1272;
+ int _mazeDirection;
+ int _nextMove;
+ Common::Point _mazePosition;
+ bool _field1282;
int _field1284;
- int _field1286;
+ bool _directionChangesEnabled;
Scene3500();
- void sub107F71(int arg1);
+ void doMovement(int id);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -694,7 +675,8 @@ public:
class Scene3600 : public SceneExt {
class Action3600: public ActionExt {
public:
- int _field1E, _field20;
+ bool _field1E;
+ int _fadePct;
Action3600();
virtual void synchronize(Serializer &s);
@@ -705,12 +687,12 @@ class Scene3600 : public SceneExt {
virtual void signal();
};
- class Item5 : public NamedHotspot {
+ class LightShaft : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor13 : public SceneActorExt {
+ class Protector : public SceneActorExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
@@ -721,35 +703,30 @@ public:
SpeakerMiranda3600 _mirandaSpeaker;
SpeakerTeal3600 _tealSpeaker;
SpeakerProtector3600 _protectorSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Item5 _item5;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
- SceneActor _actor12;
- Actor13 _actor13;
+ NamedHotspot _background;
+ NamedHotspot _console;
+ NamedHotspot _tapestry1;
+ NamedHotspot _tapestry2;
+ LightShaft _lightShaft;
+ SceneActor _protector3400;
+ SceneActor _steppingDisk;
+ SceneActor _consoleLights;
+ SceneActor _webbster;
+ SceneActor _teal;
+ SceneActor _door3400;
+ SceneActor _quinn;
+ SceneActor _seeker;
+ SceneActor _miranda;
+ Protector _protector;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
SequenceManager _sequenceManager4;
ScenePalette _palette1;
- int _field2548;
- int _field254A;
- int _field254C;
- int _field254E;
- bool _field2550;
+ bool _tealDead;
+ bool _lightEntered;
+ bool _ghoulTeleported;
Scene3600();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -765,11 +742,11 @@ public:
SpeakerQuinn3700 _quinnSpeaker;
SpeakerSeeker3700 _seekerSpeaker;
SpeakerMiranda3700 _mirandaSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ SceneActor _quinn;
+ SceneActor _seeker;
+ SceneActor _miranda;
+ SceneActor _webbster;
+ SceneActor _teleportPad;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -778,43 +755,43 @@ public:
};
class Scene3800 : public SceneExt {
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- SceneObject _object1;
- SceneObject _object2;
- SceneActor _actor1;
- NamedHotspot _item1;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
- Rect _rect1;
+ SceneObject _balloon;
+ SceneObject _harness;
+ SceneActor _quinnShadow;
+ NamedHotspot _background;
+ NorthExit _northExit;
+ EastExit _eastExit;
+ SouthExit _southExit;
+ WestExit _westExit;
+ Rect _skylineRect;
SequenceManager _sequenceManager1;
- int _field412;
+ int _desertDirection;
Scene3800();
- void initScene3800();
- void sub110BBD();
+ void initExits();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -823,22 +800,22 @@ public:
};
class Scene3900 : public SceneExt {
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -848,14 +825,14 @@ class Scene3900 : public SceneExt {
virtual void changeScene();
};
public:
- SceneActor _actor1;
- NamedHotspot _item1;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
- Exit5 _exit5;
- Rect _rect1;
+ SceneActor _quinnShadow;
+ NamedHotspot _background;
+ NorthExit _northExit;
+ EastExit _eastExit;
+ SouthExit _southExit;
+ WestExit _westExit;
+ Exit5 _westEnterForest;
+ Rect _skylineRect;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
index da1449efdf..675511ac10 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.cpp
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -36,40 +36,131 @@ namespace Ringworld2 {
VisualSpeaker::VisualSpeaker(): Speaker() {
_delayAmount = 0;
+ _voiceDelayAmount = 0;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
_color1 = 8;
_color2 = 0;
_displayMode = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
+
+ _object2 = nullptr;
+ _fieldF8 = 0;
+ _soundId = 0;
+ _removeObject = false;
+ _numFrames = 0;
+ _voiceFrameNumber = 0;
}
void VisualSpeaker::remove() {
+ _numFrames = 0;
+ _delayAmount = 0;
+ R2_GLOBALS._playStream.stop();
+
if (_object2) {
if (_fieldF8) {
_fieldF8 = 0;
_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: Handle _field18 if used in Action. It looks only used in the original in remove()
+ // _action->_field18 = 1;
+ if (_speakerMode == 0xff)
+ stopSpeaking();
+
+ _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) {
+ setVoiceFrame(1);
+ }
+ } else if (_action && _object2) {
+ _action->setDelay(1);
+ _sceneText.remove();
+
+ R2_GLOBALS._playStream.stop();
+ }
+}
+
+void VisualSpeaker::dispatch() {
+ uint32 frameNumber = R2_GLOBALS._events.getFrameNumber();
+ assert(_action);
+
+ // 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 (_voiceDelayAmount) {
+ if (frameNumber >= _voiceFrameNumber) {
+ _voiceDelayAmount = _voiceDelayAmount - (frameNumber - _voiceFrameNumber);
+ _voiceFrameNumber = frameNumber;
+
+ if (_voiceDelayAmount <= 0) {
+ _voiceDelayAmount = 0;
+ if (R2_GLOBALS._playStream.play(_soundId, NULL)) {
+ _numFrames = 2;
+ _soundId = 0;
+ } else {
+ _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)) {
+ // Don't bother waiting for a mouse click to start the next speech segment
+ _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(_voiceDelayAmount);
+ s.syncAsUint32LE(_voiceFrameNumber);
}
void VisualSpeaker::setText(const Common::String &msg) {
@@ -127,13 +218,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,25 +249,29 @@ 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 {
if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) {
- if (!R2_GLOBALS._playStream.play(_soundId, NULL))
+ if (!R2_GLOBALS._playStream.play(_soundId, NULL)) {
+ // Couldn't play voice, so fall back on showing text
_sceneText.show();
+ } else {
+ _numFrames = 2;
+ _soundId = 0;
+ }
}
}
}
-void VisualSpeaker::proc16() {
+void VisualSpeaker::stopSpeaking() {
R2_GLOBALS._playStream.stop();
- _fieldF6 = 0;
+ _speakerMode = 0;
_object1.remove();
- assert(_object2);
- _object2->show();
+ if (_object2)
+ _object2->show();
_object2 = NULL;
_fieldF8 = 0;
}
@@ -187,6 +281,11 @@ void VisualSpeaker::setFrame(int numFrames) {
_frameNumber = R2_GLOBALS._events.getFrameNumber();
}
+void VisualSpeaker::setVoiceFrame(int numFrames) {
+ _voiceDelayAmount = numFrames;
+ _voiceFrameNumber = R2_GLOBALS._events.getFrameNumber();
+}
+
void VisualSpeaker::setDelay(int delay) {
_delayAmount = delay;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
@@ -211,7 +310,7 @@ SpeakerCaptain3210::SpeakerCaptain3210() {
_speakerName = "Captain";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -219,12 +318,12 @@ SpeakerCaptain3210::SpeakerCaptain3210() {
_numFrames = 0;
}
-void SpeakerCaptain3210::proc15() {
- int v = _fieldF6;
+void SpeakerCaptain3210::animateSpeaker() {
+ int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_captain;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -250,7 +349,7 @@ SpeakerCaretaker2450::SpeakerCaretaker2450() {
_speakerName = "CARETAKER";
_color1 = 43;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -266,7 +365,7 @@ SpeakerChief1100::SpeakerChief1100() {
_speakerName = "CHIEF";
_color1 = 8;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -274,12 +373,12 @@ SpeakerChief1100::SpeakerChief1100() {
_numFrames = 0;
}
-void SpeakerChief1100::proc15() {
- int v = _fieldF6;
+void SpeakerChief1100::animateSpeaker() {
+ 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 +423,7 @@ SpeakerGuard::SpeakerGuard() {
_speakerName = "GUARD";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -332,12 +431,12 @@ SpeakerGuard::SpeakerGuard() {
_numFrames = 0;
}
-void SpeakerGuard2800::proc15() {
- int v = _fieldF6;
- Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+void SpeakerGuard2800::animateSpeaker() {
+ int v = _speakerMode;
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_guard;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -364,7 +463,7 @@ SpeakerJocko::SpeakerJocko() {
_speakerName = "Jocko";
_color1 = 45;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -372,12 +471,12 @@ SpeakerJocko::SpeakerJocko() {
_numFrames = 0;
}
-void SpeakerJocko3200::proc15() {
- int v = _fieldF6;
+void SpeakerJocko3200::animateSpeaker() {
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -395,12 +494,12 @@ void SpeakerJocko3200::proc15() {
}
}
-void SpeakerJocko3220::proc15() {
- int v = _fieldF6;
+void SpeakerJocko3220::animateSpeaker() {
+ int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -418,12 +517,12 @@ void SpeakerJocko3220::proc15() {
}
}
-void SpeakerJocko3230::proc15() {
- int v = _fieldF6;
+void SpeakerJocko3230::animateSpeaker() {
+ int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -449,7 +548,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
_speakerName = "MIRANDA";
_color1 = 154;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -457,11 +556,11 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerMiranda300::proc15() {
- int v = _fieldF6;
+void SpeakerMiranda300::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
_object2 = &R2_GLOBALS._player;
} else {
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
@@ -497,12 +596,12 @@ void SpeakerMiranda300::proc15() {
}
}
-void SpeakerMiranda1625::proc15() {
- int v = _fieldF6;
+void SpeakerMiranda1625::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor3;
+ _object2 = &scene->_mirandaMouth;
_object2->hide();
_object1.postInit();
_object1.setPosition(Common::Point(196, 65));
@@ -520,8 +619,8 @@ void SpeakerMiranda1625::proc15() {
}
}
-void SpeakerMiranda3255::proc15() {
- int v = _fieldF6;
+void SpeakerMiranda3255::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -541,25 +640,25 @@ void SpeakerMiranda3255::proc15() {
}
}
-void SpeakerMiranda3375::proc15() {
+void SpeakerMiranda3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
- if (scene->_actor1._position.y != 163)
+ if (scene->_companion1._position.y != 163)
R2_GLOBALS._player.setStrip(8);
else
R2_GLOBALS._player.setStrip(2);
@@ -591,22 +690,22 @@ void SpeakerMiranda3375::proc15() {
}
}
-void SpeakerMiranda3385::proc15() {
+void SpeakerMiranda3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -640,22 +739,22 @@ void SpeakerMiranda3385::proc15() {
}
}
-void SpeakerMiranda3395::proc15() {
+void SpeakerMiranda3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -690,22 +789,22 @@ void SpeakerMiranda3395::proc15() {
}
}
-void SpeakerMiranda3400::proc15() {
+void SpeakerMiranda3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -721,12 +820,12 @@ void SpeakerMiranda3400::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4051, 5, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4050, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -734,22 +833,22 @@ void SpeakerMiranda3400::proc15() {
}
}
-void SpeakerMiranda3600::proc15() {
+void SpeakerMiranda3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor12;
+ _object2 = &scene->_miranda;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -780,13 +879,13 @@ void SpeakerMiranda3600::proc15() {
}
}
-void SpeakerMiranda3700::proc15() {
+void SpeakerMiranda3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_miranda;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -806,25 +905,25 @@ void SpeakerMiranda3700::proc15() {
break;
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 6, 1);
- scene->_actor2.setup(20, 5, 1);
+ scene->_quinn.setup(10, 6, 1);
+ scene->_seeker.setup(20, 5, 1);
_object2->setup(30, 1, 1);
- scene->_actor4.setup(40, 1, 1);
+ scene->_webbster.setup(40, 1, 1);
_object1.setup(4050, 5, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor3.setup(30, 8, 1);
+ scene->_miranda.setup(30, 8, 1);
_object1.setup(4052, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4051, 7, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -840,7 +939,7 @@ SpeakerNej::SpeakerNej() {
_speakerName = "NEJ";
_color1 = 171;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -848,12 +947,12 @@ SpeakerNej::SpeakerNej() {
_numFrames = 0;
}
-void SpeakerNej2700::proc15() {
- int v = _fieldF6;
+void SpeakerNej2700::animateSpeaker() {
+ int v = _speakerMode;
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_nej;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -883,12 +982,12 @@ void SpeakerNej2700::proc15() {
}
}
-void SpeakerNej2750::proc15() {
- int v = _fieldF6;
+void SpeakerNej2750::animateSpeaker() {
+ int v = _speakerMode;
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_nej;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -915,12 +1014,12 @@ void SpeakerNej2750::proc15() {
}
}
-void SpeakerNej2800::proc15() {
- int v = _fieldF6;
- Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+void SpeakerNej2800::animateSpeaker() {
+ int v = _speakerMode;
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_nej;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -948,7 +1047,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
_speakerName = "PHARISHA";
_color1 = 151;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -956,12 +1055,12 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerPharisha2435::proc15() {
- int v = _fieldF6;
+void SpeakerPharisha2435::animateSpeaker() {
+ int v = _speakerMode;
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_astor;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -984,7 +1083,7 @@ SpeakerPrivate3210::SpeakerPrivate3210() {
_speakerName = "Private";
_color1 = 45;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -992,12 +1091,12 @@ SpeakerPrivate3210::SpeakerPrivate3210() {
_numFrames = 0;
}
-void SpeakerPrivate3210::proc15() {
- int v = _fieldF6;
+void SpeakerPrivate3210::animateSpeaker() {
+ int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_private;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1023,7 +1122,7 @@ SpeakerProtector3600::SpeakerProtector3600() {
_speakerName = "Protector";
_color1 = 170;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1031,17 +1130,17 @@ SpeakerProtector3600::SpeakerProtector3600() {
_numFrames = 0;
}
-void SpeakerProtector3600::proc15() {
- int v = _fieldF6;
+void SpeakerProtector3600::animateSpeaker() {
+ int v = _speakerMode;
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor13;
+ _object2 = &scene->_protector;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
@@ -1084,7 +1183,7 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
_speakerName = "QUINN";
_color1 = 60;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1092,13 +1191,14 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerQuinn300::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn300::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 3) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_quinn;
}
@@ -1106,9 +1206,6 @@ void SpeakerQuinn300::proc15() {
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
-
- if (_object2->_mover)
- _object2->addMover(NULL);
}
if (v == 0) {
@@ -1133,24 +1230,72 @@ void SpeakerQuinn300::proc15() {
case 308:
_object1.setup(308, 5, 1);
break;
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
+void SpeakerQuinn500::animateSpeaker() {
+ 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;
+void SpeakerQuinn1100::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
if (v == 0)
return;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_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();
@@ -1187,15 +1332,16 @@ void SpeakerQuinn1100::proc15() {
}
}
-void SpeakerQuinn2435::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn2435::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -1213,15 +1359,16 @@ void SpeakerQuinn2435::proc15() {
}
}
-void SpeakerQuinn2450::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn2450::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -1241,8 +1388,8 @@ void SpeakerQuinn2450::proc15() {
}
}
-void SpeakerQuinn2700::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn2700::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1272,8 +1419,8 @@ void SpeakerQuinn2700::proc15() {
}
}
-void SpeakerQuinn2750::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn2750::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1294,7 +1441,7 @@ void SpeakerQuinn2750::proc15() {
_object1.setup(4022, 5, 1);
break;
case 2752:
- _object1.setup(2752, 1, 1);
+ _object1.setup(2752, 3, 1);
break;
default:
break;
@@ -1303,8 +1450,8 @@ void SpeakerQuinn2750::proc15() {
}
}
-void SpeakerQuinn2800::proc15() {
- int v = _fieldF6;
+void SpeakerQuinn2800::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
_object2 = &R2_GLOBALS._player;
@@ -1342,13 +1489,13 @@ void SpeakerQuinn2800::proc15() {
}
}
-void SpeakerQuinn3255::proc15() {
+void SpeakerQuinn3255::animateSpeaker() {
Scene3255 *scene = (Scene3255 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor4;
+ _object2 = &scene->_quinn;
_object2->hide();
_object1.postInit();
_object1._effect = _object2->_effect;
@@ -1365,27 +1512,27 @@ void SpeakerQuinn3255::proc15() {
}
}
-void SpeakerQuinn3375::proc15() {
+void SpeakerQuinn3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
- else if (R2_GLOBALS._player._characterIndex == 2)
- _object2 = &scene->_actor1;
+ else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _object2 = &scene->_companion1;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
- if (scene->_actor1._position.y != 163)
+ if (scene->_companion1._position.y != 163)
R2_GLOBALS._player.setStrip(8);
else
R2_GLOBALS._player.setStrip(2);
@@ -1416,24 +1563,24 @@ void SpeakerQuinn3375::proc15() {
}
}
-void SpeakerQuinn3385::proc15() {
+void SpeakerQuinn3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
- else if (R2_GLOBALS._player._characterIndex == 2)
- _object2 = &scene->_actor1;
+ else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _object2 = &scene->_companion1;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -1458,7 +1605,7 @@ void SpeakerQuinn3385::proc15() {
break;
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object1.setup(4010, 3, 1);
else
_object1.setup(4010, 5, 1);
@@ -1471,24 +1618,24 @@ void SpeakerQuinn3385::proc15() {
}
}
-void SpeakerQuinn3395::proc15() {
+void SpeakerQuinn3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
- else if (R2_GLOBALS._player._characterIndex == 2)
- _object2 = &scene->_actor1;
+ else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _object2 = &scene->_companion1;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -1513,7 +1660,7 @@ void SpeakerQuinn3395::proc15() {
break;
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object1.setup(4010, 3, 1);
else
_object1.setup(4010, 5, 1);
@@ -1526,24 +1673,24 @@ void SpeakerQuinn3395::proc15() {
}
}
-void SpeakerQuinn3400::proc15() {
+void SpeakerQuinn3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
- else if (R2_GLOBALS._player._characterIndex == 2)
- _object2 = &scene->_actor1;
+ else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
+ _object2 = &scene->_companion1;
else
- _object2 = &scene->_actor2;
+ _object2 = &scene->_companion2;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
if (_object2->_mover)
@@ -1562,12 +1709,12 @@ void SpeakerQuinn3400::proc15() {
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4010, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4012, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -1575,21 +1722,21 @@ void SpeakerQuinn3400::proc15() {
}
}
-void SpeakerQuinn3600::proc15() {
+void SpeakerQuinn3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor10;
+ _object2 = &scene->_quinn;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -1626,28 +1773,28 @@ 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);
+ scene->_miranda.setup(30, 1, 1);
R2_GLOBALS._sound2.play(44);
break;
case 3:
- scene->_actor3.setup(30, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
break;
default:
- scene->_actor3.setup(30, 7, 1);
+ scene->_miranda.setup(30, 7, 1);
break;
}
VisualSpeaker::setText(msg);
}
-void SpeakerQuinn3700::proc15() {
+void SpeakerQuinn3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_quinn;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1668,24 +1815,24 @@ void SpeakerQuinn3700::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
R2_GLOBALS._sound2.stop();
- scene->_actor1.setup(10, 4, 1);
- scene->_actor3.setup(30, 7, 1);
+ scene->_quinn.setup(10, 4, 1);
+ scene->_miranda.setup(30, 7, 1);
_object1.setup(3701, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
- _object1.setup(3701, 2, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
+ _object1.setup(3702, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 2, 1);
- scene->_actor3.setup(30, 1, 1);
+ scene->_quinn.setup(10, 2, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4011, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -1697,17 +1844,8 @@ void SpeakerQuinn3700::proc15() {
// Classes related to QUINNL
//----------------------------------------------------------------------------
-SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() {
+SpeakerQuinnL::SpeakerQuinnL(): SpeakerQuinn() {
_speakerName = "QUINNL";
- _color1 = 35;
- _color2 = 0;
- _fieldF6 = 0;
- _textWidth = 300;
- _hideObjects = false;
- _object2 = NULL;
- _displayMode = 1;
- _numFrames = 0;
- _fontNumber = 10;
}
//----------------------------------------------------------------------------
@@ -1718,7 +1856,7 @@ SpeakerRalf3245::SpeakerRalf3245() {
_speakerName = "Ralf";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1726,12 +1864,12 @@ SpeakerRalf3245::SpeakerRalf3245() {
_numFrames = 0;
}
-void SpeakerRalf3245::proc15() {
- int v = _fieldF6;
+void SpeakerRalf3245::animateSpeaker() {
+ int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_ralf;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1770,7 +1908,7 @@ SpeakerRocko::SpeakerRocko() {
_speakerName = "Rocko";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1778,12 +1916,12 @@ SpeakerRocko::SpeakerRocko() {
_numFrames = 0;
}
-void SpeakerRocko3200::proc15() {
- int v = _fieldF6;
+void SpeakerRocko3200::animateSpeaker() {
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1801,12 +1939,12 @@ void SpeakerRocko3200::proc15() {
}
}
-void SpeakerRocko3220::proc15() {
- int v = _fieldF6;
+void SpeakerRocko3220::animateSpeaker() {
+ int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1824,12 +1962,12 @@ void SpeakerRocko3220::proc15() {
}
}
-void SpeakerRocko3230::proc15() {
- int v = _fieldF6;
+void SpeakerRocko3230::animateSpeaker() {
+ int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1855,7 +1993,7 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
_speakerName = "SEEKER";
_color1 = 35;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -1863,13 +2001,13 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerSeeker300::proc15() {
- int v = _fieldF6;
+void SpeakerSeeker300::animateSpeaker() {
+ 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,18 +2037,56 @@ void SpeakerSeeker300::proc15() {
}
}
-void SpeakerSeeker1100::proc15() {
- int v = _fieldF6;
+void SpeakerSeeker500::animateSpeaker() {
+ 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::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
if (v == 0)
return;
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_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();
@@ -1958,15 +2134,16 @@ void SpeakerSeeker1100::proc15() {
}
}
-void SpeakerSeeker1900::proc15() {
- int v = _fieldF6;
+void SpeakerSeeker1900::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1900);
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -1988,15 +2165,16 @@ void SpeakerSeeker1900::proc15() {
}
}
-void SpeakerSeeker2435::proc15() {
- int v = _fieldF6;
+void SpeakerSeeker2435::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -2014,15 +2192,16 @@ void SpeakerSeeker2435::proc15() {
}
}
-void SpeakerSeeker2450::proc15() {
- int v = _fieldF6;
+void SpeakerSeeker2450::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2450);
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -2039,25 +2218,25 @@ void SpeakerSeeker2450::proc15() {
}
}
-void SpeakerSeeker3375::proc15() {
+void SpeakerSeeker3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion1;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
- if (scene->_actor1._position.y != 163)
+ if (scene->_companion1._position.y != 163)
R2_GLOBALS._player.setStrip(8);
else
R2_GLOBALS._player.setStrip(2);
@@ -2088,22 +2267,22 @@ void SpeakerSeeker3375::proc15() {
}
}
-void SpeakerSeeker3385::proc15() {
+void SpeakerSeeker3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion1;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -2137,22 +2316,22 @@ void SpeakerSeeker3385::proc15() {
}
}
-void SpeakerSeeker3395::proc15() {
+void SpeakerSeeker3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion1;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2186,22 +2365,22 @@ void SpeakerSeeker3395::proc15() {
}
}
-void SpeakerSeeker3400::proc15() {
+void SpeakerSeeker3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion1;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2217,27 +2396,27 @@ void SpeakerSeeker3400::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4031, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4031, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4030, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 4:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4031, 7, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 5:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4033, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -2245,22 +2424,22 @@ void SpeakerSeeker3400::proc15() {
}
}
-void SpeakerSeeker3600::proc15() {
+void SpeakerSeeker3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2)
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor11;
+ _object2 = &scene->_seeker;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2295,22 +2474,23 @@ 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);
+ scene->_miranda.setup(30, 8, 1);
} else {
- scene->_actor3.setup(30, 2, 1);
+ scene->_miranda.setup(30, 2, 1);
}
+
VisualSpeaker::setText(msg);
}
-void SpeakerSeeker3700::proc15() {
+void SpeakerSeeker3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_seeker;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2331,19 +2511,19 @@ void SpeakerSeeker3700::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
R2_GLOBALS._sound2.stop();
- scene->_actor1.setup(10, 8, 1);
- scene->_actor2.setup(20, 7, 1);
- scene->_actor3.setup(30, 8, 1);
+ scene->_quinn.setup(10, 8, 1);
+ scene->_seeker.setup(20, 7, 1);
+ scene->_miranda.setup(30, 8, 1);
_object1.setup(3701, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 2, 1);
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
+ scene->_quinn.setup(10, 2, 1);
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4031, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -2355,17 +2535,8 @@ void SpeakerSeeker3700::proc15() {
// Classes related to SEEKERL
//----------------------------------------------------------------------------
-SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() {
+SpeakerSeekerL::SpeakerSeekerL(): SpeakerSeeker() {
_speakerName = "SEEKERL";
- _color1 = 35;
- _color2 = 0;
- _fieldF6 = 0;
- _textWidth = 300;
- _hideObjects = false;
- _object2 = NULL;
- _displayMode = 1;
- _numFrames = 0;
- _fontNumber = 10;
}
//----------------------------------------------------------------------------
@@ -2376,7 +2547,7 @@ SpeakerSocko3200::SpeakerSocko3200() {
_speakerName = "Socko";
_color1 = 10;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2384,12 +2555,12 @@ SpeakerSocko3200::SpeakerSocko3200() {
_numFrames = 0;
}
-void SpeakerSocko3200::proc15() {
- int v = _fieldF6;
+void SpeakerSocko3200::animateSpeaker() {
+ int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_socko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2411,11 +2582,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;
@@ -2423,8 +2594,8 @@ SpeakerSoldier::SpeakerSoldier(int colour) {
_numFrames = 0;
}
-void SpeakerSoldier300::proc15() {
- int v = _fieldF6;
+void SpeakerSoldier300::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
@@ -2455,7 +2626,7 @@ SpeakerTeal::SpeakerTeal(): VisualSpeaker() {
_speakerName = "TEAL";
_color1 = 22;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2467,8 +2638,43 @@ SpeakerTealMode7::SpeakerTealMode7(): SpeakerTeal() {
_displayMode = 7;
}
-void SpeakerTeal300::proc15() {
- int v = _fieldF6;
+void SpeakerTeal180::animateSpeaker() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_teal;
+ _object2->hide();
+
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(75, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(77, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerTeal300::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
@@ -2491,12 +2697,12 @@ void SpeakerTeal300::proc15() {
}
}
-void SpeakerTeal1625::proc15() {
- int v = _fieldF6;
+void SpeakerTeal1625::animateSpeaker() {
+ int v = _speakerMode;
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor2;
+ _object2 = &scene->_tealHead;
_object2->hide();
_object1.postInit();
@@ -2515,12 +2721,12 @@ void SpeakerTeal1625::proc15() {
}
}
-void SpeakerTeal3240::proc15() {
- int v = _fieldF6;
+void SpeakerTeal3240::animateSpeaker() {
+ int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_teal;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2538,17 +2744,17 @@ void SpeakerTeal3240::proc15() {
}
}
-void SpeakerTeal3400::proc15() {
+void SpeakerTeal3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor4;
+ _object2 = &scene->_teal;
_object2->hide();
_object1.postInit();
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2561,8 +2767,8 @@ void SpeakerTeal3400::proc15() {
if (scene ->_sceneMode == 3305) {
R2_GLOBALS._player.setStrip(6);
- scene->_actor1.setStrip(6);
- scene->_actor2.setStrip(6);
+ scene->_companion1.setStrip(6);
+ scene->_companion2.setStrip(6);
}
switch (v) {
@@ -2572,22 +2778,22 @@ void SpeakerTeal3400::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4107, 5, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4107, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4107, 7, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 4:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4107, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -2595,18 +2801,18 @@ void SpeakerTeal3400::proc15() {
}
}
-void SpeakerTeal3600::proc15() {
+void SpeakerTeal3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor5;
+ _object2 = &scene->_teal;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2659,7 +2865,7 @@ SpeakerTomko3245::SpeakerTomko3245() {
_speakerName = "Tomko";
_color1 = 10;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2667,12 +2873,12 @@ SpeakerTomko3245::SpeakerTomko3245() {
_numFrames = 0;
}
-void SpeakerTomko3245::proc15() {
- int v = _fieldF6;
+void SpeakerTomko3245::animateSpeaker() {
+ int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_tomko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2707,11 +2913,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;
@@ -2719,12 +2925,53 @@ SpeakerWebbster::SpeakerWebbster(int colour) {
_numFrames = 0;
}
-void SpeakerWebbster3240::proc15() {
- int v = _fieldF6;
+void SpeakerWebbster180::animateSpeaker() {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _speakerMode;
+
+ if (!_object2) {
+ _object2 = &scene->_webbster;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 6;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(75, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(76, 4, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+ _object1.setup(76, 6, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerWebbster3240::animateSpeaker() {
+ int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2742,21 +2989,21 @@ void SpeakerWebbster3240::proc15() {
}
}
-void SpeakerWebbster3375::proc15() {
+void SpeakerWebbster3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
- if (scene->_actor1._position.y != 163)
+ if (scene->_companion1._position.y != 163)
R2_GLOBALS._player.setStrip(8);
else
R2_GLOBALS._player.setStrip(2);
@@ -2786,18 +3033,18 @@ void SpeakerWebbster3375::proc15() {
}
}
-void SpeakerWebbster3385::proc15() {
+void SpeakerWebbster3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -2830,18 +3077,18 @@ void SpeakerWebbster3385::proc15() {
}
}
-void SpeakerWebbster3395::proc15() {
+void SpeakerWebbster3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2874,18 +3121,18 @@ void SpeakerWebbster3395::proc15() {
}
}
-void SpeakerWebbster3400::proc15() {
+void SpeakerWebbster3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2901,17 +3148,17 @@ void SpeakerWebbster3400::proc15() {
case 1:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4110, 5, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4110, 7, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
((SceneItem *)_action)->_sceneRegionId = 0;
_object1.setup(4110, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -2921,11 +3168,11 @@ void SpeakerWebbster3400::proc15() {
//----------------------------------------------------------------------------
-SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
+SpeakerDutyOfficer180::SpeakerDutyOfficer180(): VisualSpeaker() {
_speakerName = "DUTYOFFICER";
_color1 = 5;
_color2 = 0;
- _fieldF6 = 0;
+ _speakerMode = 0;
_textWidth = 300;
_hideObjects = false;
_object2 = NULL;
@@ -2933,13 +3180,13 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerDutyOfficer::proc15() {
+void SpeakerDutyOfficer180::animateSpeaker() {
Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
- int v = _fieldF6;
+ int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_object2;
+ _object2 = &scene->_dutyOfficer;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2953,7 +3200,7 @@ void SpeakerDutyOfficer::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- _action = NULL;
+ _action->_action = NULL;
_object1.setup(76, 2, 1);
_object1.animate(ANIM_MODE_5, this);
break;
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
index fa2946d56c..d70652ff97 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.h
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -41,24 +41,30 @@ 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 _voiceDelayAmount;
+ uint32 _voiceFrameNumber;
private:
void setFrame(int numFrames);
+ void setVoiceFrame(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();
+ virtual void animateSpeaker() {}
+ virtual void stopSpeaking();
void setDelay(int delay);
};
@@ -77,7 +83,7 @@ public:
SpeakerCaptain3210();
virtual Common::String getClassName() { return "SpeakerCaptain3210"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Caretaker
@@ -96,7 +102,7 @@ public:
SpeakerChief1100();
virtual Common::String getClassName() { return "SpeakerChief1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Guard
@@ -110,7 +116,7 @@ public:
class SpeakerGuard2800 : public SpeakerGuard {
public:
virtual Common::String getClassName() { return "SpeakerGuard2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Jocko
@@ -124,19 +130,19 @@ public:
class SpeakerJocko3200 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerJocko3220 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3220"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerJocko3230 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3230"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Miranda
@@ -150,55 +156,55 @@ public:
class SpeakerMiranda300 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda1625 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda1625"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3255 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3255"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3375 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3385 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3395 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3400 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3600 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3700 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Nej
@@ -212,19 +218,19 @@ public:
class SpeakerNej2700 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerNej2750 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2750"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerNej2800 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Pharisha
@@ -239,7 +245,7 @@ public:
class SpeakerPharisha2435 : public SpeakerPharisha {
public:
virtual Common::String getClassName() { return "SpeakerPharisha2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Private
@@ -249,7 +255,7 @@ public:
SpeakerPrivate3210();
virtual Common::String getClassName() { return "SpeakerPrivate3210"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Protector
@@ -259,7 +265,7 @@ public:
SpeakerProtector3600();
virtual Common::String getClassName() { return "SpeakerProtector3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Quinn
@@ -273,91 +279,97 @@ public:
class SpeakerQuinn300 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
+};
+
+class SpeakerQuinn500 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn500"; }
+ virtual void animateSpeaker();
};
class SpeakerQuinn1100 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2435 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2450 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2450"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2700 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2750 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2750"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2800 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3255 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3255"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3375 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3385 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3395 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3400 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3600 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3700 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3700"; }
virtual void setText(const Common::String &msg);
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to QuinnL
-class SpeakerQuinnL : public VisualSpeaker {
+class SpeakerQuinnL : public SpeakerQuinn {
public:
SpeakerQuinnL();
@@ -371,7 +383,7 @@ public:
SpeakerRalf3245();
virtual Common::String getClassName() { return "SpeakerRalf3245"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Rocko
@@ -385,19 +397,19 @@ public:
class SpeakerRocko3200 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerRocko3220 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3220"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerRocko3230 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3230"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Seeker
@@ -411,73 +423,79 @@ public:
class SpeakerSeeker300 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
+};
+
+class SpeakerSeeker500 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker500"; }
+ virtual void animateSpeaker();
};
class SpeakerSeeker1100 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker1900 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1900"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker2435 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker2450 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker2450"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3375 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3385 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3395 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3400 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3600 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3700 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3700"; }
virtual void setText(const Common::String &msg);
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to SeekerL
-class SpeakerSeekerL : public VisualSpeaker {
+class SpeakerSeekerL : public SpeakerSeeker {
public:
SpeakerSeekerL();
@@ -491,14 +509,14 @@ public:
SpeakerSocko3200();
virtual Common::String getClassName() { return "SpeakerSocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Soldier
class SpeakerSoldier : public VisualSpeaker {
public:
- SpeakerSoldier(int colour);
+ SpeakerSoldier(int color);
virtual Common::String getClassName() { return "SpeakerSoldier"; }
};
@@ -506,7 +524,7 @@ class SpeakerSoldier300 : public SpeakerSoldier {
public:
SpeakerSoldier300() : SpeakerSoldier(60) {}
virtual Common::String getClassName() { return "SpeakerSoldier300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSoldier1625 : public SpeakerSoldier {
@@ -529,34 +547,40 @@ public:
virtual Common::String getClassName() { return "SpeakerTealMode7"; }
};
+class SpeakerTeal180 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal180"; }
+ virtual void animateSpeaker();
+};
+
class SpeakerTeal300 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal1625 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal1625"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3240 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal3240"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3400 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3600 : public SpeakerTealMode7 {
public:
virtual Common::String getClassName() { return "SpeakerTeal3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Tomko
@@ -566,17 +590,24 @@ public:
SpeakerTomko3245();
virtual Common::String getClassName() { return "SpeakerTomko3245"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Webbster
class SpeakerWebbster : public VisualSpeaker {
public:
- SpeakerWebbster(int colour);
+ SpeakerWebbster(int color);
virtual Common::String getClassName() { return "SpeakerWebbster"; }
};
+class SpeakerWebbster180 : public SpeakerWebbster {
+public:
+ SpeakerWebbster180() : SpeakerWebbster(27) {}
+ virtual Common::String getClassName() { return "SpeakerWebbster180"; }
+ virtual void animateSpeaker();
+};
+
class SpeakerWebbster2500 : public SpeakerWebbster {
public:
SpeakerWebbster2500() : SpeakerWebbster(27) {}
@@ -588,7 +619,7 @@ public:
SpeakerWebbster3240() : SpeakerWebbster(10) {}
virtual Common::String getClassName() { return "SpeakerWebbster3240"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3375 : public SpeakerWebbster {
@@ -596,7 +627,7 @@ public:
SpeakerWebbster3375() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3385 : public SpeakerWebbster {
@@ -604,7 +635,7 @@ public:
SpeakerWebbster3385() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3395 : public SpeakerWebbster {
@@ -612,7 +643,7 @@ public:
SpeakerWebbster3395() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3400 : public SpeakerWebbster {
@@ -620,15 +651,15 @@ public:
SpeakerWebbster3400() : SpeakerWebbster(27) {}
virtual Common::String getClassName() { return "SpeakerWebbster3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
-class SpeakerDutyOfficer: public VisualSpeaker {
+class SpeakerDutyOfficer180: public VisualSpeaker {
public:
- SpeakerDutyOfficer();
+ SpeakerDutyOfficer180();
virtual Common::String getClassName() { return "SpeakerDutyOfficer"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
} // End of namespace Ringworld2
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index af2f3566ad..f9e84e8913 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -47,6 +47,8 @@ SavedObject::~SavedObject() {
Saver::Saver() {
_macroSaveFlag = false;
_macroRestoreFlag = false;
+
+ _factoryPtr = nullptr;
}
Saver::~Saver() {
@@ -127,7 +129,6 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
// Set fields
_macroSaveFlag = true;
- _saveSlot = slot;
// Try and create the save file
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(g_vm->generateSaveName(slot));
@@ -151,8 +152,9 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
// Save each registered SaveObject descendant object into the savegame file
for (SynchronizedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) {
- serializer.validate((*i)->getClassName());
- (*i)->synchronize(serializer);
+ SavedObject *so = *i;
+ serializer.validate(so->getClassName());
+ so->synchronize(serializer);
}
// Save file complete
@@ -176,7 +178,6 @@ Common::Error Saver::restore(int slot) {
// Set fields
_macroRestoreFlag = true;
- _saveSlot = slot;
_unresolvedPtrs.clear();
// Set up the serializer
@@ -289,7 +290,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..32da6ee7f4 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -33,7 +33,7 @@ namespace TsAGE {
typedef void (*SaveNotifierFn)(bool postFlag);
-#define TSAGE_SAVEGAME_VERSION 10
+#define TSAGE_SAVEGAME_VERSION 12
class SavedObject;
@@ -48,7 +48,7 @@ struct tSageSavegameHeader {
/*--------------------------------------------------------------------------*/
-// FIXME: workaround to supress spurious strict-alias warnings on older GCC
+// FIXME: workaround to suppress spurious strict-alias warnings on older GCC
// versions. this should be resolved with the savegame rewrite
#define SYNC_POINTER(x) do { \
SavedObject **y = (SavedObject **)((void *)&x); \
@@ -59,7 +59,7 @@ struct tSageSavegameHeader {
if (s.isLoading()) FIELD = (TYPE)v_##FIELD;
/**
- * Derived serializer class with extra synchronisation types
+ * Derived serializer class with extra synchronization types
*/
class Serializer : public Common::Serializer {
public:
@@ -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;
+ }
};
/**
@@ -202,7 +212,6 @@ private:
bool _macroSaveFlag;
bool _macroRestoreFlag;
- int _saveSlot;
void resolveLoadPointers();
public:
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 774a5277dc..1726d6ad20 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -43,6 +43,7 @@ SceneManager::SceneManager() {
g_saver->addListener(this);
_objectCount = 0;
_loadMode = 0;
+ _sceneLoadCount = 0;
}
SceneManager::~SceneManager() {
@@ -56,8 +57,13 @@ void SceneManager::setNewScene(int sceneNumber) {
void SceneManager::checkScene() {
if (_nextSceneNumber != -1) {
+ int nextSceneNumber = _nextSceneNumber;
+
sceneChange();
- _nextSceneNumber = -1;
+
+ // Unless we've already switched to yet another scene, reset
+ if (_nextSceneNumber == nextSceneNumber)
+ _nextSceneNumber = -1;
}
g_globals->dispatchSounds();
@@ -247,6 +253,14 @@ void SceneManager::listenerSynchronize(Serializer &s) {
}
}
+ // Walk regions loading
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ int walkRegionsId = GLOBALS._walkRegions._resNum;
+ s.syncAsSint16LE(walkRegionsId);
+ if (s.isLoading())
+ GLOBALS._walkRegions.load(walkRegionsId);
+ }
+
g_globals->_sceneManager._scrollerRect.synchronize(s);
SYNC_POINTER(g_globals->_scrollFollower);
s.syncAsSint16LE(_loadMode);
@@ -260,6 +274,11 @@ Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
_activeScreenNumber = 0;
_oldSceneBounds = Rect(4000, 4000, 4100, 4100);
Common::fill(&_zoomPercents[0], &_zoomPercents[256], 0);
+
+ _field12 = 0;
+ _screenNumber = 0;
+ _fieldA = 0;
+ _fieldE = 0;
}
Scene::~Scene() {
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index b9567cece2..6633d15c26 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -22,6 +22,8 @@
#include "audio/decoders/raw.h"
#include "common/config-manager.h"
+#include "audio/decoders/raw.h"
+#include "audio/audiostream.h"
#include "tsage/core.h"
#include "tsage/globals.h"
#include "tsage/debugger.h"
@@ -118,17 +120,31 @@ void SoundManager::syncSounds() {
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
+ bool subtitles = ConfMan.hasKey("subtitles") ? ConfMan.getBool("subtitles") : true;
bool music_mute = mute;
+ bool voice_mute = mute;
if (!mute) {
music_mute = ConfMan.getBool("music_mute");
+ voice_mute = ConfMan.getBool("speech_mute");
}
// Get the new music volume
int musicVolume = music_mute ? 0 : MIN(255, ConfMan.getInt("music_volume"));
this->setMasterVol(musicVolume / 2);
+
+ // Return to Ringworld voice settings
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ // If we don't have voice, then ensure that text is turned on
+ if (voice_mute)
+ subtitles = true;
+
+ R2_GLOBALS._speechSubtitles =
+ (voice_mute ? 0 : SPEECH_VOICE) |
+ (!subtitles ? 0 : SPEECH_TEXT);
+ }
}
void SoundManager::update() {
@@ -953,7 +969,7 @@ void SoundManager::sfRethinkVoiceTypes() {
int entryIndex = -1;
for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
if (vtStruct->_entries[idx]._voiceNum == foundIndex) {
- foundIndex = true;
+ foundMatch = true;
if (!vtStruct->_entries[idx]._type0._sound2) {
entryIndex = idx;
break;
@@ -992,7 +1008,7 @@ void SoundManager::sfRethinkVoiceTypes() {
if (vtStruct->_entries[idx]._type0._priority2 > maxPriority) {
maxPriority = vtStruct->_entries[idx]._type0._priority2;
- entryIndex = -1;
+ entryIndex = idx;
}
}
@@ -1720,7 +1736,7 @@ uint32 Sound::getTimeIndex() const {
}
int Sound::getCueValue() const {
- return _cueValue;
+ return _cueValue == 0xff ? -1 : _cueValue;
}
void Sound::setCueValue(int cueValue) {
@@ -2395,7 +2411,7 @@ int Sound::soFindSound(VoiceTypeStruct *vtStruct, int channelNum) {
/*--------------------------------------------------------------------------*/
ASound::ASound(): EventHandler() {
- _action = NULL;
+ _endAction = NULL;
_cueValue = -1;
if (g_globals)
g_globals->_sounds.push_back(this);
@@ -2422,23 +2438,23 @@ void ASound::dispatch() {
_cueValue = cueValue;
_sound.setCueValue(-1);
- if (_action)
- _action->signal();
+ if (_endAction)
+ _endAction->signal();
}
if (_cueValue != -1) {
if (!_sound.isPrimed()) {
_cueValue = -1;
- if (_action) {
- _action->signal();
- _action = NULL;
+ if (_endAction) {
+ _endAction->signal();
+ _endAction = NULL;
}
}
}
}
-void ASound::play(int soundNum, EventHandler *action, int volume) {
- _action = action;
+void ASound::play(int soundNum, EventHandler *endAction, int volume) {
+ _endAction = endAction;
_cueValue = 0;
setVol(volume);
@@ -2461,9 +2477,9 @@ void ASound::unPrime() {
_action = NULL;
}
-void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action) {
- if (action)
- _action = action;
+void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *endAction) {
+ if (endAction)
+ _endAction = endAction;
_sound.fade(fadeDest, fadeSteps, fadeTicks, stopAfterFadeFlag);
}
@@ -2490,8 +2506,8 @@ void ASoundExt::signal() {
}
}
-void ASoundExt::fadeOut2(EventHandler *action) {
- fade(0, 10, 10, true, action);
+void ASoundExt::fadeOut2(EventHandler *endAction) {
+ fade(0, 10, 10, true, endAction);
}
void ASoundExt::changeSound(int soundNum) {
@@ -2505,6 +2521,183 @@ void ASoundExt::changeSound(int soundNum) {
/*--------------------------------------------------------------------------*/
+void PlayStream::ResFileData::load(Common::SeekableReadStream &stream) {
+ // Validate that it's the correct data file
+ char header[4];
+ stream.read(&header[0], 4);
+ if (strncmp(header, "SPAM", 4))
+ error("Invalid voice resource data");
+
+ _fileChunkSize = stream.readUint32LE();
+ stream.skip(2);
+ _indexSize = stream.readUint16LE();
+ _chunkSize = stream.readUint16LE();
+
+ stream.skip(18);
+}
+
+PlayStream::PlayStream(): EventHandler() {
+ _index = NULL;
+ _endAction = NULL;
+ _audioStream = NULL;
+
+ _resData._fileChunkSize = 0;
+ _resData._indexSize = 0;
+ _resData._chunkSize = 0;
+ _voiceNum = 0;
+}
+
+PlayStream::~PlayStream() {
+ remove();
+}
+
+bool PlayStream::setFile(const Common::String &filename) {
+ remove();
+
+ // Open the resource file for access
+ if (!_file.open(filename))
+ return false;
+
+ // Load header
+ _resData.load(_file);
+
+ // Load the index
+ _index = new uint16[_resData._indexSize / 2];
+ for (uint i = 0; i < (_resData._indexSize / 2); ++i)
+ _index[i] = _file.readUint16LE();
+
+ return true;
+}
+
+bool PlayStream::play(int voiceNum, EventHandler *endAction) {
+ uint32 offset = getFileOffset(_index, _resData._fileChunkSize, voiceNum);
+ if (offset) {
+ stop();
+ _voiceNum = 0;
+
+ // Move to the offset for the start of the voice
+ _file.seek(offset);
+
+ // Read in the header and validate it
+ char header[4];
+ _file.read(&header[0], 4);
+ if (strncmp(header, "FEED", 4))
+ error("Invalid stream data");
+
+ // Get basic details of first sound chunk
+ uint chunkSize = _file.readUint16LE() - 16;
+ _file.skip(4);
+ int rate = _file.readUint16LE();
+ _file.skip(4);
+
+ // Create the stream
+ _audioStream = Audio::makeQueuingAudioStream(rate, false);
+
+ // Load in the first chunk
+ byte *data = (byte *)malloc(chunkSize);
+ _file.read(data, chunkSize);
+ _audioStream->queueBuffer(data, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+
+ // If necessary, load further chunks of the voice in
+ while (chunkSize == (_resData._chunkSize - 16)) {
+ // Ensure the next chunk has the 'MORE' header
+ _file.read(&header[0], 4);
+ if (!strncmp(header, "FEED", 4))
+ // Reached start of next voice sample, so stop
+ break;
+ if (strncmp(header, "MORE", 4))
+ // Not more remaining, so break
+ break;
+
+ // Get the size of the chunk
+ chunkSize = _file.readUint16LE() - 16;
+ _file.skip(10);
+
+ // Read in the data for this next chunk and queue it
+ data = (byte *)malloc(chunkSize);
+ _file.read(data, chunkSize);
+ _audioStream->queueBuffer(data, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ }
+
+ g_vm->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle,
+ _audioStream, DisposeAfterUse::YES);
+ _voiceNum = voiceNum;
+ _endAction = endAction;
+ return true;
+ }
+
+ // If it reaches this point, no valid voice data found
+ return false;
+}
+
+void PlayStream::stop() {
+ if (_audioStream) {
+ g_vm->_mixer->stopHandle(_soundHandle);
+ }
+
+ _audioStream = NULL;
+ _voiceNum = 0;
+ _endAction = NULL;
+}
+
+bool PlayStream::isPlaying() const {
+ return _audioStream != NULL && !_audioStream->endOfData();
+}
+
+void PlayStream::remove() {
+ stop();
+ _file.close();
+
+ // Free index
+ delete[] _index;
+ _index = NULL;
+
+ _endAction = NULL;
+ _voiceNum = 0;
+}
+
+void PlayStream::dispatch() {
+ if (_voiceNum != 0 && !isPlaying()) {
+ // If voice has finished playing, reset fields
+ EventHandler *endAction = _endAction;
+ _endAction = NULL;
+ _voiceNum = 0;
+
+ if (endAction)
+ // Signal given end action
+ endAction->signal();
+ }
+}
+
+uint32 PlayStream::getFileOffset(const uint16 *data, int count, int voiceNum) {
+ if (!data)
+ return 0; // no valid voice data found
+
+ int bitsIndex = voiceNum & 7;
+ int byteIndex = voiceNum >> 3;
+ int shiftAmount = bitsIndex * 2;
+ int bitMask = 3 << shiftAmount;
+ int v = (data[byteIndex] & bitMask) >> shiftAmount;
+ uint32 offset = 0;
+
+ if (!v)
+ return 0;
+
+ // Loop to figure out offsets from index words skipped over
+ for (int i = 0; i < (voiceNum >> 3); ++i) {
+ for (int bit = 0; bit < 16; bit += 2)
+ offset += ((data[i] >> bit) & 3) * count;
+ }
+
+ // Bit index loop
+ for (int i = 0; i < bitsIndex; ++i)
+ offset += ((data[byteIndex] >> (i * 2)) & 3) * count;
+
+ return offset;
+}
+
+/*--------------------------------------------------------------------------*/
+
SoundDriver::SoundDriver() {
_driverResID = 0;
_minVersion = _maxVersion = 0;
@@ -2516,13 +2709,8 @@ SoundDriver::SoundDriver() {
const byte adlib_group_data[] = { 1, 1, 9, 1, 0xff };
-const byte v440B0[9] = { 0, 1, 2, 6, 7, 8, 12, 13, 14 };
-
-const byte v440B9[9] = { 3, 4, 5, 9, 10, 11, 15, 16, 17 };
-
-const byte v440C2[18] = {
- 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21
-};
+const byte adlib_operator1_offset[] = { 0, 1, 2, 8, 9, 10, 16, 17, 18 };
+const byte adlib_operator2_offset[] = { 3, 4, 5, 11, 12, 13, 19, 20, 21 };
const byte v44134[64] = {
0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
@@ -2546,8 +2734,6 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_masterVolume = 0;
_groupData._groupMask = 9;
- _groupData._v1 = 0x46;
- _groupData._v2 = 0;
_groupData._pData = &adlib_group_data[0];
_mixer = g_vm->_mixer;
@@ -2653,10 +2839,10 @@ void AdlibSoundDriver::playSound(const byte *channelData, int dataOffset, int pr
_v4409E[channel] = dataP + offset - _patchData;
// Set sustain/release
- int portNum = v440C2[v440B0[channel]] + 0x80;
+ int portNum = adlib_operator1_offset[channel] + 0x80;
write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
- portNum = v440C2[v440B9[channel]] + 0x80;
+ portNum = adlib_operator2_offset[channel] + 0x80;
write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
if (_channelVoiced[channel])
@@ -2713,10 +2899,10 @@ void AdlibSoundDriver::updateChannelVolume(int channelNum) {
int level1 = !_v44082[channelNum] ? 63 - _v44070[channelNum] :
63 - v44134[volume * _v44070[channelNum] / 63];
- int portNum = v440C2[v440B0[channelNum]] + 0x40;
+ int portNum = adlib_operator1_offset[channelNum] + 0x40;
write(portNum, (_portContents[portNum] & 0x80) | level1);
- portNum = v440C2[v440B9[channelNum]] + 0x40;
+ portNum = adlib_operator2_offset[channelNum] + 0x40;
write(portNum, (_portContents[portNum] & 0x80) | level2);
}
@@ -2733,7 +2919,7 @@ void AdlibSoundDriver::clearVoice(int channel) {
void AdlibSoundDriver::updateChannel(int channel) {
const byte *dataP = _patchData + _v4409E[channel];
- int portOffset = v440C2[v440B0[channel]];
+ int portOffset = adlib_operator1_offset[channel];
int portNum = portOffset + 0x20;
int portValue = 0;
@@ -2756,7 +2942,7 @@ void AdlibSoundDriver::updateChannel(int channel) {
write(0x80 + portOffset, *(dataP + 14) | (*(dataP + 13) << 4));
write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 15));
- portOffset = v440C2[v440B9[channel]];
+ portOffset = adlib_operator2_offset[channel];
portNum = portOffset + 0x20;
portValue = 0;
if (*(dataP + 17))
@@ -2865,8 +3051,6 @@ SoundBlasterDriver::SoundBlasterDriver(): SoundDriver() {
_masterVolume = 0;
_groupData._groupMask = 1;
- _groupData._v1 = 0x3E;
- _groupData._v2 = 0;
static byte const group_data[] = { 3, 1, 1, 0, 0xff };
_groupData._pData = group_data;
@@ -2914,10 +3098,12 @@ void SoundBlasterDriver::playSound(const byte *channelData, int dataOffset, int
updateVoice(channel);
// Set the new channel data
- _channelData = channelData + dataOffset;
+ _channelData = channelData + dataOffset + 18;
// Make a copy of the buffer
int dataSize = g_vm->_memoryManager.getSize(channelData);
+ dataSize -= 18;
+
byte *soundData = (byte *)malloc(dataSize - dataOffset);
Common::copy(_channelData, _channelData + (dataSize - dataOffset), soundData);
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 2f59afb49b..fefe8ad101 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -63,8 +63,6 @@ public:
struct GroupData {
uint32 _groupMask;
- byte _v1;
- byte _v2;
const byte *_pData;
};
@@ -98,7 +96,7 @@ public:
virtual const GroupData *getGroupData() { return NULL; } // Method #3
virtual void installPatch(const byte *data, int size) {} // Method #4
virtual void poll() {} // Method #5
- virtual void proc12() {} // Method #6
+ virtual void method6() {} // Method #6
virtual int setMasterVolume(int volume) { return 0; } // Method #7
virtual void proc16() {} // Method #8
virtual void proc18(int al, VoiceType voiceType) {} // Method #9
@@ -259,6 +257,7 @@ public:
class Sound: public EventHandler {
private:
void _prime(int soundResID, bool dontQueue);
+ void _primeBuffer(const byte *soundData);
void _unPrime();
public:
bool _stoppedAsynchronously;
@@ -365,7 +364,7 @@ public:
class ASound: public EventHandler {
public:
Sound _sound;
- EventHandler *_action;
+ EventHandler *_endAction;
int _cueValue;
ASound();
@@ -373,7 +372,7 @@ public:
virtual void synchronize(Serializer &s);
virtual void dispatch();
- void play(int soundNum, EventHandler *action = NULL, int volume = 127);
+ void play(int soundNum, EventHandler *endAction = NULL, int volume = 127);
void stop();
void prime(int soundNum, Action *action = NULL);
void unPrime();
@@ -385,7 +384,7 @@ public:
bool isMuted() const { return _sound.isMuted(); }
void pause(bool flag) { _sound.pause(flag); }
void mute(bool flag) { _sound.mute(flag); }
- void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action);
+ void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *endAction);
void fadeIn() { fade(127, 5, 10, false, NULL); }
void fadeOut(Action *action) { fade(0, 5, 10, true, action); }
void setTimeIndex(uint32 timeIndex) { _sound.setTimeIndex(timeIndex); }
@@ -406,7 +405,7 @@ public:
int _soundNum;
ASoundExt();
- void fadeOut2(EventHandler *action);
+ void fadeOut2(EventHandler *endAction);
void changeSound(int soundNum);
virtual Common::String getClassName() { return "ASoundExt"; }
@@ -414,15 +413,36 @@ public:
virtual void signal();
};
-class PlayStream {
+class PlayStream: public EventHandler {
+ class ResFileData {
+ public:
+ int _fileChunkSize;
+ uint _indexSize;
+ uint _chunkSize;
+
+ void load(Common::SeekableReadStream &stream);
+ };
+private:
+ Common::File _file;
+ ResFileData _resData;
+ Audio::QueuingAudioStream *_audioStream;
+ Audio::SoundHandle _soundHandle;
+ uint16 *_index;
+ EventHandler *_endAction;
+ int _voiceNum;
+
+ static uint32 getFileOffset(const uint16 *data, int count, int voiceNum);
public:
- Sound _sound;
+ PlayStream();
+ virtual ~PlayStream();
- void setFile(const Common::String &filename) {}
- bool play(int soundNum, EventHandler *endAction) { return false; }
- void stop() {}
- void proc1() {}
- bool isPlaying() const { return false; }
+ bool setFile(const Common::String &filename);
+ bool play(int voiceNum, EventHandler *endAction);
+ void stop();
+ bool isPlaying() const;
+
+ virtual void remove();
+ virtual void dispatch();
};
#define ADLIB_CHANNEL_COUNT 9
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index a273ec2a0b..2749f2ac90 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -162,7 +162,7 @@ char const *const BIKINI_HUT = "Bikini Hut";
char const *const RADIO_BTN_LIST[8] = { "10-2 ", "10-4 ", "10-13", "10-15", "10-27", "10-35", "10-97", "10-98" };
// Scene 570 computer messageS
-char const *const SCENE570_PASSWORD = "PASSWORD -> ";
+char const *const SCENE570_PASSWORD = "PASSWORD - }, ";
char const *const SCENE570_C_DRIVE = "C:\\";
char const *const SCENE570_RING = "RING";
char const *const SCENE570_PROTO = "PROTO";
@@ -229,6 +229,7 @@ char const *const RESTORE_GAME = "Restore game";
char const *const SHOW_CREDITS = "Show credits";
char const *const PAUSE_GAME = "Pause game";
char const *const RESUME_PLAY = " Resume play ";
+char const *const R2_RESTART_MSG = "Go to the beginning of game?";
char const *const F2 = "F2";
char const *const F3 = "F3";
char const *const F4 = "F4";
@@ -244,7 +245,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 +375,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,
@@ -397,8 +398,8 @@ const byte k5A4D6[] = {
13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14
};
-const byte k5A72E[] = {0, 98, 135, 183, 229, 81, 133, 185, 235, 75, 131, 187, 241, 70, 129, 190, 247};
-const byte k5A73F[] = {0, 42, 42, 42, 42, 67, 67, 67, 67, 92, 92, 92, 92, 116, 116, 116, 116};
+const byte scene1550JunkX[] = {0, 98, 135, 183, 229, 81, 133, 185, 235, 75, 131, 187, 241, 70, 129, 190, 247};
+const byte scene1550JunkY[] = {0, 42, 42, 42, 42, 67, 67, 67, 67, 92, 92, 92, 92, 116, 116, 116, 116};
const byte k5A750[] = {
9, 10, 7, 13, 7, 8, 9, 7, 9, 10,
2, 3, 3, 2, 2, 2, 4, 3, 3, 4,
@@ -409,8 +410,8 @@ 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 k5A79B[] = {
+const byte scene1550JunkRegions[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
+const byte scene1550SpecialAreas[] = {
23, 3, 1,
23, 4, 1,
26, 3, 1,
@@ -448,6 +449,201 @@ const byte k5A7F6[] = {
15, 10, 11
};
+const BalloonRecord balloonData[] = {
+ { 0, -2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 0, 1 },
+ { 0, 0, 1 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 0, 2, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 0, 0, -1 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 0, -1 },
+ { 0, 0, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 0, 0 },
+ { 0, 0, -1 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 2, 0, 0 },
+ { 0, 0, -1 },
+ { -2, 0, 0 },
+ { 0, 0, -1 },
+ { -2, 0, 0 },
+ { 0, 0, -1 },
+ { 2, 0, 0 },
+ { 0, 0, -1 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 2, 0, 0 },
+ { 0, 2, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 0, 1 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, 0, 1 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, 0, -1 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, -2, 0 },
+ { 0, 0, -1 },
+ { -2, 0, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { 0, -2, 0 },
+ { 2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, 0, 0 },
+ { 2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { -2, 0, 0 },
+ { 0, -2, 0 },
+ { 0, 2, 0 },
+ { -2, 0, 0 }
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index e3daf73333..587463a918 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -182,6 +182,7 @@ extern char const *const RESTORE_GAME;
extern char const *const SHOW_CREDITS;
extern char const *const PAUSE_GAME;
extern char const *const RESUME_PLAY;
+extern char const *const R2_RESTART_MSG;
extern char const *const F2;
extern char const *const F3;
extern char const *const F4;
@@ -199,16 +200,24 @@ 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 k5A72E[];
-extern const byte k5A73F[];
+extern const byte scene1550JunkLocationsDefault[];
+extern const byte scene1550AreaMap[];
+extern const byte scene1550JunkX[];
+extern const byte scene1550JunkY[];
extern const byte k5A750[];
extern const byte k5A76D[];
-extern const byte k5A78A[];
-extern const byte k5A79B[];
+extern const byte scene1550JunkRegions[];
+extern const byte scene1550SpecialAreas[];
extern const byte k5A7F6[];
+// Scene 2900 balloon data
+struct BalloonRecord {
+ int8 x;
+ int8 y;
+ int8 v3;
+};
+extern const BalloonRecord balloonData[];
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 87697f950b..37e96c75e0 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -38,6 +38,7 @@ TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc)
_gameDescription(gameDesc) {
g_vm = this;
DebugMan.addDebugChannel(kRingDebugScripts, "scripts", "Scripts debugging");
+ _debugger = nullptr;
if (g_vm->getFeatures() & GF_DEMO)
_debugger = new DemoDebugger();
else if (g_vm->getGameID() == GType_Ringworld)
@@ -103,7 +104,7 @@ void TSageEngine::initialize() {
g_globals = new Ringworld2::Ringworld2Globals();
// Setup the user interface
- T2_GLOBALS._uiElements.setup(Common::Point(0, UI_INTERFACE_Y - 2));
+ T2_GLOBALS._uiElements.setup(Common::Point(0, UI_INTERFACE_Y));
// Reset all global variables
R2_GLOBALS.reset();
@@ -124,7 +125,7 @@ void TSageEngine::deinitialize() {
}
Common::Error TSageEngine::run() {
- // Basic initialisation
+ // Basic initialization
initialize();
g_globals->_sceneHandler->registerHandler();
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index 4bd9e49875..ae34ac0574 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->setup2(4, 1, 1, 160, 125);
} else {
// Show object description
SceneItem::display2(3, (int)cursor);
@@ -273,11 +276,29 @@ void UICollection::draw() {
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT),
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT));
+ if (g_vm->getGameID() == GType_Ringworld2)
+ r2rDrawFrame();
+
_clearScreen = 1;
g_globals->_sceneManager._scene->_sceneBounds = savedBounds;
}
}
+void UICollection::r2rDrawFrame() {
+ Visage visage;
+ visage.setVisage(2, 1);
+ GfxSurface vertLine = visage.getFrame(1);
+ GfxSurface horizLine = visage.getFrame(2);
+
+ GLOBALS._screenSurface.copyFrom(horizLine, 0, 0);
+ GLOBALS._screenSurface.copyFrom(vertLine, 0, 3);
+ GLOBALS._screenSurface.copyFrom(vertLine, SCREEN_WIDTH - 4, 3);
+
+ // Restrict drawing area to exclude the borders at the edge of the screen
+ R2_GLOBALS._screenSurface._clipRect = Rect(4, 4, SCREEN_WIDTH - 4,
+ SCREEN_HEIGHT - 4);
+}
+
/*--------------------------------------------------------------------------*/
UIElements::UIElements(): UICollection() {
@@ -286,6 +307,10 @@ UIElements::UIElements(): UICollection() {
else
_cursorVisage.setVisage(1, 5);
g_saver->addLoadNotifier(&UIElements::loadNotifierProc);
+
+ _slotStart = 0;
+ _scoreValue = 0;
+ _active = false;
}
void UIElements::synchronize(Serializer &s) {
@@ -399,7 +424,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 +435,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 +476,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 +505,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..60cefc0751 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -95,6 +95,8 @@ public:
};
class UICollection: public EventHandler {
+private:
+ void r2rDrawFrame();
protected:
void erase();
public:
@@ -137,7 +139,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/configure.engine b/engines/tucker/configure.engine
new file mode 100644
index 0000000000..06676cf0a4
--- /dev/null
+++ b/engines/tucker/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tucker "Bud Tucker in Double Trouble" yes
diff --git a/engines/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/voyeur/animation.cpp b/engines/voyeur/animation.cpp
index 3bcc6cf10f..cbd7b0af18 100644
--- a/engines/voyeur/animation.cpp
+++ b/engines/voyeur/animation.cpp
@@ -230,7 +230,7 @@ void RL2Decoder::RL2VideoTrack::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->getPixels() + y * getWidth() + x, (*it).right - x);
}
}
@@ -238,7 +238,7 @@ void RL2Decoder::RL2VideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
}
void RL2Decoder::RL2VideoTrack::copyFrame(uint8 *data) {
- memcpy((byte *)_surface->pixels, data, getWidth() * getHeight());
+ memcpy((byte *)_surface->getPixels(), data, getWidth() * getHeight());
// Redraw
_dirtyRects.clear();
@@ -248,7 +248,7 @@ void RL2Decoder::RL2VideoTrack::copyFrame(uint8 *data) {
void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithoutBackground(int screenOffset) {
if (screenOffset == -1)
screenOffset = _videoBase;
- byte *destP = (byte *)_surface->pixels + screenOffset;
+ byte *destP = (byte *)_surface->getPixels() + screenOffset;
int frameSize = _surface->w * _surface->h - screenOffset;
while (frameSize > 0) {
@@ -280,8 +280,8 @@ void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithoutBackground(int screenOffset
void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithBackground() {
int screenOffset = _videoBase;
int frameSize = _surface->w * _surface->h - _videoBase;
- byte *src = (byte *)_backSurface->pixels;
- byte *dest = (byte *)_surface->pixels;
+ byte *src = (byte *)_backSurface->getPixels();
+ byte *dest = (byte *)_surface->getPixels();
while (frameSize > 0) {
byte nextByte = _fileStream->readByte();
diff --git a/engines/voyeur/configure.engine b/engines/voyeur/configure.engine
new file mode 100644
index 0000000000..647e20267f
--- /dev/null
+++ b/engines/voyeur/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine voyeur "Voyeur" yes
diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp
index 6bd0012fe7..56b7afd377 100644
--- a/engines/voyeur/events.cpp
+++ b/engines/voyeur/events.cpp
@@ -108,7 +108,7 @@ void EventsManager::checkForNextFrameCounter() {
voyeurTimer();
// Display the frame
- g_system->copyRectToScreen((byte *)_vm->_graphicsManager._screenSurface.pixels,
+ g_system->copyRectToScreen((byte *)_vm->_graphicsManager._screenSurface.getPixels(),
SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
g_system->updateScreen();
diff --git a/engines/voyeur/graphics.cpp b/engines/voyeur/graphics.cpp
index 6e3ed103ce..3a37eb9fb0 100644
--- a/engines/voyeur/graphics.cpp
+++ b/engines/voyeur/graphics.cpp
@@ -308,7 +308,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
// loc_2566F
if (srcFlags & DISPFLAG_2) {
// loc_256FA
- srcP = (byte *)_screenSurface.pixels + srcOffset;
+ srcP = (byte *)_screenSurface.getPixels() + srcOffset;
for (int yp = 0; yp < height1; ++yp) {
for (int xp = 0; xp < width2; ++width2, ++srcP, ++destP) {
@@ -341,7 +341,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
}
} else {
// loc_25829
- destP = (byte *)_screenSurface.pixels + screenOffset;
+ destP = (byte *)_screenSurface.getPixels() + screenOffset;
for (int yp = 0; yp < height1; ++yp) {
Common::copy(srcP, srcP + width2, destP);
@@ -356,7 +356,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
// loc_25D4A
} else {
// loc_2606D
- destP = (byte *)_screenSurface.pixels + screenOffset;
+ destP = (byte *)_screenSurface.getPixels() + screenOffset;
for (int yp = 0; yp < height1; ++yp) {
Common::copy(srcP, srcP + width2, destP);
@@ -491,7 +491,7 @@ error("TODO: var22/var24/var2C not initialised before use?");
// loc_27477
if (destFlags & DISPFLAG_8) {
// loc_27481
- destP = (byte *)_screenSurface.pixels + screenOffset;
+ destP = (byte *)_screenSurface.getPixels() + screenOffset;
for (int yp = 0; yp < height1; ++yp) {
Common::fill(srcP, srcP + width2, onOff);
destP += width2 + widthDiff2;
diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp
index f39d9be9d0..871fc41d25 100644
--- a/engines/voyeur/voyeur.cpp
+++ b/engines/voyeur/voyeur.cpp
@@ -502,8 +502,8 @@ void VoyeurEngine::doOpening() {
if (decoder.needsUpdate()) {
const Graphics::Surface *frame = decoder.decodeNextFrame();
- Common::copy((byte *)frame->pixels, (byte *)frame->pixels + 320 * 200,
- (byte *)_graphicsManager._screenSurface.pixels);
+ Common::copy((byte *)frame->getPixels(), (byte *)frame->getPixels() + 320 * 200,
+ (byte *)_graphicsManager._screenSurface.getPixels());
}
_eventsManager.pollEvents();
@@ -526,8 +526,8 @@ void VoyeurEngine::playRL2Video(const Common::String &filename) {
if (decoder.needsUpdate()) {
const Graphics::Surface *frame = decoder.decodeNextFrame();
- Common::copy((byte *)frame->pixels, (byte *)frame->pixels + 320 * 200,
- (byte *)_graphicsManager._screenSurface.pixels);
+ Common::copy((byte *)frame->getPixels(), (byte *)frame->getPixels() + 320 * 200,
+ (byte *)_graphicsManager._screenSurface.getPixels());
}
_eventsManager.pollEvents();
diff --git a/engines/wintermute/ad/ad_actor.cpp b/engines/wintermute/ad/ad_actor.cpp
index e4c18d6287..33ad39b411 100644
--- a/engines/wintermute/ad/ad_actor.cpp
+++ b/engines/wintermute/ad/ad_actor.cpp
@@ -119,7 +119,7 @@ AdActor::~AdActor() {
//////////////////////////////////////////////////////////////////////////
bool AdActor::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdActor::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -179,7 +179,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(ANIMATION)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdActor::loadBuffer(byte *buffer, bool complete) {
+bool AdActor::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ACTOR)
TOKEN_TABLE(X)
@@ -219,12 +219,12 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(ANIMATION)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTOR) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ACTOR) {
_gameRef->LOG(0, "'ACTOR' keyword expected.");
return STATUS_FAILED;
}
@@ -234,55 +234,55 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
AdGame *adGame = (AdGame *)_gameRef;
AdSpriteSet *spr = nullptr;
int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
+ parser.scanStr(params, "%b", &_zoomable);
break;
case TOKEN_ROTABLE:
case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
+ parser.scanStr(params, "%b", &_rotatable);
break;
case TOKEN_REGISTRABLE:
case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
+ parser.scanStr(params, "%b", &_registrable);
break;
case TOKEN_SHADOWABLE:
case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
+ parser.scanStr(params, "%b", &_shadowable);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_WALK:
@@ -348,7 +348,7 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_CURSOR:
@@ -362,12 +362,12 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
+ parser.scanStr(params, "%d", &_sFXVolume);
break;
case TOKEN_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_scale = (float)s;
}
@@ -375,14 +375,14 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
case TOKEN_RELATIVE_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_relativeScale = (float)s;
}
break;
case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ parser.scanStr(params, "%b", &_autoSoundPanning);
break;
case TOKEN_PROPERTY:
@@ -432,15 +432,15 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
+ parser.scanStr(params, "%b", &_ignoreItems);
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -1319,29 +1319,29 @@ BaseSprite *AdActor::getTalkStanceOld(const char *stance) {
bool AdActor::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_dir));
+ persistMgr->transferSint32(TMEMBER_INT(_dir));
persistMgr->transferPtr(TMEMBER_PTR(_path));
- persistMgr->transfer(TMEMBER(_pFCount));
- persistMgr->transfer(TMEMBER(_pFStepX));
- persistMgr->transfer(TMEMBER(_pFStepY));
- persistMgr->transfer(TMEMBER(_pFX));
- persistMgr->transfer(TMEMBER(_pFY));
+ persistMgr->transferSint32(TMEMBER(_pFCount));
+ persistMgr->transferDouble(TMEMBER(_pFStepX));
+ persistMgr->transferDouble(TMEMBER(_pFStepY));
+ persistMgr->transferDouble(TMEMBER(_pFX));
+ persistMgr->transferDouble(TMEMBER(_pFY));
persistMgr->transferPtr(TMEMBER_PTR(_standSprite));
_talkSprites.persist(persistMgr);
_talkSpritesEx.persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_targetDir));
- persistMgr->transfer(TMEMBER_INT(_afterWalkDir));
+ persistMgr->transferSint32(TMEMBER_INT(_targetDir));
+ persistMgr->transferSint32(TMEMBER_INT(_afterWalkDir));
persistMgr->transferPtr(TMEMBER_PTR(_targetPoint));
persistMgr->transferPtr(TMEMBER_PTR(_turnLeftSprite));
persistMgr->transferPtr(TMEMBER_PTR(_turnRightSprite));
persistMgr->transferPtr(TMEMBER_PTR(_walkSprite));
persistMgr->transferPtr(TMEMBER_PTR(_animSprite2));
- persistMgr->transfer(TMEMBER(_talkAnimName));
- persistMgr->transfer(TMEMBER(_idleAnimName));
- persistMgr->transfer(TMEMBER(_walkAnimName));
- persistMgr->transfer(TMEMBER(_turnLeftAnimName));
- persistMgr->transfer(TMEMBER(_turnRightAnimName));
+ persistMgr->transferString(TMEMBER(_talkAnimName));
+ persistMgr->transferString(TMEMBER(_idleAnimName));
+ persistMgr->transferString(TMEMBER(_walkAnimName));
+ persistMgr->transferString(TMEMBER(_turnLeftAnimName));
+ persistMgr->transferString(TMEMBER(_turnRightAnimName));
_anims.persist(persistMgr);
@@ -1376,7 +1376,7 @@ TDirection AdActor::angleToDirection(int angle) {
//////////////////////////////////////////////////////////////////////////
-int AdActor::getHeight() {
+int32 AdActor::getHeight() {
// if no current sprite is set, set some
if (_currentSprite == nullptr) {
if (_standSprite) {
@@ -1410,20 +1410,20 @@ bool AdActor::mergeAnims(const char *animsFilename) {
TOKEN_TABLE_END
- byte *fileBuffer = BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
+ char *fileBuffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
if (fileBuffer == nullptr) {
_gameRef->LOG(0, "AdActor::MergeAnims failed for file '%s'", animsFilename);
return STATUS_FAILED;
}
- byte *buffer = fileBuffer;
- byte *params;
+ char *buffer = fileBuffer;
+ char *params;
int cmd;
BaseParser parser;
bool ret = STATUS_OK;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_ANIMATION: {
AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
@@ -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..3225eb44ec 100644
--- a/engines/wintermute/ad/ad_actor.h
+++ b/engines/wintermute/ad/ad_actor.h
@@ -47,7 +47,7 @@ class AdActor : public AdTalkHolder {
public:
TDirection angleToDirection(int angle);
DECLARE_PERSISTENT(AdActor, AdTalkHolder)
- virtual int getHeight();
+ virtual int32 getHeight() override;
BaseSprite *getTalkStance(const char *stance);
virtual void goTo(int x, int y, TDirection afterWalkDir = DI_NONE);
BasePoint *_targetPoint;
@@ -57,7 +57,7 @@ public:
AdActor(BaseGame *inGame/*=nullptr*/);
virtual ~AdActor();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
private:
@@ -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..098da49750 100644
--- a/engines/wintermute/ad/ad_entity.cpp
+++ b/engines/wintermute/ad/ad_entity.cpp
@@ -100,7 +100,7 @@ const char *AdEntity::getItemName() const {
//////////////////////////////////////////////////////////////////////////
bool AdEntity::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdEntity::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -166,7 +166,7 @@ TOKEN_DEF(WALK_TO_DIR)
TOKEN_DEF(SAVE_STATE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdEntity::loadBuffer(byte *buffer, bool complete) {
+bool AdEntity::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ENTITY)
TOKEN_TABLE(SPRITE)
@@ -212,12 +212,12 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(SAVE_STATE)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ENTITY) {
_gameRef->LOG(0, "'ENTITY' keyword expected.");
return STATUS_FAILED;
}
@@ -227,27 +227,27 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
AdGame *adGame = (AdGame *)_gameRef;
BaseSprite *spr = nullptr;
int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_SPRITE: {
delete _sprite;
_sprite = nullptr;
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params))) {
+ if (!spr || DID_FAIL(spr->loadFile(params))) {
cmd = PARSERR_GENERIC;
} else {
_sprite = spr;
@@ -257,7 +257,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK: {
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, adGame->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSprites.add(spr);
@@ -267,7 +267,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK_SPECIAL: {
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, adGame->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSpritesEx.add(spr);
@@ -276,28 +276,28 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_ITEM:
- setItem((char *)params);
+ setItem(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
+ parser.scanStr(params, "%b", &_zoomable);
break;
case TOKEN_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_scale = (float)s;
}
@@ -305,7 +305,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_RELATIVE_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_relativeScale = (float)s;
}
@@ -313,27 +313,27 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_ROTABLE:
case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
+ parser.scanStr(params, "%b", &_rotatable);
break;
case TOKEN_REGISTRABLE:
case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
+ parser.scanStr(params, "%b", &_registrable);
break;
case TOKEN_SHADOWABLE:
case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
+ parser.scanStr(params, "%b", &_shadowable);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -341,7 +341,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_REGION: {
@@ -402,11 +402,11 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_SUBTYPE: {
- if (scumm_stricmp((char *)params, "sound") == 0) {
+ if (scumm_stricmp(params, "sound") == 0) {
delete _sprite;
_sprite = nullptr;
if (_gameRef->_editorMode) {
@@ -430,23 +430,23 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SOUND:
- playSFX((char *)params, false, false);
+ playSFX(params, false, false);
break;
case TOKEN_SOUND_START_TIME:
- parser.scanStr((char *)params, "%d", &_sFXStart);
+ parser.scanStr(params, "%d", &_sFXStart);
break;
case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
+ parser.scanStr(params, "%d", &_sFXVolume);
break;
case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ parser.scanStr(params, "%b", &_autoSoundPanning);
break;
case TOKEN_SAVE_STATE:
- parser.scanStr((char *)params, "%b", &_saveState);
+ parser.scanStr(params, "%b", &_saveState);
break;
case TOKEN_PROPERTY:
@@ -454,15 +454,15 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
+ parser.scanStr(params, "%b", &_ignoreItems);
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -470,16 +470,16 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_WALK_TO_X:
- parser.scanStr((char *)params, "%d", &_walkToX);
+ parser.scanStr(params, "%d", &_walkToX);
break;
case TOKEN_WALK_TO_Y:
- parser.scanStr((char *)params, "%d", &_walkToY);
+ parser.scanStr(params, "%d", &_walkToY);
break;
case TOKEN_WALK_TO_DIR: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
if (i < 0) {
i = 0;
}
@@ -1067,7 +1067,7 @@ bool AdEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
//////////////////////////////////////////////////////////////////////////
-int AdEntity::getHeight() {
+int32 AdEntity::getHeight() {
if (_region && !_sprite) {
return _region->_rect.bottom - _region->_rect.top;
} else {
@@ -1092,16 +1092,16 @@ void AdEntity::updatePosition() {
bool AdEntity::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_item));
+ persistMgr->transferCharPtr(TMEMBER(_item));
persistMgr->transferPtr(TMEMBER_PTR(_region));
//persistMgr->transfer(TMEMBER(_sprite));
- persistMgr->transfer(TMEMBER_INT(_subtype));
+ persistMgr->transferSint32(TMEMBER_INT(_subtype));
_talkSprites.persist(persistMgr);
_talkSpritesEx.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_walkToX));
- persistMgr->transfer(TMEMBER(_walkToY));
- persistMgr->transfer(TMEMBER_INT(_walkToDir));
+ persistMgr->transferSint32(TMEMBER(_walkToX));
+ persistMgr->transferSint32(TMEMBER(_walkToY));
+ persistMgr->transferSint32(TMEMBER_INT(_walkToDir));
persistMgr->transferPtr(TMEMBER_PTR(_theora));
@@ -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..c3ed5622e5 100644
--- a/engines/wintermute/ad/ad_entity.h
+++ b/engines/wintermute/ad/ad_entity.h
@@ -40,7 +40,7 @@ public:
void setItem(const char *itemName);
DECLARE_PERSISTENT(AdEntity, AdTalkHolder)
void updatePosition();
- virtual int getHeight();
+ virtual int32 getHeight() override;
BaseRegion *_region;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
virtual bool update();
@@ -48,7 +48,7 @@ public:
AdEntity(BaseGame *inGame);
virtual ~AdEntity();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
int32 getWalkToX() const;
int32 getWalkToY() const;
@@ -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..904b8a541c 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -1245,7 +1245,7 @@ bool AdGame::showCursor() {
//////////////////////////////////////////////////////////////////////////
bool AdGame::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdGame::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -1281,7 +1281,7 @@ TOKEN_DEF(STARTUP_SCENE)
TOKEN_DEF(DEBUG_STARTUP_SCENE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadBuffer(byte *buffer, bool complete) {
+bool AdGame::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(GAME)
TOKEN_TABLE(AD_GAME)
@@ -1295,14 +1295,14 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(DEBUG_STARTUP_SCENE)
TOKEN_TABLE_END
- byte *params;
- byte *params2;
+ char *params;
+ char *params2;
int cmd = 1;
BaseParser parser;
bool itemFound = false, itemsFound = false;
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_GAME:
if (DID_FAIL(BaseGame::loadBuffer(params, false))) {
@@ -1311,12 +1311,12 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AD_GAME:
- while (cmd > 0 && (cmd = parser.getCommand((char **)&params, commands, (char **)&params2)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&params, commands, &params2)) > 0) {
switch (cmd) {
case TOKEN_RESPONSE_BOX:
delete _responseBox;
_responseBox = new AdResponseBox(_gameRef);
- if (_responseBox && !DID_FAIL(_responseBox->loadFile((char *)params2))) {
+ if (_responseBox && !DID_FAIL(_responseBox->loadFile(params2))) {
registerObject(_responseBox);
} else {
delete _responseBox;
@@ -1328,7 +1328,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_INVENTORY_BOX:
delete _inventoryBox;
_inventoryBox = new AdInventoryBox(_gameRef);
- if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile((char *)params2))) {
+ if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile(params2))) {
registerObject(_inventoryBox);
} else {
delete _inventoryBox;
@@ -1339,7 +1339,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_ITEMS:
itemsFound = true;
- BaseUtils::setString(&_itemsFile, (char *)params2);
+ BaseUtils::setString(&_itemsFile, params2);
if (DID_FAIL(loadItemsFile(_itemsFile))) {
delete[] _itemsFile;
_itemsFile = nullptr;
@@ -1348,9 +1348,9 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_TALK_SKIP_BUTTON:
- if (scumm_stricmp((char *)params2, "right") == 0) {
+ if (scumm_stricmp(params2, "right") == 0) {
_talkSkipButton = TALK_SKIP_RIGHT;
- } else if (scumm_stricmp((char *)params2, "both") == 0) {
+ } else if (scumm_stricmp(params2, "both") == 0) {
_talkSkipButton = TALK_SKIP_BOTH;
} else {
_talkSkipButton = TALK_SKIP_LEFT;
@@ -1359,7 +1359,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_SCENE_VIEWPORT: {
Rect32 rc;
- parser.scanStr((char *)params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ parser.scanStr(params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
if (!_sceneViewport) {
_sceneViewport = new BaseViewport(_gameRef);
}
@@ -1374,11 +1374,11 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_STARTUP_SCENE:
- BaseUtils::setString(&_startupScene, (char *)params2);
+ BaseUtils::setString(&_startupScene, params2);
break;
case TOKEN_DEBUG_STARTUP_SCENE:
- BaseUtils::setString(&_debugStartupScene, (char *)params2);
+ BaseUtils::setString(&_debugStartupScene, params2);
break;
}
}
@@ -1417,41 +1417,41 @@ bool AdGame::persist(BasePersistenceManager *persistMgr) {
_objects.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_prevSceneName));
- persistMgr->transfer(TMEMBER(_prevSceneFilename));
+ persistMgr->transferCharPtr(TMEMBER(_prevSceneName));
+ persistMgr->transferCharPtr(TMEMBER(_prevSceneFilename));
persistMgr->transferPtr(TMEMBER_PTR(_responseBox));
_responsesBranch.persist(persistMgr);
_responsesGame.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_scene));
_sceneStates.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scheduledFadeIn));
- persistMgr->transfer(TMEMBER(_scheduledScene));
+ persistMgr->transferBool(TMEMBER(_scheduledFadeIn));
+ persistMgr->transferCharPtr(TMEMBER(_scheduledScene));
persistMgr->transferPtr(TMEMBER_PTR(_selectedItem));
- persistMgr->transfer(TMEMBER_INT(_talkSkipButton));
+ persistMgr->transferSint32(TMEMBER_INT(_talkSkipButton));
_sentences.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_sceneViewport));
- persistMgr->transfer(TMEMBER_INT(_stateEx));
- persistMgr->transfer(TMEMBER(_initialScene));
- persistMgr->transfer(TMEMBER(_debugStartupScene));
+ persistMgr->transferSint32(TMEMBER_INT(_stateEx));
+ persistMgr->transferBool(TMEMBER(_initialScene));
+ persistMgr->transferCharPtr(TMEMBER(_debugStartupScene));
persistMgr->transferPtr(TMEMBER_PTR(_invObject));
persistMgr->transferPtr(TMEMBER_PTR(_inventoryOwner));
- persistMgr->transfer(TMEMBER(_tempDisableSaveState));
+ persistMgr->transferBool(TMEMBER(_tempDisableSaveState));
_items.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_itemsFile));
+ persistMgr->transferCharPtr(TMEMBER(_itemsFile));
_speechDirs.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_smartItemCursor));
+ persistMgr->transferBool(TMEMBER(_smartItemCursor));
if (!persistMgr->getIsSaving()) {
_initialScene = false;
}
- persistMgr->transfer(TMEMBER(_startupScene));
+ persistMgr->transferCharPtr(TMEMBER(_startupScene));
return STATUS_OK;
@@ -1518,7 +1518,7 @@ bool AdGame::getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *ex
//////////////////////////////////////////////////////////////////////////
bool AdGame::loadItemsFile(const char *filename, bool merge) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdGame::LoadItemsFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -1541,12 +1541,12 @@ bool AdGame::loadItemsFile(const char *filename, bool merge) {
//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
+bool AdGame::loadItemsBuffer(char *buffer, bool merge) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ITEM)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
@@ -1556,7 +1556,7 @@ bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
}
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_ITEM: {
AdItem *item = new AdItem(_gameRef);
@@ -1637,7 +1637,7 @@ bool AdGame::windowLoadHook(UIWindow *win, char **buffer, char **params) {
switch (cmd) {
case TOKEN_ENTITY_CONTAINER: {
UIEntity *ent = new UIEntity(_gameRef);
- if (!ent || DID_FAIL(ent->loadBuffer((byte *)*params, false))) {
+ if (!ent || DID_FAIL(ent->loadBuffer(*params, false))) {
delete ent;
ent = nullptr;
cmd = PARSERR_GENERIC;
@@ -2160,7 +2160,6 @@ bool AdGame::onMouseLeftDown() {
_gameRef->_capturedObject = _gameRef->_activeObject;
}
_mouseLeftDown = true;
- BasePlatform::setCapture(/*_renderer->_window*/);
return STATUS_OK;
}
@@ -2171,7 +2170,6 @@ bool AdGame::onMouseLeftUp() {
_activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
}
- BasePlatform::releaseCapture();
_capturedObject = nullptr;
_mouseLeftDown = false;
@@ -2282,4 +2280,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..019f2e6478 100644
--- a/engines/wintermute/ad/ad_game.h
+++ b/engines/wintermute/ad/ad_game.h
@@ -120,10 +120,10 @@ public:
BaseArray<AdObject *> _objects;
virtual bool loadFile(const char *filename);
- virtual bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool loadBuffer(char *buffer, bool complete = true);
bool loadItemsFile(const char *filename, bool merge = false);
- bool loadItemsBuffer(byte *buffer, bool merge = false);
+ bool loadItemsBuffer(char *buffer, bool merge = false);
// scripting interface
virtual ScValue *scGetProperty(const Common::String &name) override;
@@ -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..f9352c77c6 100644
--- a/engines/wintermute/ad/ad_inventory.cpp
+++ b/engines/wintermute/ad/ad_inventory.cpp
@@ -128,9 +128,9 @@ bool AdInventory::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
_takenItems.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
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..5d7f053bb5 100644
--- a/engines/wintermute/ad/ad_inventory_box.cpp
+++ b/engines/wintermute/ad/ad_inventory_box.cpp
@@ -120,8 +120,8 @@ bool AdInventoryBox::display() {
if (_closeButton) {
_closeButton->_posX = _closeButton->_posY = 0;
- _closeButton->_width = _gameRef->_renderer->getWidth();
- _closeButton->_height = _gameRef->_renderer->getHeight();
+ _closeButton->setWidth(_gameRef->_renderer->getWidth());
+ _closeButton->setHeight(_gameRef->_renderer->getHeight());
_closeButton->display();
}
@@ -165,7 +165,7 @@ bool AdInventoryBox::display() {
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdInventoryBox::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -203,7 +203,7 @@ TOKEN_DEF(HIDE_SELECTED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
+bool AdInventoryBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(INVENTORY_BOX)
TOKEN_TABLE(TEMPLATE)
@@ -221,34 +221,34 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
bool alwaysVisible = false;
_exclusive = false;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_INVENTORY_BOX) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_INVENTORY_BOX) {
_gameRef->LOG(0, "'INVENTORY_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_WINDOW:
@@ -264,35 +264,35 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
break;
case TOKEN_EXCLUSIVE:
- parser.scanStr((char *)params, "%b", &_exclusive);
+ parser.scanStr(params, "%b", &_exclusive);
break;
case TOKEN_HIDE_SELECTED:
- parser.scanStr((char *)params, "%b", &_hideSelected);
+ parser.scanStr(params, "%b", &_hideSelected);
break;
case TOKEN_ALWAYS_VISIBLE:
- parser.scanStr((char *)params, "%b", &alwaysVisible);
+ parser.scanStr(params, "%b", &alwaysVisible);
break;
case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
+ parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_ITEM_WIDTH:
- parser.scanStr((char *)params, "%d", &_itemWidth);
+ parser.scanStr(params, "%d", &_itemWidth);
break;
case TOKEN_ITEM_HEIGHT:
- parser.scanStr((char *)params, "%d", &_itemHeight);
+ parser.scanStr(params, "%d", &_itemHeight);
break;
case TOKEN_SCROLL_BY:
- parser.scanStr((char *)params, "%d", &_scrollBy);
+ parser.scanStr(params, "%d", &_scrollBy);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -323,7 +323,7 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
if (_window) {
for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
+ if (!_window->_widgets[i]->getListener()) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
@@ -372,18 +372,18 @@ bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_closeButton));
- persistMgr->transfer(TMEMBER(_hideSelected));
- persistMgr->transfer(TMEMBER(_itemHeight));
- persistMgr->transfer(TMEMBER(_itemsArea));
- persistMgr->transfer(TMEMBER(_itemWidth));
- persistMgr->transfer(TMEMBER(_scrollBy));
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_spacing));
- persistMgr->transfer(TMEMBER(_visible));
+ persistMgr->transferBool(TMEMBER(_hideSelected));
+ persistMgr->transferSint32(TMEMBER(_itemHeight));
+ persistMgr->transferRect32(TMEMBER(_itemsArea));
+ persistMgr->transferSint32(TMEMBER(_itemWidth));
+ persistMgr->transferSint32(TMEMBER(_scrollBy));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_spacing));
+ persistMgr->transferBool(TMEMBER(_visible));
persistMgr->transferPtr(TMEMBER_PTR(_window));
- persistMgr->transfer(TMEMBER(_exclusive));
+ persistMgr->transferBool(TMEMBER(_exclusive));
return STATUS_OK;
}
-} // 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..4d576625b2 100644
--- a/engines/wintermute/ad/ad_inventory_box.h
+++ b/engines/wintermute/ad/ad_inventory_box.h
@@ -51,7 +51,7 @@ public:
AdInventoryBox(BaseGame *inGame);
virtual ~AdInventoryBox();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
private:
bool _exclusive;
@@ -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..1f19a3eeae 100644
--- a/engines/wintermute/ad/ad_item.cpp
+++ b/engines/wintermute/ad/ad_item.cpp
@@ -84,7 +84,7 @@ AdItem::~AdItem() {
//////////////////////////////////////////////////////////////////////////
bool AdItem::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdItem::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -134,7 +134,7 @@ TOKEN_DEF(AMOUNT_STRING)
TOKEN_DEF(AMOUNT)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdItem::loadBuffer(byte *buffer, bool complete) {
+bool AdItem::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ITEM)
TOKEN_TABLE(TEMPLATE)
@@ -164,12 +164,12 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(AMOUNT)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ITEM) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ITEM) {
_gameRef->LOG(0, "'ITEM' keyword expected.");
return STATUS_FAILED;
}
@@ -177,31 +177,31 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
}
int ar = 0, ag = 0, ab = 0, alpha = 255;
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_IMAGE:
case TOKEN_SPRITE:
delete _sprite;
_sprite = new BaseSprite(_gameRef, this);
- if (!_sprite || DID_FAIL(_sprite->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_sprite || DID_FAIL(_sprite->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _sprite;
cmd = PARSERR_GENERIC;
}
@@ -211,32 +211,32 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_SPRITE_HOVER:
delete _spriteHover;
_spriteHover = new BaseSprite(_gameRef, this);
- if (!_spriteHover || DID_FAIL(_spriteHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_spriteHover || DID_FAIL(_spriteHover->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _spriteHover;
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AMOUNT:
- parser.scanStr((char *)params, "%d", &_amount);
+ parser.scanStr(params, "%d", &_amount);
break;
case TOKEN_DISPLAY_AMOUNT:
- parser.scanStr((char *)params, "%b", &_displayAmount);
+ parser.scanStr(params, "%b", &_displayAmount);
break;
case TOKEN_AMOUNT_OFFSET_X:
- parser.scanStr((char *)params, "%d", &_amountOffsetX);
+ parser.scanStr(params, "%d", &_amountOffsetX);
break;
case TOKEN_AMOUNT_OFFSET_Y:
- parser.scanStr((char *)params, "%d", &_amountOffsetY);
+ parser.scanStr(params, "%d", &_amountOffsetY);
break;
case TOKEN_AMOUNT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_amountAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_amountAlign = TAL_RIGHT;
} else {
_amountAlign = TAL_CENTER;
@@ -244,12 +244,12 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AMOUNT_STRING:
- BaseUtils::setString(&_amountString, (char *)params);
+ BaseUtils::setString(&_amountString, params);
break;
case TOKEN_TALK: {
BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSprites.add(spr);
@@ -259,7 +259,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK_SPECIAL: {
BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSpritesEx.add(spr);
@@ -270,7 +270,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursorNormal;
_cursorNormal = new BaseSprite(_gameRef);
- if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _cursorNormal;
_cursorNormal = nullptr;
cmd = PARSERR_GENERIC;
@@ -280,7 +280,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR_HOVER:
delete _cursorHover;
_cursorHover = new BaseSprite(_gameRef);
- if (!_cursorHover || DID_FAIL(_cursorHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_cursorHover || DID_FAIL(_cursorHover->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _cursorHover;
_cursorHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -288,11 +288,11 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CURSOR_COMBINED:
- parser.scanStr((char *)params, "%b", &_cursorCombined);
+ parser.scanStr(params, "%b", &_cursorCombined);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -300,11 +300,11 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -783,17 +783,17 @@ bool AdItem::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_cursorCombined));
+ persistMgr->transferBool(TMEMBER(_cursorCombined));
persistMgr->transferPtr(TMEMBER_PTR(_cursorHover));
persistMgr->transferPtr(TMEMBER_PTR(_cursorNormal));
persistMgr->transferPtr(TMEMBER_PTR(_spriteHover));
- persistMgr->transfer(TMEMBER(_inInventory));
- persistMgr->transfer(TMEMBER(_displayAmount));
- persistMgr->transfer(TMEMBER(_amount));
- persistMgr->transfer(TMEMBER(_amountOffsetX));
- persistMgr->transfer(TMEMBER(_amountOffsetY));
- persistMgr->transfer(TMEMBER_INT(_amountAlign));
- persistMgr->transfer(TMEMBER(_amountString));
+ persistMgr->transferBool(TMEMBER(_inInventory));
+ persistMgr->transferBool(TMEMBER(_displayAmount));
+ persistMgr->transferSint32(TMEMBER(_amount));
+ persistMgr->transferSint32(TMEMBER(_amountOffsetX));
+ persistMgr->transferSint32(TMEMBER(_amountOffsetY));
+ persistMgr->transferSint32(TMEMBER_INT(_amountAlign));
+ persistMgr->transferCharPtr(TMEMBER(_amountString));
return STATUS_OK;
}
@@ -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..935ea5d73d 100644
--- a/engines/wintermute/ad/ad_item.h
+++ b/engines/wintermute/ad/ad_item.h
@@ -35,6 +35,8 @@
namespace Wintermute {
class AdItem : public AdTalkHolder {
+ using Wintermute::AdObject::display;
+
public:
bool update();
DECLARE_PERSISTENT(AdItem, AdTalkHolder)
@@ -48,7 +50,7 @@ public:
AdItem(BaseGame *inGame);
virtual ~AdItem();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
// scripting interface
virtual ScValue *scGetProperty(const Common::String &name) override;
@@ -64,6 +66,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..17dd83a8b7 100644
--- a/engines/wintermute/ad/ad_layer.cpp
+++ b/engines/wintermute/ad/ad_layer.cpp
@@ -62,7 +62,7 @@ AdLayer::~AdLayer() {
//////////////////////////////////////////////////////////////////////////
bool AdLayer::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdLayer::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -100,7 +100,7 @@ TOKEN_DEF(CLOSE_UP)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdLayer::loadBuffer(byte *buffer, bool complete) {
+bool AdLayer::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(LAYER)
TOKEN_TABLE(TEMPLATE)
@@ -119,52 +119,52 @@ bool AdLayer::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_LAYER) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_LAYER) {
_gameRef->LOG(0, "'LAYER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_MAIN:
- parser.scanStr((char *)params, "%b", &_main);
+ parser.scanStr(params, "%b", &_main);
break;
case TOKEN_CLOSE_UP:
- parser.scanStr((char *)params, "%b", &_closeUp);
+ parser.scanStr(params, "%b", &_closeUp);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_REGION: {
@@ -203,11 +203,11 @@ bool AdLayer::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -551,14 +551,14 @@ bool AdLayer::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_closeUp));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_main));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferBool(TMEMBER(_closeUp));
+ persistMgr->transferSint32(TMEMBER(_height));
+ persistMgr->transferBool(TMEMBER(_main));
_nodes.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
-} // 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..af7c3a364c 100644
--- a/engines/wintermute/ad/ad_layer.h
+++ b/engines/wintermute/ad/ad_layer.h
@@ -43,7 +43,7 @@ public:
virtual ~AdLayer();
BaseArray<AdSceneNode *> _nodes;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
@@ -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..dd07f23762 100644
--- a/engines/wintermute/ad/ad_node_state.cpp
+++ b/engines/wintermute/ad/ad_node_state.cpp
@@ -95,13 +95,13 @@ void AdNodeState::setCursor(const char *filename) {
bool AdNodeState::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_name));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_cursor));
- persistMgr->transfer(TMEMBER(_alphaColor));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferCharPtr(TMEMBER(_name));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferCharPtr(TMEMBER(_cursor));
+ persistMgr->transferUint32(TMEMBER(_alphaColor));
for (int i = 0; i < 7; i++) {
- persistMgr->transfer(TMEMBER(_caption[i]));
+ persistMgr->transferCharPtr(TMEMBER(_caption[i]));
}
return STATUS_OK;
@@ -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..3664e0fd8a 100644
--- a/engines/wintermute/ad/ad_object.cpp
+++ b/engines/wintermute/ad/ad_object.cpp
@@ -859,7 +859,7 @@ bool AdObject::setFont(const char *filename) {
//////////////////////////////////////////////////////////////////////////
-int AdObject::getHeight() {
+int32 AdObject::getHeight() {
if (!_currentSprite) {
return 0;
} else {
@@ -1030,30 +1030,30 @@ bool AdObject::reset() {
bool AdObject::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferPtr(TMEMBER_PTR(_blockRegion));
persistMgr->transferPtr(TMEMBER_PTR(_currentBlockRegion));
persistMgr->transferPtr(TMEMBER_PTR(_currentWptGroup));
persistMgr->transferPtr(TMEMBER_PTR(_currentSprite));
- persistMgr->transfer(TMEMBER(_drawn));
+ persistMgr->transferBool(TMEMBER(_drawn));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_ignoreItems));
- persistMgr->transfer(TMEMBER_INT(_nextState));
+ persistMgr->transferBool(TMEMBER(_ignoreItems));
+ persistMgr->transferSint32(TMEMBER_INT(_nextState));
persistMgr->transferPtr(TMEMBER_PTR(_sentence));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
persistMgr->transferPtr(TMEMBER_PTR(_animSprite));
- persistMgr->transfer(TMEMBER(_sceneIndependent));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimName));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimUsed));
+ persistMgr->transferBool(TMEMBER(_sceneIndependent));
+ persistMgr->transferCharPtr(TMEMBER(_forcedTalkAnimName));
+ persistMgr->transferBool(TMEMBER(_forcedTalkAnimUsed));
persistMgr->transferPtr(TMEMBER_PTR(_tempSprite2));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
persistMgr->transferPtr(TMEMBER_PTR(_wptGroup));
persistMgr->transferPtr(TMEMBER_PTR(_stickRegion));
- persistMgr->transfer(TMEMBER(_subtitlesModRelative));
- persistMgr->transfer(TMEMBER(_subtitlesModX));
- persistMgr->transfer(TMEMBER(_subtitlesModY));
- persistMgr->transfer(TMEMBER(_subtitlesModXCenter));
- persistMgr->transfer(TMEMBER(_subtitlesWidth));
+ persistMgr->transferBool(TMEMBER(_subtitlesModRelative));
+ persistMgr->transferSint32(TMEMBER(_subtitlesModX));
+ persistMgr->transferSint32(TMEMBER(_subtitlesModY));
+ persistMgr->transferBool(TMEMBER(_subtitlesModXCenter));
+ persistMgr->transferSint32(TMEMBER(_subtitlesWidth));
persistMgr->transferPtr(TMEMBER_PTR(_inventory));
persistMgr->transferPtr(TMEMBER_PTR(_partEmitter));
@@ -1065,9 +1065,9 @@ bool AdObject::persist(BasePersistenceManager *persistMgr) {
_attachmentsPost.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_registerAlias));
- persistMgr->transfer(TMEMBER(_partFollowParent));
- persistMgr->transfer(TMEMBER(_partOffsetX));
- persistMgr->transfer(TMEMBER(_partOffsetY));
+ persistMgr->transferBool(TMEMBER(_partFollowParent));
+ persistMgr->transferSint32(TMEMBER(_partOffsetX));
+ persistMgr->transferSint32(TMEMBER(_partOffsetY));
return STATUS_OK;
}
@@ -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..ba984ef8d1 100644
--- a/engines/wintermute/ad/ad_object.h
+++ b/engines/wintermute/ad/ad_object.h
@@ -61,7 +61,7 @@ public:
bool reset();
DECLARE_PERSISTENT(AdObject, BaseObject)
virtual void talk(const char *text, const char *sound = nullptr, uint32 duration = 0, const char *stances = nullptr, TTextAlign align = TAL_CENTER);
- virtual int getHeight() override;
+ virtual int32 getHeight() override;
bool setFont(const char *filename);
virtual bool update() override;
@@ -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..156fc80958 100644
--- a/engines/wintermute/ad/ad_path.cpp
+++ b/engines/wintermute/ad/ad_path.cpp
@@ -110,11 +110,11 @@ bool AdPath::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_currIndex));
+ persistMgr->transferSint32(TMEMBER(_currIndex));
_points.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_ready));
+ persistMgr->transferBool(TMEMBER(_ready));
return STATUS_OK;
}
-} // 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..5ee9568608 100644
--- a/engines/wintermute/ad/ad_path_point.cpp
+++ b/engines/wintermute/ad/ad_path_point.cpp
@@ -65,11 +65,11 @@ bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
BasePoint::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_distance));
- persistMgr->transfer(TMEMBER(_marked));
+ persistMgr->transferSint32(TMEMBER(_distance));
+ persistMgr->transferBool(TMEMBER(_marked));
persistMgr->transferPtr(TMEMBER_PTR(_origin));
return STATUS_OK;
}
-} // 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..2e8e73a1cf 100644
--- a/engines/wintermute/ad/ad_region.cpp
+++ b/engines/wintermute/ad/ad_region.cpp
@@ -69,7 +69,7 @@ bool AdRegion::hasDecoration() const {
//////////////////////////////////////////////////////////////////////////
bool AdRegion::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdRegion::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -110,7 +110,7 @@ TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdRegion::loadBuffer(byte *buffer, bool complete) {
+bool AdRegion::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(REGION)
TOKEN_TABLE(TEMPLATE)
@@ -131,12 +131,12 @@ bool AdRegion::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
_gameRef->LOG(0, "'REGION' keyword expected.");
return STATUS_FAILED;
}
@@ -150,67 +150,67 @@ bool AdRegion::loadBuffer(byte *buffer, bool complete) {
int ar = 255, ag = 255, ab = 255, alpha = 255;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_BLOCKED:
- parser.scanStr((char *)params, "%b", &_blocked);
+ parser.scanStr(params, "%b", &_blocked);
break;
case TOKEN_DECORATION:
- parser.scanStr((char *)params, "%b", &_decoration);
+ parser.scanStr(params, "%b", &_decoration);
break;
case TOKEN_ZOOM:
case TOKEN_SCALE: {
int j;
- parser.scanStr((char *)params, "%d", &j);
+ parser.scanStr(params, "%d", &j);
_zoom = (float)j;
}
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -401,12 +401,12 @@ bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool AdRegion::persist(BasePersistenceManager *persistMgr) {
BaseRegion::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_alpha));
- persistMgr->transfer(TMEMBER(_blocked));
- persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_zoom));
+ persistMgr->transferUint32(TMEMBER(_alpha));
+ persistMgr->transferBool(TMEMBER(_blocked));
+ persistMgr->transferBool(TMEMBER(_decoration));
+ 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..f3674dcbfb 100644
--- a/engines/wintermute/ad/ad_region.h
+++ b/engines/wintermute/ad/ad_region.h
@@ -40,7 +40,7 @@ public:
AdRegion(BaseGame *inGame);
virtual ~AdRegion();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool hasDecoration() const;
@@ -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..e7b4188de6 100644
--- a/engines/wintermute/ad/ad_response.cpp
+++ b/engines/wintermute/ad/ad_response.cpp
@@ -134,10 +134,10 @@ bool AdResponse::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_icon));
persistMgr->transferPtr(TMEMBER_PTR(_iconHover));
persistMgr->transferPtr(TMEMBER_PTR(_iconPressed));
- persistMgr->transfer(TMEMBER(_iD));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_textOrig));
- persistMgr->transfer(TMEMBER_INT(_responseType));
+ persistMgr->transferSint32(TMEMBER(_iD));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferCharPtr(TMEMBER(_textOrig));
+ persistMgr->transferSint32(TMEMBER_INT(_responseType));
persistMgr->transferPtr(TMEMBER_PTR(_font));
return STATUS_OK;
@@ -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..f2e986cbdc 100644
--- a/engines/wintermute/ad/ad_response_box.cpp
+++ b/engines/wintermute/ad/ad_response_box.cpp
@@ -58,7 +58,7 @@ AdResponseBox::AdResponseBox(BaseGame *inGame) : BaseObject(inGame) {
_shieldWindow = new UIWindow(_gameRef);
_horizontal = false;
- BasePlatform::setRectEmpty(&_responseArea);
+ _responseArea.setEmpty();
_scrollOffset = 0;
_spacing = 0;
@@ -121,12 +121,12 @@ void AdResponseBox::clearButtons() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::invalidateButtons() {
for (uint32 i = 0; i < _respButtons.size(); i++) {
- _respButtons[i]->_image = nullptr;
- _respButtons[i]->_cursor = nullptr;
- _respButtons[i]->_font = nullptr;
- _respButtons[i]->_fontHover = nullptr;
- _respButtons[i]->_fontPress = nullptr;
+ _respButtons[i]->setImage(nullptr);
+ _respButtons[i]->setFont(nullptr);
_respButtons[i]->setText("");
+ _respButtons[i]->_cursor = nullptr;
+ _respButtons[i]->setFontHover(nullptr);
+ _respButtons[i]->setFontPress(nullptr);
}
return STATUS_OK;
}
@@ -141,16 +141,17 @@ bool AdResponseBox::createButtons() {
UIButton *btn = new UIButton(_gameRef);
if (btn) {
btn->_parent = _window;
- btn->_sharedFonts = btn->_sharedImages = true;
+ btn->setSharedFonts(true);
+ btn->setSharedImages(true);
btn->_sharedCursors = true;
// iconic
if (_responses[i]->getIcon()) {
- btn->_image = _responses[i]->getIcon();
+ btn->setImage(_responses[i]->getIcon());
if (_responses[i]->getIconHover()) {
- btn->_imageHover = _responses[i]->getIconHover();
+ btn->setImageHover(_responses[i]->getIconHover());
}
if (_responses[i]->getIconPressed()) {
- btn->_imagePress = _responses[i]->getIconPressed();
+ btn->setImagePress(_responses[i]->getIconPressed());
}
btn->setCaption(_responses[i]->getText());
@@ -163,23 +164,30 @@ bool AdResponseBox::createButtons() {
// textual
else {
btn->setText(_responses[i]->getText());
- btn->_font = (_font == nullptr) ? _gameRef->getSystemFont() : _font;
- btn->_fontHover = (_fontHover == nullptr) ? _gameRef->getSystemFont() : _fontHover;
- btn->_fontPress = btn->_fontHover;
- btn->_align = _align;
+ if (_font == nullptr) {
+ btn->setFont(_gameRef->getSystemFont());
+ } else {
+ btn->setFont(_font);
+ }
+ btn->setFontHover((_fontHover == nullptr) ? _gameRef->getSystemFont() : _fontHover);
+ btn->setFontPress(btn->getFontHover());
+ btn->setTextAlign(_align);
if (_gameRef->_touchInterface) {
- btn->_fontHover = btn->_font;
+ btn->setFontHover(btn->getFont());
}
if (_responses[i]->getFont()) {
- btn->_font = _responses[i]->getFont();
+ btn->setFont(_responses[i]->getFont());
}
- btn->_width = _responseArea.right - _responseArea.left;
- if (btn->_width <= 0) {
- btn->_width = _gameRef->_renderer->getWidth();
+ int width = _responseArea.right - _responseArea.left;
+
+ if (width <= 0) {
+ btn->setWidth(_gameRef->_renderer->getWidth());
+ } else {
+ btn->setWidth(width);
}
}
btn->setName("response");
@@ -187,17 +195,17 @@ bool AdResponseBox::createButtons() {
// make the responses touchable
if (_gameRef->_touchInterface) {
- btn->_height = MAX<int32>(btn->_height, 50);
+ btn->setHeight(MAX<int32>(btn->getHeight(), 50));
}
//btn->SetListener(this, btn, _responses[i]->_iD);
btn->setListener(this, btn, i);
- btn->_visible = false;
+ btn->setVisible(false);
_respButtons.add(btn);
- if (_responseArea.bottom - _responseArea.top < btn->_height) {
+ if (_responseArea.bottom - _responseArea.top < btn->getHeight()) {
_gameRef->LOG(0, "Warning: Response '%s' is too high to be displayed within response box. Correcting.", _responses[i]->getText());
- _responseArea.bottom += (btn->_height - (_responseArea.bottom - _responseArea.top));
+ _responseArea.bottom += (btn->getHeight() - (_responseArea.bottom - _responseArea.top));
}
}
}
@@ -209,7 +217,7 @@ bool AdResponseBox::createButtons() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdResponseBox::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -245,7 +253,7 @@ TOKEN_DEF(VERTICAL_ALIGN)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
+bool AdResponseBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(RESPONSE_BOX)
TOKEN_TABLE(TEMPLATE)
@@ -262,22 +270,22 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_RESPONSE_BOX) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_RESPONSE_BOX) {
_gameRef->LOG(0, "'RESPONSE_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -298,7 +306,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -308,24 +316,24 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_fontHover) {
_gameRef->_fontStorage->removeFont(_fontHover);
}
- _fontHover = _gameRef->_fontStorage->addFont((char *)params);
+ _fontHover = _gameRef->_fontStorage->addFont(params);
if (!_fontHover) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
break;
case TOKEN_HORIZONTAL:
- parser.scanStr((char *)params, "%b", &_horizontal);
+ parser.scanStr(params, "%b", &_horizontal);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "center") == 0) {
+ if (scumm_stricmp(params, "center") == 0) {
_align = TAL_CENTER;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_align = TAL_RIGHT;
} else {
_align = TAL_LEFT;
@@ -333,9 +341,9 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_VERTICAL_ALIGN:
- if (scumm_stricmp((char *)params, "top") == 0) {
+ if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
- } else if (scumm_stricmp((char *)params, "center") == 0) {
+ } else if (scumm_stricmp(params, "center") == 0) {
_verticalAlign = VAL_CENTER;
} else {
_verticalAlign = VAL_BOTTOM;
@@ -343,7 +351,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
+ parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -353,7 +361,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -368,7 +376,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_window) {
for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
+ if (!_window->_widgets[i]->getListener()) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
@@ -461,7 +469,7 @@ bool AdResponseBox::display() {
if (!_horizontal) {
int totalHeight = 0;
for (i = 0; i < _respButtons.size(); i++) {
- totalHeight += (_respButtons[i]->_height + _spacing);
+ totalHeight += (_respButtons[i]->getHeight() + _spacing);
}
totalHeight -= _spacing;
@@ -487,22 +495,22 @@ bool AdResponseBox::display() {
// prepare response buttons
bool scrollNeeded = false;
for (i = _scrollOffset; i < _respButtons.size(); i++) {
- if ((_horizontal && xxx + _respButtons[i]->_width > rect.right)
- || (!_horizontal && yyy + _respButtons[i]->_height > rect.bottom)) {
+ if ((_horizontal && xxx + _respButtons[i]->getWidth() > rect.right)
+ || (!_horizontal && yyy + _respButtons[i]->getHeight() > rect.bottom)) {
scrollNeeded = true;
- _respButtons[i]->_visible = false;
+ _respButtons[i]->setVisible(false);
break;
}
- _respButtons[i]->_visible = true;
+ _respButtons[i]->setVisible(true);
_respButtons[i]->_posX = xxx;
_respButtons[i]->_posY = yyy;
if (_horizontal) {
- xxx += (_respButtons[i]->_width + _spacing);
+ xxx += (_respButtons[i]->getWidth() + _spacing);
} else {
- yyy += (_respButtons[i]->_height + _spacing);
+ yyy += (_respButtons[i]->getHeight() + _spacing);
}
}
@@ -515,8 +523,8 @@ bool AdResponseBox::display() {
// go exclusive
if (_shieldWindow) {
_shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->getWidth();
- _shieldWindow->_height = _gameRef->_renderer->getHeight();
+ _shieldWindow->setWidth(_gameRef->_renderer->getWidth());
+ _shieldWindow->setHeight(_gameRef->_renderer->getHeight());
_shieldWindow->display();
}
@@ -575,20 +583,20 @@ bool AdResponseBox::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_font));
persistMgr->transferPtr(TMEMBER_PTR(_fontHover));
- persistMgr->transfer(TMEMBER(_horizontal));
- persistMgr->transfer(TMEMBER(_lastResponseText));
- persistMgr->transfer(TMEMBER(_lastResponseTextOrig));
+ persistMgr->transferBool(TMEMBER(_horizontal));
+ persistMgr->transferCharPtr(TMEMBER(_lastResponseText));
+ persistMgr->transferCharPtr(TMEMBER(_lastResponseTextOrig));
_respButtons.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_responseArea));
+ persistMgr->transferRect32(TMEMBER(_responseArea));
_responses.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER(_spacing));
+ persistMgr->transferSint32(TMEMBER(_spacing));
persistMgr->transferPtr(TMEMBER_PTR(_waitingScript));
persistMgr->transferPtr(TMEMBER_PTR(_window));
- persistMgr->transfer(TMEMBER_INT(_verticalAlign));
- persistMgr->transfer(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
return STATUS_OK;
}
@@ -737,4 +745,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..9469bfda43 100644
--- a/engines/wintermute/ad/ad_response_box.h
+++ b/engines/wintermute/ad/ad_response_box.h
@@ -72,7 +72,7 @@ public:
virtual ~AdResponseBox();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
UIWindow *getResponseWindow();
@@ -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..44b43a6077 100644
--- a/engines/wintermute/ad/ad_response_context.cpp
+++ b/engines/wintermute/ad/ad_response_context.cpp
@@ -50,8 +50,8 @@ AdResponseContext::~AdResponseContext() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseContext::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_context));
- persistMgr->transfer(TMEMBER(_id));
+ persistMgr->transferCharPtr(TMEMBER(_context));
+ persistMgr->transferSint32(TMEMBER(_id));
return STATUS_OK;
}
@@ -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..b5bdc8ebe9 100644
--- a/engines/wintermute/ad/ad_rot_level.cpp
+++ b/engines/wintermute/ad/ad_rot_level.cpp
@@ -53,7 +53,7 @@ AdRotLevel::~AdRotLevel() {
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdRotLevel::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -82,7 +82,7 @@ TOKEN_DEF(ROTATION)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
+bool AdRotLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ROTATION_LEVEL)
TOKEN_TABLE(TEMPLATE)
@@ -91,33 +91,33 @@ bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ROTATION_LEVEL) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ROTATION_LEVEL) {
_gameRef->LOG(0, "'ROTATION_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_ROTATION: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
_rotation = (float)i;
}
break;
@@ -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..47c621845a 100644
--- a/engines/wintermute/ad/ad_rot_level.h
+++ b/engines/wintermute/ad/ad_rot_level.h
@@ -42,9 +42,9 @@ public:
float getRotation() const { return _rotation; }
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
};
-} // end of namespace Wintermute
+} // 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..aa7f6f89cf 100644
--- a/engines/wintermute/ad/ad_scale_level.cpp
+++ b/engines/wintermute/ad/ad_scale_level.cpp
@@ -54,7 +54,7 @@ float AdScaleLevel::getScale() const {
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -83,7 +83,7 @@ TOKEN_DEF(SCALE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
+bool AdScaleLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SCALE_LEVEL)
TOKEN_TABLE(TEMPLATE)
@@ -92,33 +92,33 @@ bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCALE_LEVEL) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SCALE_LEVEL) {
_gameRef->LOG(0, "'SCALE_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_SCALE: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
_scale = (float)i;
}
break;
@@ -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..768e79bbf7 100644
--- a/engines/wintermute/ad/ad_scale_level.h
+++ b/engines/wintermute/ad/ad_scale_level.h
@@ -41,12 +41,12 @@ public:
virtual ~AdScaleLevel();
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
float getScale() const;
private:
float _scale;
};
-} // 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..ab7ab51f30 100644
--- a/engines/wintermute/ad/ad_scene.cpp
+++ b/engines/wintermute/ad/ad_scene.cpp
@@ -538,7 +538,7 @@ bool AdScene::initLoop() {
//////////////////////////////////////////////////////////////////////////
bool AdScene::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdScene::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -600,7 +600,7 @@ TOKEN_DEF(PERSISTENT_STATE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdScene::loadBuffer(byte *buffer, bool complete) {
+bool AdScene::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SCENE)
TOKEN_TABLE(TEMPLATE)
@@ -643,12 +643,12 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
cleanup();
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCENE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SCENE) {
_gameRef->LOG(0, "'SCENE' keyword expected.");
return STATUS_FAILED;
}
@@ -659,20 +659,20 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
char camera[MAX_PATH_LENGTH] = "";
/* float waypointHeight = -1.0f; */
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_LAYER: {
@@ -747,7 +747,7 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -755,99 +755,99 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CAMERA:
- Common::strlcpy(camera, (char *)params, MAX_PATH_LENGTH);
+ Common::strlcpy(camera, params, MAX_PATH_LENGTH);
break;
case TOKEN_EDITOR_MARGIN_H:
- parser.scanStr((char *)params, "%d", &_editorMarginH);
+ parser.scanStr(params, "%d", &_editorMarginH);
break;
case TOKEN_EDITOR_MARGIN_V:
- parser.scanStr((char *)params, "%d", &_editorMarginV);
+ parser.scanStr(params, "%d", &_editorMarginV);
break;
case TOKEN_EDITOR_COLOR_FRAME:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColFrame = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_ENTITY:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColEntity = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_ENTITY_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColEntitySel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_REGION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColRegionSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_DECORATION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColDecorSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_BLOCKED_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColBlockedSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_WAYPOINTS_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColWaypointsSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_REGION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColRegion = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_DECORATION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColDecor = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_BLOCKED:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColBlocked = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_WAYPOINTS:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColWaypoints = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_SCALE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColScale = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_SHOW_REGIONS:
- parser.scanStr((char *)params, "%b", &_editorShowRegions);
+ parser.scanStr(params, "%b", &_editorShowRegions);
break;
case TOKEN_EDITOR_SHOW_BLOCKED:
- parser.scanStr((char *)params, "%b", &_editorShowBlocked);
+ parser.scanStr(params, "%b", &_editorShowBlocked);
break;
case TOKEN_EDITOR_SHOW_DECORATION:
- parser.scanStr((char *)params, "%b", &_editorShowDecor);
+ parser.scanStr(params, "%b", &_editorShowDecor);
break;
case TOKEN_EDITOR_SHOW_ENTITIES:
- parser.scanStr((char *)params, "%b", &_editorShowEntities);
+ parser.scanStr(params, "%b", &_editorShowEntities);
break;
case TOKEN_EDITOR_SHOW_SCALE:
- parser.scanStr((char *)params, "%b", &_editorShowScale);
+ parser.scanStr(params, "%b", &_editorShowScale);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -856,7 +856,7 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
case TOKEN_VIEWPORT: {
Rect32 rc;
- parser.scanStr((char *)params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
if (!_viewport) {
_viewport = new BaseViewport(_gameRef);
}
@@ -864,13 +864,14 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
_viewport->setRect(rc.left, rc.top, rc.right, rc.bottom, true);
}
}
+ break;
case TOKEN_PERSISTENT_STATE:
- parser.scanStr((char *)params, "%b", &_persistentState);
+ parser.scanStr(params, "%b", &_persistentState);
break;
case TOKEN_PERSISTENT_STATE_SPRITES:
- parser.scanStr((char *)params, "%b", &_persistentStateSprites);
+ parser.scanStr(params, "%b", &_persistentStateSprites);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -1014,8 +1015,8 @@ bool AdScene::traverseNodes(bool doUpdate) {
}
if (_shieldWindow) {
_shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->getWidth();
- _shieldWindow->_height = _gameRef->_renderer->getHeight();
+ _shieldWindow->setWidth(_gameRef->_renderer->getWidth());
+ _shieldWindow->setHeight(_gameRef->_renderer->getHeight());
_shieldWindow->display();
}
}
@@ -2299,58 +2300,58 @@ float AdScene::getScaleAt(int Y) {
bool AdScene::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_autoScroll));
- persistMgr->transfer(TMEMBER(_editorColBlocked));
- persistMgr->transfer(TMEMBER(_editorColBlockedSel));
- persistMgr->transfer(TMEMBER(_editorColDecor));
- persistMgr->transfer(TMEMBER(_editorColDecorSel));
- persistMgr->transfer(TMEMBER(_editorColEntity));
- persistMgr->transfer(TMEMBER(_editorColEntitySel));
- persistMgr->transfer(TMEMBER(_editorColFrame));
- persistMgr->transfer(TMEMBER(_editorColRegion));
- persistMgr->transfer(TMEMBER(_editorColRegionSel));
- persistMgr->transfer(TMEMBER(_editorColScale));
- persistMgr->transfer(TMEMBER(_editorColWaypoints));
- persistMgr->transfer(TMEMBER(_editorColWaypointsSel));
- persistMgr->transfer(TMEMBER(_editorMarginH));
- persistMgr->transfer(TMEMBER(_editorMarginV));
- persistMgr->transfer(TMEMBER(_editorShowBlocked));
- persistMgr->transfer(TMEMBER(_editorShowDecor));
- persistMgr->transfer(TMEMBER(_editorShowEntities));
- persistMgr->transfer(TMEMBER(_editorShowRegions));
- persistMgr->transfer(TMEMBER(_editorShowScale));
+ persistMgr->transferBool(TMEMBER(_autoScroll));
+ persistMgr->transferUint32(TMEMBER(_editorColBlocked));
+ persistMgr->transferUint32(TMEMBER(_editorColBlockedSel));
+ persistMgr->transferUint32(TMEMBER(_editorColDecor));
+ persistMgr->transferUint32(TMEMBER(_editorColDecorSel));
+ persistMgr->transferUint32(TMEMBER(_editorColEntity));
+ persistMgr->transferUint32(TMEMBER(_editorColEntitySel));
+ persistMgr->transferUint32(TMEMBER(_editorColFrame));
+ persistMgr->transferUint32(TMEMBER(_editorColRegion));
+ persistMgr->transferUint32(TMEMBER(_editorColRegionSel));
+ persistMgr->transferUint32(TMEMBER(_editorColScale));
+ persistMgr->transferUint32(TMEMBER(_editorColWaypoints));
+ persistMgr->transferUint32(TMEMBER(_editorColWaypointsSel));
+ persistMgr->transferSint32(TMEMBER(_editorMarginH));
+ persistMgr->transferSint32(TMEMBER(_editorMarginV));
+ persistMgr->transferBool(TMEMBER(_editorShowBlocked));
+ persistMgr->transferBool(TMEMBER(_editorShowDecor));
+ persistMgr->transferBool(TMEMBER(_editorShowEntities));
+ persistMgr->transferBool(TMEMBER(_editorShowRegions));
+ persistMgr->transferBool(TMEMBER(_editorShowScale));
persistMgr->transferPtr(TMEMBER_PTR(_fader));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_initialized));
- persistMgr->transfer(TMEMBER(_lastTimeH));
- persistMgr->transfer(TMEMBER(_lastTimeV));
+ persistMgr->transferSint32(TMEMBER(_height));
+ persistMgr->transferBool(TMEMBER(_initialized));
+ persistMgr->transferUint32(TMEMBER(_lastTimeH));
+ persistMgr->transferUint32(TMEMBER(_lastTimeV));
_layers.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_mainLayer));
_objects.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_offsetLeft));
- persistMgr->transfer(TMEMBER(_offsetTop));
- persistMgr->transfer(TMEMBER(_paralaxScrolling));
- persistMgr->transfer(TMEMBER(_persistentState));
- persistMgr->transfer(TMEMBER(_persistentStateSprites));
- persistMgr->transfer(TMEMBER(_pfMaxTime));
+ persistMgr->transferSint32(TMEMBER(_offsetLeft));
+ persistMgr->transferSint32(TMEMBER(_offsetTop));
+ persistMgr->transferBool(TMEMBER(_paralaxScrolling));
+ persistMgr->transferBool(TMEMBER(_persistentState));
+ persistMgr->transferBool(TMEMBER(_persistentStateSprites));
+ persistMgr->transferUint32(TMEMBER(_pfMaxTime));
_pfPath.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_pfPointsNum));
- persistMgr->transfer(TMEMBER(_pfReady));
+ persistMgr->transferSint32(TMEMBER(_pfPointsNum));
+ persistMgr->transferBool(TMEMBER(_pfReady));
persistMgr->transferPtr(TMEMBER_PTR(_pfRequester));
persistMgr->transferPtr(TMEMBER_PTR(_pfTarget));
persistMgr->transferPtr(TMEMBER_PTR(_pfTargetPath));
_rotLevels.persist(persistMgr);
_scaleLevels.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollPixelsH));
- persistMgr->transfer(TMEMBER(_scrollPixelsV));
- persistMgr->transfer(TMEMBER(_scrollTimeH));
- persistMgr->transfer(TMEMBER(_scrollTimeV));
+ persistMgr->transferSint32(TMEMBER(_scrollPixelsH));
+ persistMgr->transferSint32(TMEMBER(_scrollPixelsV));
+ persistMgr->transferUint32(TMEMBER(_scrollTimeH));
+ persistMgr->transferUint32(TMEMBER(_scrollTimeV));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER(_targetOffsetLeft));
- persistMgr->transfer(TMEMBER(_targetOffsetTop));
+ persistMgr->transferSint32(TMEMBER(_targetOffsetLeft));
+ persistMgr->transferSint32(TMEMBER(_targetOffsetTop));
_waypointGroups.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_viewport));
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
@@ -2989,4 +2990,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..1f35a776b5 100644
--- a/engines/wintermute/ad/ad_scene.h
+++ b/engines/wintermute/ad/ad_scene.h
@@ -124,7 +124,7 @@ public:
BaseArray<AdObject *> _objects;
BaseArray<AdWaypointGroup *> _waypointGroups;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
int32 _width;
int32 _height;
bool addObject(AdObject *Object);
@@ -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..5f6207c23a 100644
--- a/engines/wintermute/ad/ad_scene_node.cpp
+++ b/engines/wintermute/ad/ad_scene_node.cpp
@@ -74,9 +74,9 @@ bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_entity));
persistMgr->transferPtr(TMEMBER_PTR(_region));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
return STATUS_OK;
}
-} // 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..a4218751c3 100644
--- a/engines/wintermute/ad/ad_scene_state.cpp
+++ b/engines/wintermute/ad/ad_scene_state.cpp
@@ -56,7 +56,7 @@ AdSceneState::~AdSceneState() {
//////////////////////////////////////////////////////////////////////////
bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_filename));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
_nodeStates.persist(persistMgr);
return STATUS_OK;
@@ -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..21ffac5aaf 100644
--- a/engines/wintermute/ad/ad_sentence.cpp
+++ b/engines/wintermute/ad/ad_sentence.cpp
@@ -249,23 +249,23 @@ bool AdSentence::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER_INT(_align));
- persistMgr->transfer(TMEMBER(_currentStance));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER(_currentStance));
persistMgr->transferPtr(TMEMBER_PTR(_currentSprite));
- persistMgr->transfer(TMEMBER(_currentSkelAnim));
- persistMgr->transfer(TMEMBER(_duration));
+ persistMgr->transferCharPtr(TMEMBER(_currentSkelAnim));
+ persistMgr->transferUint32(TMEMBER(_duration));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_pos));
+ persistMgr->transferPoint32(TMEMBER(_pos));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
- persistMgr->transfer(TMEMBER(_soundStarted));
- persistMgr->transfer(TMEMBER(_stances));
- persistMgr->transfer(TMEMBER(_startTime));
+ persistMgr->transferBool(TMEMBER(_soundStarted));
+ persistMgr->transferCharPtr(TMEMBER(_stances));
+ persistMgr->transferUint32(TMEMBER(_startTime));
persistMgr->transferPtr(TMEMBER_PTR(_talkDef));
- persistMgr->transfer(TMEMBER(_tempStance));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_width));
- persistMgr->transfer(TMEMBER(_fixedPos));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_tempStance));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferSint32(TMEMBER(_width));
+ persistMgr->transferBool(TMEMBER(_fixedPos));
+ persistMgr->transferBool(TMEMBER(_freezable));
return STATUS_OK;
}
@@ -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..dd920492de 100644
--- a/engines/wintermute/ad/ad_sprite_set.cpp
+++ b/engines/wintermute/ad/ad_sprite_set.cpp
@@ -60,7 +60,7 @@ AdSpriteSet::~AdSpriteSet() {
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::loadFile(const char *filename, int lifeTime, TSpriteCacheType cacheType) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdSpriteSet::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -93,7 +93,7 @@ TOKEN_DEF(TEMPLATE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
+bool AdSpriteSet::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SPRITESET)
TOKEN_TABLE(NAME)
@@ -109,12 +109,12 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITESET) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SPRITESET) {
_gameRef->LOG(0, "'SPRITESET' keyword expected.");
return STATUS_FAILED;
}
@@ -122,23 +122,23 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
}
BaseSprite *spr = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params, lifeTime, cacheType))) {
+ if (DID_FAIL(loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_LEFT:
delete _sprites[DI_LEFT];
_sprites[DI_LEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_LEFT] = spr;
@@ -149,7 +149,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_RIGHT];
_sprites[DI_RIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_RIGHT] = spr;
@@ -160,7 +160,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UP];
_sprites[DI_UP] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UP] = spr;
@@ -171,7 +171,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWN];
_sprites[DI_DOWN] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWN] = spr;
@@ -182,7 +182,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UPLEFT];
_sprites[DI_UPLEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPLEFT] = spr;
@@ -193,7 +193,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UPRIGHT];
_sprites[DI_UPRIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPRIGHT] = spr;
@@ -204,7 +204,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWNLEFT];
_sprites[DI_DOWNLEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNLEFT] = spr;
@@ -215,7 +215,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWNRIGHT];
_sprites[DI_DOWNRIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNRIGHT] = spr;
@@ -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..ece71f7adb 100644
--- a/engines/wintermute/ad/ad_sprite_set.h
+++ b/engines/wintermute/ad/ad_sprite_set.h
@@ -44,10 +44,10 @@ public:
AdSpriteSet(BaseGame *inGame, BaseObject *owner = nullptr);
virtual ~AdSpriteSet();
bool loadFile(const char *filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
- bool loadBuffer(byte *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
+ bool loadBuffer(char *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
BaseSprite *_sprites[NUM_DIRECTIONS];
};
-} // 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..22e3d7b4cc 100644
--- a/engines/wintermute/ad/ad_talk_def.cpp
+++ b/engines/wintermute/ad/ad_talk_def.cpp
@@ -71,7 +71,7 @@ AdTalkDef::~AdTalkDef() {
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdTalkDef::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -101,7 +101,7 @@ TOKEN_DEF(DEFAULT_SPRITE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
+bool AdTalkDef::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TALK)
TOKEN_TABLE(TEMPLATE)
@@ -112,22 +112,22 @@ bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TALK) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TALK) {
_gameRef->LOG(0, "'TALK' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -145,11 +145,11 @@ bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_DEFAULT_SPRITE:
- BaseUtils::setString(&_defaultSpriteFilename, (char *)params);
+ BaseUtils::setString(&_defaultSpriteFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET_FILE:
- BaseUtils::setString(&_defaultSpriteSetFilename, (char *)params);
+ BaseUtils::setString(&_defaultSpriteSetFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET: {
@@ -209,9 +209,9 @@ bool AdTalkDef::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_defaultSprite));
- persistMgr->transfer(TMEMBER(_defaultSpriteFilename));
+ persistMgr->transferCharPtr(TMEMBER(_defaultSpriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_defaultSpriteSet));
- persistMgr->transfer(TMEMBER(_defaultSpriteSetFilename));
+ persistMgr->transferCharPtr(TMEMBER(_defaultSpriteSetFilename));
_nodes.persist(persistMgr);
@@ -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..5711906b4b 100644
--- a/engines/wintermute/ad/ad_talk_def.h
+++ b/engines/wintermute/ad/ad_talk_def.h
@@ -46,13 +46,13 @@ public:
AdTalkDef(BaseGame *inGame);
virtual ~AdTalkDef();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
BaseArray<AdTalkNode *> _nodes;
char *_defaultSpriteFilename;
BaseSprite *_defaultSprite;
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..6c0d2e1f06 100644
--- a/engines/wintermute/ad/ad_talk_node.cpp
+++ b/engines/wintermute/ad/ad_talk_node.cpp
@@ -79,7 +79,7 @@ TOKEN_DEF(PRECACHE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
+bool AdTalkNode::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ACTION)
TOKEN_TABLE(SPRITESET_FILE)
@@ -92,12 +92,12 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ACTION) {
_gameRef->LOG(0, "'ACTION' keyword expected.");
return STATUS_FAILED;
}
@@ -108,14 +108,14 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
_playToEnd = false;
_preCache = false;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_SPRITE:
- BaseUtils::setString(&_spriteFilename, (char *)params);
+ BaseUtils::setString(&_spriteFilename, params);
break;
case TOKEN_SPRITESET_FILE:
- BaseUtils::setString(&_spriteSetFilename, (char *)params);
+ BaseUtils::setString(&_spriteSetFilename, params);
break;
case TOKEN_SPRITESET: {
@@ -130,20 +130,20 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_START_TIME:
- parser.scanStr((char *)params, "%d", &_startTime);
+ parser.scanStr(params, "%d", &_startTime);
break;
case TOKEN_END_TIME:
- parser.scanStr((char *)params, "%d", &_endTime);
+ parser.scanStr(params, "%d", &_endTime);
break;
case TOKEN_PRECACHE:
- parser.scanStr((char *)params, "%b", &_preCache);
+ parser.scanStr(params, "%b", &_preCache);
break;
case TOKEN_COMMENT:
if (_gameRef->_editorMode) {
- BaseUtils::setString(&_comment, (char *)params);
+ BaseUtils::setString(&_comment, params);
}
break;
@@ -191,14 +191,14 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_comment));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_endTime));
- persistMgr->transfer(TMEMBER(_playToEnd));
+ persistMgr->transferCharPtr(TMEMBER(_comment));
+ persistMgr->transferUint32(TMEMBER(_startTime));
+ persistMgr->transferUint32(TMEMBER(_endTime));
+ persistMgr->transferBool(TMEMBER(_playToEnd));
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
- persistMgr->transfer(TMEMBER(_spriteFilename));
+ persistMgr->transferCharPtr(TMEMBER(_spriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_spriteSet));
- persistMgr->transfer(TMEMBER(_spriteSetFilename));
+ persistMgr->transferCharPtr(TMEMBER(_spriteSetFilename));
return STATUS_OK;
}
@@ -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..7a014b2d9f 100644
--- a/engines/wintermute/ad/ad_talk_node.h
+++ b/engines/wintermute/ad/ad_talk_node.h
@@ -46,7 +46,7 @@ public:
AdTalkNode(BaseGame *inGame);
virtual ~AdTalkNode();
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
char *_spriteFilename;
BaseSprite *_sprite;
@@ -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..ae6b18e266 100644
--- a/engines/wintermute/ad/ad_waypoint_group.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group.cpp
@@ -66,7 +66,7 @@ void AdWaypointGroup::cleanup() {
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdWaypointGroup::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -98,7 +98,7 @@ TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
+bool AdWaypointGroup::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(WAYPOINTS)
TOKEN_TABLE(TEMPLATE)
@@ -110,43 +110,43 @@ bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WAYPOINTS) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_WAYPOINTS) {
_gameRef->LOG(0, "'WAYPOINTS' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_PROPERTY:
@@ -194,11 +194,11 @@ bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
- persistMgr->transfer(TMEMBER(_lastMimicX));
- persistMgr->transfer(TMEMBER(_lastMimicY));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferSint32(TMEMBER(_editorSelectedPoint));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
+ persistMgr->transferSint32(TMEMBER(_lastMimicX));
+ persistMgr->transferSint32(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
return STATUS_OK;
@@ -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..47fd611be6 100644
--- a/engines/wintermute/ad/ad_waypoint_group.h
+++ b/engines/wintermute/ad/ad_waypoint_group.h
@@ -41,7 +41,7 @@ public:
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
AdWaypointGroup(BaseGame *inGame);
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual ~AdWaypointGroup();
bool _active;
@@ -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..6a0666b36e 100644
--- a/engines/wintermute/base/base.cpp
+++ b/engines/wintermute/base/base.cpp
@@ -60,7 +60,7 @@ Common::String BaseClass::getEditorProp(const Common::String &propName, const Co
if (_editorPropsIter != _editorProps.end()) {
return _editorPropsIter->_value.c_str();
} else {
- return initVal;
+ return initVal; // Used to be NULL
}
}
@@ -87,7 +87,7 @@ TOKEN_DEF(NAME)
TOKEN_DEF(VALUE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
+bool BaseClass::parseEditorProperty(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(NAME)
@@ -100,12 +100,12 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
}
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_EDITOR_PROPERTY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDITOR_PROPERTY) {
BaseEngine::LOG(0, "'EDITOR_PROPERTY' keyword expected.");
return STATUS_FAILED;
}
@@ -115,13 +115,13 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
char *propName = nullptr;
char *propValue = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME:
delete[] propName;
- propName = new char[strlen((char *)params) + 1];
+ propName = new char[strlen(params) + 1];
if (propName) {
- strcpy(propName, (char *)params);
+ strcpy(propName, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -129,9 +129,9 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
case TOKEN_VALUE:
delete[] propValue;
- propValue = new char[strlen((char *)params) + 1];
+ propValue = new char[strlen(params) + 1];
if (propValue) {
- strcpy(propValue, (char *)params);
+ strcpy(propValue, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -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..8767cc9bdd 100644
--- a/engines/wintermute/base/base.h
+++ b/engines/wintermute/base/base.h
@@ -44,9 +44,9 @@ class BaseClass {
public:
bool _persistable;
bool setEditorProp(const Common::String &propName, const Common::String &propValue);
- Common::String getEditorProp(const Common::String &propName, const Common::String &initVal = nullptr);
+ Common::String getEditorProp(const Common::String &propName, const Common::String &initVal = Common::String());
BaseClass(TDynamicConstructor, TDynamicConstructor) {}
- bool parseEditorProperty(byte *buffer, bool complete = true);
+ bool parseEditorProperty(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
BaseClass();
BaseClass(BaseGame *GameOwner);
@@ -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..69cc7b02b6 100644
--- a/engines/wintermute/base/base_active_rect.cpp
+++ b/engines/wintermute/base/base_active_rect.cpp
@@ -37,7 +37,7 @@ namespace Wintermute {
//////////////////////////////////////////////////////////////////////
BaseActiveRect::BaseActiveRect(BaseGame *inGame) : BaseClass(inGame) {
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_owner = nullptr;
_frame = nullptr;
_region = nullptr;
@@ -52,7 +52,7 @@ BaseActiveRect::BaseActiveRect(BaseGame *inGame) : BaseClass(inGame) {
BaseActiveRect::BaseActiveRect(BaseGame *inGame, BaseObject *owner, BaseSubFrame *frame, int x, int y, int width, int height, float zoomX, float zoomY, bool precise) : BaseClass(inGame) {
_owner = owner;
_frame = frame;
- BasePlatform::setRect(&_rect, x, y, x + width, y + height);
+ _rect.setRect(x, y, x + width, y + height);
_zoomX = zoomX;
_zoomY = zoomY;
_precise = precise;
@@ -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..c7dac8be27 100644
--- a/engines/wintermute/base/base_fader.cpp
+++ b/engines/wintermute/base/base_fader.cpp
@@ -175,16 +175,16 @@ uint32 BaseFader::getCurrentColor() const {
bool BaseFader::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_blue));
- persistMgr->transfer(TMEMBER(_currentAlpha));
- persistMgr->transfer(TMEMBER(_duration));
- persistMgr->transfer(TMEMBER(_green));
- persistMgr->transfer(TMEMBER(_red));
- persistMgr->transfer(TMEMBER(_sourceAlpha));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_targetAlpha));
- persistMgr->transfer(TMEMBER(_system));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferByte(TMEMBER(_blue));
+ persistMgr->transferByte(TMEMBER(_currentAlpha));
+ persistMgr->transferUint32(TMEMBER(_duration));
+ persistMgr->transferByte(TMEMBER(_green));
+ persistMgr->transferByte(TMEMBER(_red));
+ persistMgr->transferByte(TMEMBER(_sourceAlpha));
+ persistMgr->transferUint32(TMEMBER(_startTime));
+ persistMgr->transferByte(TMEMBER(_targetAlpha));
+ persistMgr->transferBool(TMEMBER(_system));
if (_system && !persistMgr->getIsSaving()) {
_startTime = 0;
@@ -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 4c7c31562d..286f83defe 100644
--- a/engines/wintermute/base/base_file_manager.cpp
+++ b/engines/wintermute/base/base_file_manager.cpp
@@ -168,15 +168,20 @@ bool BaseFileManager::initPaths() {
if (languageSubFolder.exists()) {
addPath(PATH_PACKAGE, languageSubFolder);
}
+ // Also add languages/ for Reversion1.
+ languageSubFolder = gameData.getChild("languages");
+ if (languageSubFolder.exists()) {
+ addPath(PATH_PACKAGE, languageSubFolder);
+ }
return STATUS_OK;
}
bool BaseFileManager::registerPackages(const Common::FSList &fslist) {
for (Common::FSList::const_iterator it = fslist.begin(); it != fslist.end(); ++it) {
- debugC(kWintermuteDebugFileAccess, "Adding %s", (*it).getName().c_str());
- if ((*it).getName().contains(".dcp")) {
- if (registerPackage((*it))) {
- addPath(PATH_PACKAGE, (*it));
+ debugC(kWintermuteDebugFileAccess, "Adding %s", it->getName().c_str());
+ if (it->getName().contains(".dcp")) {
+ if (registerPackage(*it)) {
+ addPath(PATH_PACKAGE, *it);
}
}
}
@@ -187,36 +192,72 @@ bool BaseFileManager::registerPackages(const Common::FSList &fslist) {
bool BaseFileManager::registerPackages() {
debugC(kWintermuteDebugFileAccess | kWintermuteDebugLog, "Scanning packages");
+ // We need the target name as a Common::String to perform some game-specific hacks.
+ Common::String targetName = BaseEngine::instance().getGameTargetName();
+
// Register without using SearchMan, as otherwise the FSNode-based lookup in openPackage will fail
// and that has to be like that to support the detection-scheme.
Common::FSList files;
- for (Common::FSList::iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) {
- debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", (*it).getPath().c_str(), (*it).getName().c_str());
- if ((*it).getChildren(files, Common::FSNode::kListFilesOnly)) {
- warning("getChildren() failed for path: %s", (*it).getDisplayName().c_str());
+ for (Common::FSList::const_iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) {
+ debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", it->getPath().c_str(), it->getName().c_str());
+ if (!it->getChildren(files, Common::FSNode::kListFilesOnly)) {
+ warning("getChildren() failed for path: %s", it->getDisplayName().c_str());
}
- for (Common::FSList::iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
- if (!fileIt->getName().hasSuffix(".dcp")) {
+ for (Common::FSList::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
+ // To prevent any case sensitivity issues we make the filename
+ // all lowercase here. This makes the code slightly prettier
+ // than the equivalent of using equalsIgnoreCase.
+ Common::String fileName = fileIt->getName();
+ fileName.toLowercase();
+
+ if (!fileName.hasSuffix(".dcp")) {
continue;
}
+ // HACK: for Reversion1, avoid loading xlanguage_pt.dcp from the main folder:
+ if (_language != Common::PT_BRA && targetName.hasPrefix("reversion1")) {
+ if (fileName == "xlanguage_pt.dcp") {
+ continue;
+ }
+ }
+
+ // Again, make the parent's name all lowercase to avoid any case
+ // issues.
+ Common::String parentName = fileIt->getParent().getName();
+ parentName.toLowercase();
+
// Avoid registering all the language files
// TODO: Select based on the gameDesc.
- if (_language != Common::UNK_LANG && fileIt->getParent().getName() == "language") {
- Common::String parentName = fileIt->getParent().getName();
- Common::String dcpName = fileIt->getName();
- if (_language == Common::EN_ANY && fileIt->getName() != "english.dcp") {
+ if (_language != Common::UNK_LANG && (parentName == "language" || parentName == "languages")) {
+ // English
+ if (_language == Common::EN_ANY && (fileName != "english.dcp" && fileName != "xlanguage_en.dcp")) {
+ continue;
+ // Chinese
+ } else if (_language == Common::ZH_CNA && (fileName != "chinese.dcp" && fileName != "xlanguage_nz.dcp")) {
+ continue;
+ // Czech
+ } else if (_language == Common::CZ_CZE && (fileName != "czech.dcp" && fileName != "xlanguage_cz.dcp")) {
+ continue;
+ // French
+ } else if (_language == Common::FR_FRA && (fileName != "french.dcp" && fileName != "xlanguage_fr.dcp")) {
+ continue;
+ // German
+ } else if (_language == Common::DE_DEU && (fileName != "german.dcp" && fileName != "xlanguage_de.dcp")) {
continue;
- } else if (_language == Common::CZ_CZE && fileIt->getName() != "czech.dcp") {
+ // Italian
+ } else if (_language == Common::IT_ITA && (fileName != "italian.dcp" && fileName != "xlanguage_it.dcp")) {
continue;
- } else if (_language == Common::IT_ITA && fileIt->getName() != "italian.dcp") {
+ // Polish
+ } else if (_language == Common::PL_POL && (fileName != "polish.dcp" && fileName != "xlanguage_po.dcp")) {
continue;
- } else if (_language == Common::PL_POL && fileIt->getName() != "polish.dcp") {
+ // Portuguese
+ } else if (_language == Common::PT_BRA && (fileName != "portuguese.dcp" && fileName != "xlanguage_pt.dcp")) {
continue;
- } else if (_language == Common::RU_RUS && fileIt->getName() != "russian.dcp") {
+ // Russian
+ } else if (_language == Common::RU_RUS && (fileName != "russian.dcp" && fileName != "xlanguage_ru.dcp")) {
continue;
}
}
- debugC(kWintermuteDebugFileAccess, "Registering %s %s", (*fileIt).getPath().c_str(), (*fileIt).getName().c_str());
+ debugC(kWintermuteDebugFileAccess, "Registering %s %s", fileIt->getPath().c_str(), fileIt->getName().c_str());
registerPackage((*fileIt));
}
}
@@ -250,8 +291,6 @@ Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &f
Common::String upcName = filename;
upcName.toUppercase();
Common::SeekableReadStream *file = nullptr;
- char fileName[MAX_PATH_LENGTH];
- Common::strlcpy(fileName, upcName.c_str(), MAX_PATH_LENGTH);
// correct slashes
for (uint32 i = 0; i < upcName.size(); i++) {
@@ -269,7 +308,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 +399,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..1455733461 100644
--- a/engines/wintermute/base/base_frame.cpp
+++ b/engines/wintermute/base/base_frame.cpp
@@ -142,7 +142,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(KILL_SOUND)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
+bool BaseFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(DELAY)
TOKEN_TABLE(IMAGE)
@@ -181,10 +181,10 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
bool decoration = false;
bool mirrorX = false;
bool mirrorY = false;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
char *surface_file = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, &params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_DELAY:
parser.scanStr(params, "%d", &_delay);
@@ -249,7 +249,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
case TOKEN_SUBFRAME: {
BaseSubFrame *subframe = new BaseSubFrame(_gameRef);
- if (!subframe || DID_FAIL(subframe->loadBuffer((byte *)params, lifeTime, keepLoaded))) {
+ if (!subframe || DID_FAIL(subframe->loadBuffer(params, lifeTime, keepLoaded))) {
delete subframe;
cmd = PARSERR_GENERIC;
} else {
@@ -290,7 +290,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
}
@@ -325,7 +325,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
}
}
- if (BasePlatform::isRectEmpty(&rect)) {
+ if (rect.isRectEmpty()) {
sub->setDefaultRect();
} else {
sub->setRect(rect);
@@ -352,7 +352,7 @@ bool BaseFrame::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, float
if (!rect) {
return false;
}
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
Rect32 subRect;
@@ -414,12 +414,12 @@ bool BaseFrame::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
_applyEvent.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_delay));
- persistMgr->transfer(TMEMBER(_editorExpanded));
- persistMgr->transfer(TMEMBER(_keyframe));
- persistMgr->transfer(TMEMBER(_killSound));
- persistMgr->transfer(TMEMBER(_moveX));
- persistMgr->transfer(TMEMBER(_moveY));
+ persistMgr->transferUint32(TMEMBER(_delay));
+ persistMgr->transferBool(TMEMBER(_editorExpanded));
+ persistMgr->transferBool(TMEMBER(_keyframe));
+ persistMgr->transferBool(TMEMBER(_killSound));
+ persistMgr->transferSint32(TMEMBER(_moveX));
+ persistMgr->transferSint32(TMEMBER(_moveY));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
_subframes.persist(persistMgr);
@@ -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..c4cfc443fa 100644
--- a/engines/wintermute/base/base_frame.h
+++ b/engines/wintermute/base/base_frame.h
@@ -52,7 +52,7 @@ public:
uint32 _delay;
BaseArray<BaseSubFrame *> _subframes;
bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, bool allFrames = false, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
- bool loadBuffer(byte *buffer, int lifeTime, bool keepLoaded);
+ bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
BaseFrame(BaseGame *inGame);
virtual ~BaseFrame();
@@ -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 e97e342149..6b7e1cf803 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;
@@ -185,7 +185,7 @@ BaseGame::BaseGame(const Common::String &gameId) : BaseObject(this), _gameId(gam
_lastCursor = nullptr;
- BasePlatform::setRectEmpty(&_mouseLockRect);
+ _mouseLockRect.setEmpty();
_suppressScriptErrors = false;
_lastMiniUpdate = 0;
@@ -212,7 +212,7 @@ BaseGame::BaseGame(const Common::String &gameId) : BaseObject(this), _gameId(gam
#else*/
_touchInterface = false;
_constrainedMemory = false;
-
+
_settings = new BaseGameSettings(this);
//#endif
@@ -573,7 +573,7 @@ bool BaseGame::initLoop() {
_focusedWindow = nullptr;
for (int i = _windows.size() - 1; i >= 0; i--) {
- if (_windows[i]->_visible) {
+ if (_windows[i]->isVisible()) {
_focusedWindow = _windows[i];
break;
}
@@ -620,7 +620,7 @@ void BaseGame::getOffset(int *offsetX, int *offsetY) const {
//////////////////////////////////////////////////////////////////////////
bool BaseGame::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseGame::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -690,7 +690,7 @@ TOKEN_DEF(GUID)
TOKEN_DEF(COMPAT_KILL_METHOD_THREADS)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseGame::loadBuffer(byte *buffer, bool complete) {
+bool BaseGame::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(GAME)
TOKEN_TABLE(TEMPLATE)
@@ -740,32 +740,32 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
Common::String loadImageName = "";
Common::String saveImageName = "";
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_GAME) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_GAME) {
_gameRef->LOG(0, "'GAME' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_SYSTEM_FONT:
@@ -774,7 +774,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
}
_systemFont = nullptr;
- _systemFont = _gameRef->_fontStorage->addFont((char *)params);
+ _systemFont = _gameRef->_fontStorage->addFont(params);
break;
case TOKEN_VIDEO_FONT:
@@ -783,14 +783,14 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
}
_videoFont = nullptr;
- _videoFont = _gameRef->_fontStorage->addFont((char *)params);
+ _videoFont = _gameRef->_fontStorage->addFont(params);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -801,7 +801,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
delete _activeCursor;
_activeCursor = nullptr;
_activeCursor = new BaseSprite(_gameRef);
- if (!_activeCursor || DID_FAIL(_activeCursor->loadFile((char *)params))) {
+ if (!_activeCursor || DID_FAIL(_activeCursor->loadFile(params))) {
delete _activeCursor;
_activeCursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -811,7 +811,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_NONINTERACTIVE_CURSOR:
delete _cursorNoninteractive;
_cursorNoninteractive = new BaseSprite(_gameRef);
- if (!_cursorNoninteractive || DID_FAIL(_cursorNoninteractive->loadFile((char *)params))) {
+ if (!_cursorNoninteractive || DID_FAIL(_cursorNoninteractive->loadFile(params))) {
delete _cursorNoninteractive;
_cursorNoninteractive = nullptr;
cmd = PARSERR_GENERIC;
@@ -819,23 +819,23 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PERSONAL_SAVEGAMES:
- parser.scanStr((char *)params, "%b", &_personalizedSave);
+ parser.scanStr(params, "%b", &_personalizedSave);
break;
case TOKEN_SUBTITLES:
- parser.scanStr((char *)params, "%b", &_subtitles);
+ parser.scanStr(params, "%b", &_subtitles);
break;
case TOKEN_SUBTITLES_SPEED:
- parser.scanStr((char *)params, "%d", &_subtitlesSpeed);
+ parser.scanStr(params, "%d", &_subtitlesSpeed);
break;
case TOKEN_VIDEO_SUBTITLES:
- parser.scanStr((char *)params, "%b", &_videoSubtitles);
+ parser.scanStr(params, "%b", &_videoSubtitles);
break;
case TOKEN_PROPERTY:
@@ -847,66 +847,66 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_THUMBNAIL_WIDTH:
- parser.scanStr((char *)params, "%d", &_thumbnailWidth);
+ parser.scanStr(params, "%d", &_thumbnailWidth);
break;
case TOKEN_THUMBNAIL_HEIGHT:
- parser.scanStr((char *)params, "%d", &_thumbnailHeight);
+ parser.scanStr(params, "%d", &_thumbnailHeight);
break;
case TOKEN_INDICATOR_X:
- parser.scanStr((char *)params, "%d", &indicatorX);
+ parser.scanStr(params, "%d", &indicatorX);
break;
case TOKEN_INDICATOR_Y:
- parser.scanStr((char *)params, "%d", &indicatorY);
+ parser.scanStr(params, "%d", &indicatorY);
break;
case TOKEN_INDICATOR_COLOR: {
int r, g, b, a;
- parser.scanStr((char *)params, "%d,%d,%d,%d", &r, &g, &b, &a);
+ parser.scanStr(params, "%d,%d,%d,%d", &r, &g, &b, &a);
indicatorColor = BYTETORGBA(r, g, b, a);
}
break;
case TOKEN_INDICATOR_WIDTH:
- parser.scanStr((char *)params, "%d", &indicatorWidth);
+ parser.scanStr(params, "%d", &indicatorWidth);
break;
case TOKEN_INDICATOR_HEIGHT:
- parser.scanStr((char *)params, "%d", &indicatorHeight);
+ parser.scanStr(params, "%d", &indicatorHeight);
break;
case TOKEN_SAVE_IMAGE:
- saveImageName = (char *) params;
+ saveImageName = params;
break;
case TOKEN_SAVE_IMAGE_X:
- parser.scanStr((char *)params, "%d", &saveImageX);
+ parser.scanStr(params, "%d", &saveImageX);
break;
case TOKEN_SAVE_IMAGE_Y:
- parser.scanStr((char *)params, "%d", &saveImageY);
+ parser.scanStr(params, "%d", &saveImageY);
break;
case TOKEN_LOAD_IMAGE:
- loadImageName = (char *) params;
+ loadImageName = params;
break;
case TOKEN_LOAD_IMAGE_X:
- parser.scanStr((char *)params, "%d", &loadImageX);
+ parser.scanStr(params, "%d", &loadImageX);
break;
case TOKEN_LOAD_IMAGE_Y:
- parser.scanStr((char *)params, "%d", &loadImageY);
+ parser.scanStr(params, "%d", &loadImageY);
break;
case TOKEN_LOCAL_SAVE_DIR:
- _localSaveDir = (char *)params;
+ _localSaveDir = params;
break;
case TOKEN_COMPAT_KILL_METHOD_THREADS:
- parser.scanStr((char *)params, "%b", &_compatKillMethodThreads);
+ parser.scanStr(params, "%b", &_compatKillMethodThreads);
break;
}
}
@@ -1123,7 +1123,7 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
BaseUtils::swap(&top, &bottom);
}
- BasePlatform::setRect(&_mouseLockRect, left, top, right, bottom);
+ _mouseLockRect.setRect(left, top, right, bottom);
stack->pushNULL();
return STATUS_OK;
@@ -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;
}
@@ -2558,7 +2554,7 @@ bool BaseGame::displayQuickMsg() {
// update
for (uint32 i = 0; i < _quickMessages.size(); i++) {
- if (_currentTime - _quickMessages[i]->_startTime >= QUICK_MSG_DURATION) {
+ if (_currentTime - _quickMessages[i]->getStartTime() >= QUICK_MSG_DURATION) {
delete _quickMessages[i];
_quickMessages.remove_at(i);
i--;
@@ -2583,7 +2579,7 @@ void BaseGame::quickMessage(const char *text) {
delete _quickMessages[0];
_quickMessages.remove_at(0);
}
- _quickMessages.add(new BaseQuickMsg(_gameRef, text));
+ _quickMessages.add(new BaseQuickMsg(_currentTime, text));
}
@@ -3023,10 +3019,10 @@ bool BaseGame::displayWindows(bool inGame) {
bool res;
// did we lose focus? focus topmost window
- if (_focusedWindow == nullptr || !_focusedWindow->_visible || _focusedWindow->_disable) {
+ if (_focusedWindow == nullptr || !_focusedWindow->isVisible() || _focusedWindow->isDisabled()) {
_focusedWindow = nullptr;
for (int i = _windows.size() - 1; i >= 0; i--) {
- if (_windows[i]->_visible && !_windows[i]->_disable) {
+ if (_windows[i]->isVisible() && !_windows[i]->isDisabled()) {
_focusedWindow = _windows[i];
break;
}
@@ -3035,7 +3031,7 @@ bool BaseGame::displayWindows(bool inGame) {
// display all windows
for (uint32 i = 0; i < _windows.size(); i++) {
- if (_windows[i]->_visible && _windows[i]->_inGame == inGame) {
+ if (_windows[i]->isVisible() && _windows[i]->getInGame() == inGame) {
res = _windows[i]->display();
if (DID_FAIL(res)) {
@@ -3058,61 +3054,61 @@ bool BaseGame::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_activeObject));
persistMgr->transferPtr(TMEMBER_PTR(_capturedObject));
persistMgr->transferPtr(TMEMBER_PTR(_cursorNoninteractive));
- persistMgr->transfer(TMEMBER(_editorMode));
+ persistMgr->transferBool(TMEMBER(_editorMode));
persistMgr->transferPtr(TMEMBER_PTR(_fader));
- persistMgr->transfer(TMEMBER(_freezeLevel));
+ persistMgr->transferSint32(TMEMBER(_freezeLevel));
persistMgr->transferPtr(TMEMBER_PTR(_focusedWindow));
persistMgr->transferPtr(TMEMBER_PTR(_fontStorage));
- persistMgr->transfer(TMEMBER(_interactive));
+ persistMgr->transferBool(TMEMBER(_interactive));
persistMgr->transferPtr(TMEMBER_PTR(_keyboardState));
- persistMgr->transfer(TMEMBER(_lastTime));
+ persistMgr->transferUint32(TMEMBER(_lastTime));
persistMgr->transferPtr(TMEMBER_PTR(_mainObject));
_musicSystem->persistChannels(persistMgr);
_musicSystem->persistCrossfadeSettings(persistMgr);
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_offsetPercentX));
- persistMgr->transfer(TMEMBER(_offsetPercentY));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentX));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentY));
- persistMgr->transfer(TMEMBER(_origInteractive));
- persistMgr->transfer(TMEMBER_INT(_origState));
- persistMgr->transfer(TMEMBER(_personalizedSave));
- persistMgr->transfer(TMEMBER(_quitting));
+ persistMgr->transferBool(TMEMBER(_origInteractive));
+ persistMgr->transferSint32(TMEMBER_INT(_origState));
+ persistMgr->transferBool(TMEMBER(_personalizedSave));
+ persistMgr->transferBool(TMEMBER(_quitting));
_regObjects.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_scEngine));
//persistMgr->transfer(TMEMBER(_soundMgr));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
//persistMgr->transfer(TMEMBER(_surfaceStorage));
- persistMgr->transfer(TMEMBER(_subtitles));
- persistMgr->transfer(TMEMBER(_subtitlesSpeed));
+ persistMgr->transferBool(TMEMBER(_subtitles));
+ persistMgr->transferSint32(TMEMBER(_subtitlesSpeed));
persistMgr->transferPtr(TMEMBER_PTR(_systemFont));
persistMgr->transferPtr(TMEMBER_PTR(_videoFont));
- persistMgr->transfer(TMEMBER(_videoSubtitles));
+ persistMgr->transferBool(TMEMBER(_videoSubtitles));
_timerNormal.persist(persistMgr);
_timerLive.persist(persistMgr);
_renderer->persistSaveLoadImages(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_textEncoding));
- persistMgr->transfer(TMEMBER(_textRTL));
+ persistMgr->transferSint32(TMEMBER_INT(_textEncoding));
+ persistMgr->transferBool(TMEMBER(_textRTL));
- persistMgr->transfer(TMEMBER(_soundBufferSizeSec));
- persistMgr->transfer(TMEMBER(_suspendedRendering));
+ persistMgr->transferSint32(TMEMBER(_soundBufferSizeSec));
+ persistMgr->transferBool(TMEMBER(_suspendedRendering));
- persistMgr->transfer(TMEMBER(_mouseLockRect));
+ persistMgr->transferRect32(TMEMBER(_mouseLockRect));
_windows.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_suppressScriptErrors));
- persistMgr->transfer(TMEMBER(_autorunDisabled));
+ persistMgr->transferBool(TMEMBER(_suppressScriptErrors));
+ persistMgr->transferBool(TMEMBER(_autorunDisabled));
- persistMgr->transfer(TMEMBER(_autoSaveOnExit));
- persistMgr->transfer(TMEMBER(_autoSaveSlot));
- persistMgr->transfer(TMEMBER(_cursorHidden));
+ persistMgr->transferBool(TMEMBER(_autoSaveOnExit));
+ persistMgr->transferUint32(TMEMBER(_autoSaveSlot));
+ persistMgr->transferBool(TMEMBER(_cursorHidden));
if (!persistMgr->getIsSaving()) {
_quitting = false;
@@ -3135,7 +3131,7 @@ bool BaseGame::focusWindow(UIWindow *window) {
_gameRef->_focusedWindow = window;
}
- if (window->_mode == WINDOW_NORMAL && prev != window && _gameRef->validObject(prev) && (prev->_mode == WINDOW_EXCLUSIVE || prev->_mode == WINDOW_SYSTEM_EXCLUSIVE)) {
+ if (window->getMode() == WINDOW_NORMAL && prev != window && _gameRef->validObject(prev) && (prev->getMode() == WINDOW_EXCLUSIVE || prev->getMode() == WINDOW_SYSTEM_EXCLUSIVE)) {
return focusWindow(prev);
} else {
return STATUS_OK;
@@ -3365,10 +3361,10 @@ bool BaseGame::getCurrentViewportRect(Rect32 *rect, bool *custom) const {
*custom = true;
}
} else {
- BasePlatform::setRect(rect, _renderer->_drawOffsetX,
- _renderer->_drawOffsetY,
- _renderer->getWidth() + _renderer->_drawOffsetX,
- _renderer->getHeight() + _renderer->_drawOffsetY);
+ rect->setRect(_renderer->_drawOffsetX,
+ _renderer->_drawOffsetY,
+ _renderer->getWidth() + _renderer->_drawOffsetX,
+ _renderer->getHeight() + _renderer->_drawOffsetY);
if (custom) {
*custom = false;
}
@@ -3581,7 +3577,6 @@ bool BaseGame::onMouseLeftDown() {
_capturedObject = _activeObject;
}
_mouseLeftDown = true;
- BasePlatform::setCapture(/*_renderer->_window*/);
return STATUS_OK;
}
@@ -3592,7 +3587,6 @@ bool BaseGame::onMouseLeftUp() {
_activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
}
- BasePlatform::releaseCapture();
_capturedObject = nullptr;
_mouseLeftDown = false;
@@ -3734,7 +3728,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 +3896,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..742d6f548d 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,14 +150,14 @@ public:
BaseScriptable *_mathClass;
BaseSurfaceStorage *_surfaceStorage;
BaseFontStorage *_fontStorage;
- BaseGame(const Common::String &gameId);
+ BaseGame(const Common::String &targetName);
virtual ~BaseGame();
bool _debugDebugMode;
int32 _sequence;
virtual bool loadFile(const char *filename);
- virtual bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool loadBuffer(char *buffer, bool complete = true);
int32 _viewportSP;
@@ -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..8894fb843f 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,28 +205,28 @@ 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;
}
bool BaseGameMusic::persistChannels(BasePersistenceManager *persistMgr) {
for (int i = 0; i < NUM_MUSIC_CHANNELS; i++) {
persistMgr->transferPtr(TMEMBER_PTR(_music[i]));
- persistMgr->transfer(TMEMBER(_musicStartTime[i]));
+ persistMgr->transferUint32(TMEMBER(_musicStartTime[i]));
}
return true;
}
bool BaseGameMusic::persistCrossfadeSettings(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_musicCrossfadeRunning));
- persistMgr->transfer(TMEMBER(_musicCrossfadeStartTime));
- persistMgr->transfer(TMEMBER(_musicCrossfadeLength));
- persistMgr->transfer(TMEMBER(_musicCrossfadeChannel1));
- persistMgr->transfer(TMEMBER(_musicCrossfadeChannel2));
- persistMgr->transfer(TMEMBER(_musicCrossfadeSwap));
+ persistMgr->transferBool(TMEMBER(_musicCrossfadeRunning));
+ persistMgr->transferUint32(TMEMBER(_musicCrossfadeStartTime));
+ persistMgr->transferUint32(TMEMBER(_musicCrossfadeLength));
+ persistMgr->transferSint32(TMEMBER(_musicCrossfadeChannel1));
+ persistMgr->transferSint32(TMEMBER(_musicCrossfadeChannel2));
+ persistMgr->transferBool(TMEMBER(_musicCrossfadeSwap));
return true;
}
@@ -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..43809b5d1e 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,90 +101,90 @@ bool BaseGameSettings::loadSettings(const char *filename) {
TOKEN_TABLE(SAVED_GAME_EXT)
TOKEN_TABLE(GUID)
TOKEN_TABLE_END
-
-
- byte *origBuffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+
+
+ char *origBuffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (origBuffer == nullptr) {
BaseEngine::LOG(0, "BaseGame::LoadSettings failed for file '%s'", filename);
return STATUS_FAILED;
}
-
+
bool ret = STATUS_OK;
-
- byte *buffer = origBuffer;
- byte *params;
+
+ char *buffer = origBuffer;
+ char *params;
int cmd;
BaseParser parser;
-
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SETTINGS) {
+
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SETTINGS) {
BaseEngine::LOG(0, "'SETTINGS' keyword expected in game settings file.");
return STATUS_FAILED;
}
buffer = params;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_GAME:
delete[] _gameFile;
- _gameFile = new char[strlen((char *)params) + 1];
+ _gameFile = new char[strlen(params) + 1];
if (_gameFile) {
- strcpy(_gameFile, (char *)params);
+ strcpy(_gameFile, params);
}
break;
-
+
case TOKEN_STRING_TABLE:
- if (DID_FAIL(_stringTable->loadFile((char *)params))) {
+ if (DID_FAIL(_stringTable->loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
-
+
case TOKEN_RESOLUTION:
- parser.scanStr((char *)params, "%d,%d", &_resWidth, &_resHeight);
+ parser.scanStr(params, "%d,%d", &_resWidth, &_resHeight);
break;
-
+
case TOKEN_REQUIRE_3D_ACCELERATION:
- parser.scanStr((char *)params, "%b", &_requireAcceleration);
+ parser.scanStr(params, "%b", &_requireAcceleration);
break;
-
+
case TOKEN_REQUIRE_SOUND:
- parser.scanStr((char *)params, "%b", &_requireSound);
+ parser.scanStr(params, "%b", &_requireSound);
break;
-
+
case TOKEN_HWTL_MODE:
- parser.scanStr((char *)params, "%d", &_TLMode);
+ parser.scanStr(params, "%d", &_TLMode);
break;
-
+
case TOKEN_ALLOW_WINDOWED_MODE:
- parser.scanStr((char *)params, "%b", &_allowWindowed);
+ parser.scanStr(params, "%b", &_allowWindowed);
break;
-
+
case TOKEN_ALLOW_DESKTOP_RES:
- parser.scanStr((char *)params, "%b", &_allowDesktopRes);
+ parser.scanStr(params, "%b", &_allowDesktopRes);
break;
-
+
case TOKEN_ALLOW_ADVANCED:
- parser.scanStr((char *)params, "%b", &_allowAdvanced);
+ parser.scanStr(params, "%b", &_allowAdvanced);
break;
-
+
case TOKEN_ALLOW_ACCESSIBILITY_TAB:
- parser.scanStr((char *)params, "%b", &_allowAccessTab);
+ parser.scanStr(params, "%b", &_allowAccessTab);
break;
-
+
case TOKEN_ALLOW_ABOUT_TAB:
- parser.scanStr((char *)params, "%b", &_allowAboutTab);
+ parser.scanStr(params, "%b", &_allowAboutTab);
break;
-
+
case TOKEN_REGISTRY_PATH:
- //BaseEngine::instance().getRegistry()->setBasePath((char *)params);
+ //BaseEngine::instance().getRegistry()->setBasePath(params);
break;
-
+
case TOKEN_RICH_SAVED_GAMES:
- parser.scanStr((char *)params, "%b", &_richSavedGames);
+ parser.scanStr(params, "%b", &_richSavedGames);
break;
-
+
case TOKEN_SAVED_GAME_EXT:
- _savedGameExt = (char *)params;
+ _savedGameExt = params;
break;
-
+
case TOKEN_GUID:
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..77469e07a5 100644
--- a/engines/wintermute/base/base_keyboard_state.cpp
+++ b/engines/wintermute/base/base_keyboard_state.cpp
@@ -221,12 +221,12 @@ bool BaseKeyboardState::persist(BasePersistenceManager *persistMgr) {
//if (!persistMgr->getIsSaving()) cleanup();
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_currentAlt));
- persistMgr->transfer(TMEMBER(_currentCharCode));
- persistMgr->transfer(TMEMBER(_currentControl));
- persistMgr->transfer(TMEMBER(_currentKeyData));
- persistMgr->transfer(TMEMBER(_currentPrintable));
- persistMgr->transfer(TMEMBER(_currentShift));
+ persistMgr->transferBool(TMEMBER(_currentAlt));
+ persistMgr->transferUint32(TMEMBER(_currentCharCode));
+ persistMgr->transferBool(TMEMBER(_currentControl));
+ persistMgr->transferUint32(TMEMBER(_currentKeyData));
+ persistMgr->transferBool(TMEMBER(_currentPrintable));
+ persistMgr->transferBool(TMEMBER(_currentShift));
if (!persistMgr->getIsSaving()) {
_keyStates = new uint8[323]; // Hardcoded size for the common/keyboard.h enum
@@ -276,17 +276,21 @@ uint32 BaseKeyboardState::keyCodeToVKey(Common::Event *event) {
}
enum VKeyCodes {
- kVkSpace = 32,
- kVkLeft = 37,
- kVkUp = 38,
- kVkRight = 39,
- kVkDown = 40
+ kVkEscape = 27,
+ kVkSpace = 32,
+ kVkLeft = 37,
+ kVkUp = 38,
+ kVkRight = 39,
+ kVkDown = 40
};
//////////////////////////////////////////////////////////////////////////
Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
// todo
switch (vkey) {
+ case kVkEscape:
+ return Common::KEYCODE_ESCAPE;
+ break;
case kVkSpace:
return Common::KEYCODE_SPACE;
break;
@@ -310,4 +314,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..540c7dd164 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -63,7 +63,7 @@ BaseObject::BaseObject(BaseGame *inGame) : BaseScriptHolder(inGame) {
_iD = _gameRef->getSequence();
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_rectSet = false;
_cursor = nullptr;
@@ -953,53 +953,53 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
BaseScriptHolder::persist(persistMgr);
for (int i = 0; i < 7; i++) {
- persistMgr->transfer(TMEMBER(_caption[i]));
+ persistMgr->transferCharPtr(TMEMBER(_caption[i]));
}
persistMgr->transferPtr(TMEMBER_PTR(_activeCursor));
- persistMgr->transfer(TMEMBER(_alphaColor));
- persistMgr->transfer(TMEMBER(_autoSoundPanning));
+ persistMgr->transferUint32(TMEMBER(_alphaColor));
+ persistMgr->transferBool(TMEMBER(_autoSoundPanning));
persistMgr->transferPtr(TMEMBER_PTR(_cursor));
- persistMgr->transfer(TMEMBER(_sharedCursors));
- persistMgr->transfer(TMEMBER(_editorAlwaysRegister));
- persistMgr->transfer(TMEMBER(_editorOnly));
- persistMgr->transfer(TMEMBER(_editorSelected));
- persistMgr->transfer(TMEMBER(_iD));
- persistMgr->transfer(TMEMBER(_is3D));
- persistMgr->transfer(TMEMBER(_movable));
- persistMgr->transfer(TMEMBER(_posX));
- persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_relativeScale));
- persistMgr->transfer(TMEMBER(_rotatable));
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferBool(TMEMBER(_sharedCursors));
+ persistMgr->transferBool(TMEMBER(_editorAlwaysRegister));
+ persistMgr->transferBool(TMEMBER(_editorOnly));
+ persistMgr->transferBool(TMEMBER(_editorSelected));
+ persistMgr->transferSint32(TMEMBER(_iD));
+ persistMgr->transferBool(TMEMBER(_is3D));
+ persistMgr->transferBool(TMEMBER(_movable));
+ persistMgr->transferSint32(TMEMBER(_posX));
+ persistMgr->transferSint32(TMEMBER(_posY));
+ persistMgr->transferFloat(TMEMBER(_relativeScale));
+ persistMgr->transferBool(TMEMBER(_rotatable));
+ persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transferPtr(TMEMBER_PTR(_sFX));
- persistMgr->transfer(TMEMBER(_sFXStart));
- persistMgr->transfer(TMEMBER(_sFXVolume));
- persistMgr->transfer(TMEMBER(_ready));
- persistMgr->transfer(TMEMBER(_rect));
- persistMgr->transfer(TMEMBER(_rectSet));
- persistMgr->transfer(TMEMBER(_registrable));
- persistMgr->transfer(TMEMBER(_shadowable));
- persistMgr->transfer(TMEMBER(_soundEvent));
- persistMgr->transfer(TMEMBER(_zoomable));
+ persistMgr->transferUint32(TMEMBER(_sFXStart));
+ persistMgr->transferSint32(TMEMBER(_sFXVolume));
+ persistMgr->transferBool(TMEMBER(_ready));
+ persistMgr->transferRect32(TMEMBER(_rect));
+ persistMgr->transferBool(TMEMBER(_rectSet));
+ persistMgr->transferBool(TMEMBER(_registrable));
+ persistMgr->transferBool(TMEMBER(_shadowable));
+ persistMgr->transferCharPtr(TMEMBER(_soundEvent));
+ persistMgr->transferBool(TMEMBER(_zoomable));
- persistMgr->transfer(TMEMBER(_scaleX));
- persistMgr->transfer(TMEMBER(_scaleY));
+ persistMgr->transferFloat(TMEMBER(_scaleX));
+ persistMgr->transferFloat(TMEMBER(_scaleY));
- persistMgr->transfer(TMEMBER(_rotate));
- persistMgr->transfer(TMEMBER(_rotateValid));
- persistMgr->transfer(TMEMBER(_relativeRotate));
+ persistMgr->transferFloat(TMEMBER(_rotate));
+ persistMgr->transferBool(TMEMBER(_rotateValid));
+ persistMgr->transferFloat(TMEMBER(_relativeRotate));
- persistMgr->transfer(TMEMBER(_saveState));
- persistMgr->transfer(TMEMBER(_nonIntMouseEvents));
+ persistMgr->transferBool(TMEMBER(_saveState));
+ persistMgr->transferBool(TMEMBER(_nonIntMouseEvents));
- persistMgr->transfer(TMEMBER_INT(_sFXType));
- persistMgr->transfer(TMEMBER(_sFXParam1));
- persistMgr->transfer(TMEMBER(_sFXParam2));
- persistMgr->transfer(TMEMBER(_sFXParam3));
- persistMgr->transfer(TMEMBER(_sFXParam4));
+ persistMgr->transferSint32(TMEMBER_INT(_sFXType));
+ persistMgr->transferFloat(TMEMBER(_sFXParam1));
+ persistMgr->transferFloat(TMEMBER(_sFXParam2));
+ persistMgr->transferFloat(TMEMBER(_sFXParam3));
+ persistMgr->transferFloat(TMEMBER(_sFXParam4));
- persistMgr->transfer(TMEMBER_INT(_blendMode));
+ persistMgr->transferSint32(TMEMBER_INT(_blendMode));
return STATUS_OK;
}
@@ -1039,7 +1039,7 @@ bool BaseObject::setActiveCursor(const char *filename) {
//////////////////////////////////////////////////////////////////////////
-int BaseObject::getHeight() {
+int32 BaseObject::getHeight() {
return 0;
}
@@ -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..a190b1bcb4 100644
--- a/engines/wintermute/base/base_object.h
+++ b/engines/wintermute/base/base_object.h
@@ -89,7 +89,7 @@ public:
virtual bool handleMouseWheel(int delta);
virtual bool handleMouse(TMouseEvent event, TMouseButton button);
virtual bool handleKeypress(Common::Event *event, bool printable = false);
- virtual int getHeight();
+ virtual int32 getHeight();
bool setCursor(const char *filename);
bool setActiveCursor(const char *filename);
bool cleanup();
@@ -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..ff9c6c81b0 100644
--- a/engines/wintermute/base/base_parser.cpp
+++ b/engines/wintermute/base/base_parser.cpp
@@ -250,10 +250,10 @@ Common::String BaseParser::getToken(char **buf) {
*t++ = 0;
} else if (*b == 0) {
*buf = b;
- return nullptr;
+ return Common::String();
} else {
// Error.
- return nullptr;
+ return Common::String();
}
*buf = b;
@@ -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..3d0fc0e925 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';
-
- Common::String retString = ret;
- delete[] ret;
+ uint32 len = strlen(val);
- 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);
}
@@ -580,7 +587,7 @@ double BasePersistenceManager::getDouble() {
//////////////////////////////////////////////////////////////////////////
// bool
-bool BasePersistenceManager::transfer(const char *name, bool *val) {
+bool BasePersistenceManager::transferBool(const char *name, bool *val) {
if (_saving) {
_saveStream->writeByte(*val);
if (_saveStream->err()) {
@@ -599,7 +606,7 @@ bool BasePersistenceManager::transfer(const char *name, bool *val) {
//////////////////////////////////////////////////////////////////////////
// int
-bool BasePersistenceManager::transfer(const char *name, int32 *val) {
+bool BasePersistenceManager::transferSint32(const char *name, int32 *val) {
if (_saving) {
_saveStream->writeSint32LE(*val);
if (_saveStream->err()) {
@@ -618,7 +625,7 @@ bool BasePersistenceManager::transfer(const char *name, int32 *val) {
//////////////////////////////////////////////////////////////////////////
// DWORD
-bool BasePersistenceManager::transfer(const char *name, uint32 *val) {
+bool BasePersistenceManager::transferUint32(const char *name, uint32 *val) {
if (_saving) {
_saveStream->writeUint32LE(*val);
if (_saveStream->err()) {
@@ -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()) {
@@ -656,7 +663,7 @@ bool BasePersistenceManager::transfer(const char *name, float *val) {
//////////////////////////////////////////////////////////////////////////
// double
-bool BasePersistenceManager::transfer(const char *name, double *val) {
+bool BasePersistenceManager::transferDouble(const char *name, double *val) {
if (_saving) {
putDouble(*val);
if (_saveStream->err()) {
@@ -675,7 +682,7 @@ bool BasePersistenceManager::transfer(const char *name, double *val) {
//////////////////////////////////////////////////////////////////////////
// char*
-bool BasePersistenceManager::transfer(const char *name, char **val) {
+bool BasePersistenceManager::transferCharPtr(const char *name, char **val) {
if (_saving) {
putString(*val);
return STATUS_OK;
@@ -692,7 +699,7 @@ bool BasePersistenceManager::transfer(const char *name, char **val) {
//////////////////////////////////////////////////////////////////////////
// const char*
-bool BasePersistenceManager::transfer(const char *name, const char **val) {
+bool BasePersistenceManager::transferConstChar(const char *name, const char **val) {
if (_saving) {
putString(*val);
return STATUS_OK;
@@ -709,9 +716,9 @@ bool BasePersistenceManager::transfer(const char *name, const char **val) {
//////////////////////////////////////////////////////////////////////////
// Common::String
-bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
+bool BasePersistenceManager::transferString(const char *name, Common::String *val) {
if (_saving) {
- putString(*val);
+ putString(val->c_str());
return STATUS_OK;
} else {
char *str = getString();
@@ -730,39 +737,8 @@ bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
}
//////////////////////////////////////////////////////////////////////////
-bool BasePersistenceManager::transfer(const char *name, AnsiStringArray &val) {
- size_t size;
-
- if (_saving) {
- size = val.size();
- _saveStream->writeUint32LE(size);
-
- for (AnsiStringArray::iterator it = val.begin(); it != val.end(); ++it) {
- putString((*it).c_str());
- }
- } else {
- val.clear();
- size = _loadStream->readUint32LE();
-
- for (size_t i = 0; i < size; i++) {
- char *str = getString();
- if (_loadStream->err()) {
- delete[] str;
- return STATUS_FAILED;
- }
- if (str) {
- val.push_back(str);
- }
- delete[] str;
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
// BYTE
-bool BasePersistenceManager::transfer(const char *name, byte *val) {
+bool BasePersistenceManager::transferByte(const char *name, byte *val) {
if (_saving) {
_saveStream->writeByte(*val);
if (_saveStream->err()) {
@@ -781,7 +757,7 @@ bool BasePersistenceManager::transfer(const char *name, byte *val) {
//////////////////////////////////////////////////////////////////////////
// RECT
-bool BasePersistenceManager::transfer(const char *name, Rect32 *val) {
+bool BasePersistenceManager::transferRect32(const char *name, Rect32 *val) {
if (_saving) {
_saveStream->writeSint32LE(val->left);
_saveStream->writeSint32LE(val->top);
@@ -806,7 +782,7 @@ bool BasePersistenceManager::transfer(const char *name, Rect32 *val) {
//////////////////////////////////////////////////////////////////////////
// POINT
-bool BasePersistenceManager::transfer(const char *name, Point32 *val) {
+bool BasePersistenceManager::transferPoint32(const char *name, Point32 *val) {
if (_saving) {
_saveStream->writeSint32LE(val->x);
_saveStream->writeSint32LE(val->y);
@@ -827,7 +803,7 @@ bool BasePersistenceManager::transfer(const char *name, Point32 *val) {
//////////////////////////////////////////////////////////////////////////
// Vector2
-bool BasePersistenceManager::transfer(const char *name, Vector2 *val) {
+bool BasePersistenceManager::transferVector2(const char *name, Vector2 *val) {
if (_saving) {
putFloat(val->x);
putFloat(val->y);
@@ -887,4 +863,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..43259b26ff 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();
@@ -74,19 +74,18 @@ public:
byte *_richBuffer;
bool transferPtr(const char *name, void *val);
- bool transfer(const char *name, int32 *val);
- bool transfer(const char *name, uint32 *val);
- bool transfer(const char *name, float *val);
- bool transfer(const char *name, double *val);
- bool transfer(const char *name, bool *val);
- bool transfer(const char *name, byte *val);
- bool transfer(const char *name, Rect32 *val);
- bool transfer(const char *name, Point32 *val);
- bool transfer(const char *name, const char **val);
- bool transfer(const char *name, char **val);
- bool transfer(const char *name, Common::String *val);
- bool transfer(const char *name, Vector2 *val);
- bool transfer(const char *name, AnsiStringArray &Val);
+ bool transferSint32(const char *name, int32 *val);
+ bool transferUint32(const char *name, uint32 *val);
+ bool transferFloat(const char *name, float *val);
+ bool transferDouble(const char *name, double *val);
+ bool transferBool(const char *name, bool *val);
+ bool transferByte(const char *name, byte *val);
+ bool transferRect32(const char *name, Rect32 *val);
+ bool transferPoint32(const char *name, Point32 *val);
+ bool transferConstChar(const char *name, const char **val);
+ bool transferCharPtr(const char *name, char **val);
+ bool transferString(const char *name, Common::String *val);
+ bool transferVector2(const char *name, Vector2 *val);
BasePersistenceManager(const char *savePrefix = nullptr, bool deleteSingleton = false);
virtual ~BasePersistenceManager();
bool checkVersion(byte verMajor, byte verMinor, byte verBuild);
@@ -115,6 +114,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..84b6a629c7 100644
--- a/engines/wintermute/base/base_point.cpp
+++ b/engines/wintermute/base/base_point.cpp
@@ -54,10 +54,10 @@ BasePoint::BasePoint(int initX, int initY) {
//////////////////////////////////////////////////////////////////////////
bool BasePoint::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(x));
- persistMgr->transfer(TMEMBER(y));
+ persistMgr->transferSint32(TMEMBER(x));
+ persistMgr->transferSint32(TMEMBER(y));
return STATUS_OK;
}
-} // 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 50a9031eee..ac0c107d3b 100644
--- a/engines/wintermute/base/base_quick_msg.cpp
+++ b/engines/wintermute/base/base_quick_msg.cpp
@@ -27,14 +27,13 @@
*/
#include "engines/wintermute/base/base_quick_msg.h"
-#include "engines/wintermute/base/base_game.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
-BaseQuickMsg::BaseQuickMsg(BaseGame *inGame, const char *text) {
+BaseQuickMsg::BaseQuickMsg(uint32 startTime, const char *text) {
_text = text;
- _startTime = _gameRef->_currentTime;
+ _startTime = startTime;
}
@@ -48,4 +47,9 @@ const char *BaseQuickMsg::getText() const {
return _text.c_str();
}
-} // end of namespace Wintermute
+//////////////////////////////////////////////////////////////////////////
+uint32 BaseQuickMsg::getStartTime() const {
+ return _startTime;
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/base/base_quick_msg.h b/engines/wintermute/base/base_quick_msg.h
index 0d342b3b12..b706424c18 100644
--- a/engines/wintermute/base/base_quick_msg.h
+++ b/engines/wintermute/base/base_quick_msg.h
@@ -32,18 +32,18 @@
#include "common/str.h"
namespace Wintermute {
-class BaseGame;
+
class BaseQuickMsg {
public:
const char *getText() const;
- uint32 _startTime;
- BaseQuickMsg(BaseGame *inGame, const char *text);
+ uint32 getStartTime() const;
+ BaseQuickMsg(uint32 startTime, const char *text);
virtual ~BaseQuickMsg();
private:
- BaseGame *_gameRef;
Common::String _text;
+ 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..dc17b18ea2 100644
--- a/engines/wintermute/base/base_region.cpp
+++ b/engines/wintermute/base/base_region.cpp
@@ -48,7 +48,7 @@ BaseRegion::BaseRegion(BaseGame *inGame) : BaseObject(inGame) {
_lastMimicScale = -1;
_lastMimicX = _lastMimicY = INT_MIN;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
}
@@ -65,7 +65,7 @@ void BaseRegion::cleanup() {
}
_points.clear();
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_editorSelectedPoint = -1;
}
@@ -102,7 +102,7 @@ bool BaseRegion::pointInRegion(int x, int y) {
//////////////////////////////////////////////////////////////////////////
bool BaseRegion::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
BaseEngine::LOG(0, "BaseRegion::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -135,7 +135,7 @@ TOKEN_DEF(EDITOR_SELECTED_POINT)
TOKEN_DEF(PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
+bool BaseRegion::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(REGION)
TOKEN_TABLE(TEMPLATE)
@@ -148,12 +148,12 @@ bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
BaseEngine::LOG(0, "'REGION' keyword expected.");
return STATUS_FAILED;
}
@@ -165,39 +165,39 @@ bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
}
_points.clear();
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_PROPERTY:
@@ -430,11 +430,11 @@ bool BaseRegion::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
- persistMgr->transfer(TMEMBER(_lastMimicX));
- persistMgr->transfer(TMEMBER(_lastMimicY));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferSint32(TMEMBER(_editorSelectedPoint));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
+ persistMgr->transferSint32(TMEMBER(_lastMimicX));
+ persistMgr->transferSint32(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
return STATUS_OK;
@@ -491,7 +491,7 @@ bool BaseRegion::ptInPolygon(int32 x, int32 y) {
//////////////////////////////////////////////////////////////////////////
bool BaseRegion::getBoundingRect(Rect32 *rect) {
if (_points.size() == 0) {
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
} else {
int32 minX = INT_MAX, minY = INT_MAX, maxX = INT_MIN, maxY = INT_MIN;
@@ -502,7 +502,7 @@ bool BaseRegion::getBoundingRect(Rect32 *rect) {
maxX = MAX(maxX, _points[i]->x);
maxY = MAX(maxY, _points[i]->y);
}
- BasePlatform::setRect(rect, minX, minY, maxX, maxY);
+ rect->setRect(minX, minY, maxX, maxY);
}
return STATUS_OK;
}
@@ -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..846dcfc341 100644
--- a/engines/wintermute/base/base_region.h
+++ b/engines/wintermute/base/base_region.h
@@ -48,7 +48,7 @@ public:
bool pointInRegion(int x, int y);
bool createRegion();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
Rect32 _rect;
BaseArray<BasePoint *> _points;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) { return saveAsText(buffer, indent, nullptr); }
@@ -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..5fb0b62713 100644
--- a/engines/wintermute/base/base_script_holder.cpp
+++ b/engines/wintermute/base/base_script_holder.cpp
@@ -280,14 +280,14 @@ bool BaseScriptHolder::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool BaseScriptHolder::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferBool(TMEMBER(_freezable));
if (persistMgr->getIsSaving()) {
const char *name = getName();
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
} else {
char *name;
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferCharPtr(TMEMBER(name));
setName(name);
delete[] name;
}
@@ -370,19 +370,19 @@ TOKEN_DEF(NAME)
TOKEN_DEF(VALUE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
+bool BaseScriptHolder::parseProperty(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(NAME)
TOKEN_TABLE(VALUE)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_PROPERTY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_PROPERTY) {
BaseEngine::LOG(0, "'PROPERTY' keyword expected.");
return STATUS_FAILED;
}
@@ -392,13 +392,13 @@ bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
char *propName = nullptr;
char *propValue = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME:
delete[] propName;
- propName = new char[strlen((char *)params) + 1];
+ propName = new char[strlen(params) + 1];
if (propName) {
- strcpy(propName, (char *)params);
+ strcpy(propName, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -406,9 +406,9 @@ bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
case TOKEN_VALUE:
delete[] propValue;
- propValue = new char[strlen((char *)params) + 1];
+ propValue = new char[strlen(params) + 1];
if (propValue) {
- strcpy(propValue, (char *)params);
+ strcpy(propValue, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -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..b4e22a59ee 100644
--- a/engines/wintermute/base/base_script_holder.h
+++ b/engines/wintermute/base/base_script_holder.h
@@ -53,7 +53,7 @@ public:
bool applyEvent(const char *eventName, bool unbreakable = false);
void setFilename(const char *filename);
const char *getFilename() { return _filename; }
- bool parseProperty(byte *buffer, bool complete = true);
+ bool parseProperty(char *buffer, bool complete = true);
bool _freezable;
bool _ready;
@@ -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..d2ff627f0a 100644
--- a/engines/wintermute/base/base_scriptable.cpp
+++ b/engines/wintermute/base/base_scriptable.cpp
@@ -153,7 +153,7 @@ void BaseScriptable::scSetBool(bool val) {
//////////////////////////////////////////////////////////////////////////
bool BaseScriptable::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_refCount));
+ persistMgr->transferSint32(TMEMBER(_refCount));
persistMgr->transferPtr(TMEMBER_PTR(_scProp));
persistMgr->transferPtr(TMEMBER_PTR(_scValue));
@@ -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..b1fcb42dcc 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -168,7 +168,7 @@ bool BaseSprite::loadFile(const Common::String &filename, int lifeTime, TSpriteC
ret = STATUS_OK;
}
} else {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer) {
if (DID_FAIL(ret = loadBuffer(buffer, true, lifeTime, cacheType))) {
BaseEngine::LOG(0, "Error parsing SPRITE file '%s'", filename.c_str());
@@ -204,7 +204,7 @@ TOKEN_DEF(EDITOR_BG_ALPHA)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
+bool BaseSprite::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(CONTINUOUS)
TOKEN_TABLE(SPRITE)
@@ -223,7 +223,7 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
@@ -231,7 +231,7 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SPRITE) {
BaseEngine::LOG(0, "'SPRITE' keyword expected.");
return STATUS_FAILED;
}
@@ -240,30 +240,30 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
int frameCount = 1;
BaseFrame *frame;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_CONTINUOUS:
- parser.scanStr((char *)params, "%b", &_continuous);
+ parser.scanStr(params, "%b", &_continuous);
break;
case TOKEN_EDITOR_MUTED:
- parser.scanStr((char *)params, "%b", &_editorMuted);
+ parser.scanStr(params, "%b", &_editorMuted);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_LOOPING:
- parser.scanStr((char *)params, "%b", &_looping);
+ parser.scanStr(params, "%b", &_looping);
break;
case TOKEN_PRECISE:
- parser.scanStr((char *)params, "%b", &_precise);
+ parser.scanStr(params, "%b", &_precise);
break;
case TOKEN_STREAMED:
- parser.scanStr((char *)params, "%b", &_streamed);
+ parser.scanStr(params, "%b", &_streamed);
if (_streamed && lifeTime == -1) {
lifeTime = 500;
cacheType = CACHE_ALL;
@@ -271,33 +271,33 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
break;
case TOKEN_STREAMED_KEEP_LOADED:
- parser.scanStr((char *)params, "%b", &_streamedKeepLoaded);
+ parser.scanStr(params, "%b", &_streamedKeepLoaded);
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_EDITOR_BG_FILE:
if (_gameRef->_editorMode) {
delete[] _editorBgFile;
- _editorBgFile = new char[strlen((char *)params) + 1];
+ _editorBgFile = new char[strlen(params) + 1];
if (_editorBgFile) {
- strcpy(_editorBgFile, (char *)params);
+ strcpy(_editorBgFile, params);
}
}
break;
case TOKEN_EDITOR_BG_OFFSET_X:
- parser.scanStr((char *)params, "%d", &_editorBgOffsetX);
+ parser.scanStr(params, "%d", &_editorBgOffsetX);
break;
case TOKEN_EDITOR_BG_OFFSET_Y:
- parser.scanStr((char *)params, "%d", &_editorBgOffsetY);
+ parser.scanStr(params, "%d", &_editorBgOffsetY);
break;
case TOKEN_EDITOR_BG_ALPHA:
- parser.scanStr((char *)params, "%d", &_editorBgAlpha);
+ parser.scanStr(params, "%d", &_editorBgAlpha);
_editorBgAlpha = MIN<int32>(_editorBgAlpha, 255);
_editorBgAlpha = MAX<int32>(_editorBgAlpha, 0);
break;
@@ -462,7 +462,7 @@ bool BaseSprite::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, float
return false;
}
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
for (uint32 i = 0; i < _frames.size(); i++) {
Rect32 frame;
Rect32 temp;
@@ -520,29 +520,29 @@ bool BaseSprite::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool BaseSprite::persist(BasePersistenceManager *persistMgr) {
BaseScriptHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_canBreak));
- persistMgr->transfer(TMEMBER(_changed));
- persistMgr->transfer(TMEMBER(_paused));
- persistMgr->transfer(TMEMBER(_continuous));
- persistMgr->transfer(TMEMBER(_currentFrame));
- persistMgr->transfer(TMEMBER(_editorAllFrames));
- persistMgr->transfer(TMEMBER(_editorBgAlpha));
- persistMgr->transfer(TMEMBER(_editorBgFile));
- persistMgr->transfer(TMEMBER(_editorBgOffsetX));
- persistMgr->transfer(TMEMBER(_editorBgOffsetY));
- persistMgr->transfer(TMEMBER(_editorMuted));
- persistMgr->transfer(TMEMBER(_finished));
+ persistMgr->transferBool(TMEMBER(_canBreak));
+ persistMgr->transferBool(TMEMBER(_changed));
+ persistMgr->transferBool(TMEMBER(_paused));
+ persistMgr->transferBool(TMEMBER(_continuous));
+ persistMgr->transferSint32(TMEMBER(_currentFrame));
+ persistMgr->transferBool(TMEMBER(_editorAllFrames));
+ persistMgr->transferSint32(TMEMBER(_editorBgAlpha));
+ persistMgr->transferCharPtr(TMEMBER(_editorBgFile));
+ persistMgr->transferSint32(TMEMBER(_editorBgOffsetX));
+ persistMgr->transferSint32(TMEMBER(_editorBgOffsetY));
+ persistMgr->transferBool(TMEMBER(_editorMuted));
+ persistMgr->transferBool(TMEMBER(_finished));
_frames.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_lastFrameTime));
- persistMgr->transfer(TMEMBER(_looping));
- persistMgr->transfer(TMEMBER(_moveX));
- persistMgr->transfer(TMEMBER(_moveY));
+ persistMgr->transferUint32(TMEMBER(_lastFrameTime));
+ persistMgr->transferBool(TMEMBER(_looping));
+ persistMgr->transferSint32(TMEMBER(_moveX));
+ persistMgr->transferSint32(TMEMBER(_moveY));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
- persistMgr->transfer(TMEMBER(_precise));
- persistMgr->transfer(TMEMBER(_streamed));
- persistMgr->transfer(TMEMBER(_streamedKeepLoaded));
+ persistMgr->transferBool(TMEMBER(_precise));
+ persistMgr->transferBool(TMEMBER(_streamed));
+ persistMgr->transferBool(TMEMBER(_streamedKeepLoaded));
return STATUS_OK;
@@ -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..54d595f655 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 loadBuffer(char *buffer, bool compete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
bool loadFile(const Common::String &filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
- bool draw(int x, int y, BaseObject *Register = nullptr, float zoomX = 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..38eebb067b 100644
--- a/engines/wintermute/base/base_sub_frame.cpp
+++ b/engines/wintermute/base/base_sub_frame.cpp
@@ -34,10 +34,11 @@
#include "engines/wintermute/base/base_surface_storage.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/graphics/transform_tools.h"
+#include "engines/wintermute/graphics/transform_struct.h"
namespace Wintermute {
@@ -46,12 +47,13 @@ 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;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_editorSelected = false;
@@ -94,7 +96,7 @@ TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
+bool BaseSubFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(TRANSPARENT)
@@ -118,13 +120,13 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
int r = 255, g = 255, b = 255;
int ar = 255, ag = 255, ab = 255, alpha = 255;
bool custoTrans = false;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
char *surfaceFile = nullptr;
delete _surface;
_surface = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, &params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_IMAGE:
surfaceFile = params;
@@ -176,7 +178,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
}
@@ -205,7 +207,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
return STATUS_FAILED;
}
*/
- if (BasePlatform::isRectEmpty(&rect)) {
+ if (rect.isRectEmpty()) {
setDefaultRect();
} else {
setRect(rect);
@@ -216,7 +218,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
Rect32 BaseSubFrame::getRect() {
if (_wantsDefaultRect && _surface) {
- BasePlatform::setRect(&_rect, 0, 0, _surface->getWidth(), _surface->getHeight());
+ _rect.setRect(0, 0, _surface->getWidth(), _surface->getHeight());
_wantsDefaultRect = false;
}
return _rect;
@@ -233,12 +235,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 +259,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, (uint32)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);
}
}
@@ -278,11 +293,10 @@ bool BaseSubFrame::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, flo
float ratioX = scaleX / 100.0f;
float ratioY = scaleY / 100.0f;
- BasePlatform::setRect(rect,
- (int)(x - _hotspotX * ratioX),
- (int)(y - _hotspotY * ratioY),
- (int)(x - _hotspotX * ratioX + (getRect().right - getRect().left) * ratioX),
- (int)(y - _hotspotY * ratioY + (getRect().bottom - getRect().top) * ratioY));
+ rect->setRect((int)(x - _hotspotX * ratioX),
+ (int)(y - _hotspotY * ratioY),
+ (int)(x - _hotspotX * ratioX + (getRect().right - getRect().left) * ratioX),
+ (int)(y - _hotspotY * ratioY + (getRect().bottom - getRect().top) * ratioY));
return true;
}
@@ -302,9 +316,9 @@ bool BaseSubFrame::saveAsText(BaseDynamicBuffer *buffer, int indent, bool comple
}
Rect32 rect;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
if (_surface) {
- BasePlatform::setRect(&rect, 0, 0, _surface->getWidth(), _surface->getHeight());
+ rect.setRect(0, 0, _surface->getWidth(), _surface->getHeight());
}
if (!(rect == getRect())) {
buffer->putTextIndent(indent + 2, "RECT { %d,%d,%d,%d }\n", getRect().left, getRect().top, getRect().right, getRect().bottom);
@@ -360,7 +374,7 @@ void BaseSubFrame::setDefaultRect() {
_wantsDefaultRect = true;
} else {
_wantsDefaultRect = false;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
}
}
@@ -370,27 +384,27 @@ bool BaseSubFrame::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_2DOnly));
- persistMgr->transfer(TMEMBER(_3DOnly));
- persistMgr->transfer(TMEMBER(_alpha));
- persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_editorSelected));
- persistMgr->transfer(TMEMBER(_hotspotX));
- persistMgr->transfer(TMEMBER(_hotspotY));
- persistMgr->transfer(TMEMBER(_rect));
- persistMgr->transfer(TMEMBER(_wantsDefaultRect));
-
- persistMgr->transfer(TMEMBER(_surfaceFilename));
- persistMgr->transfer(TMEMBER(_cKDefault));
- persistMgr->transfer(TMEMBER(_cKRed));
- persistMgr->transfer(TMEMBER(_cKGreen));
- persistMgr->transfer(TMEMBER(_cKBlue));
- persistMgr->transfer(TMEMBER(_lifeTime));
-
- persistMgr->transfer(TMEMBER(_keepLoaded));
- persistMgr->transfer(TMEMBER(_mirrorX));
- persistMgr->transfer(TMEMBER(_mirrorY));
- persistMgr->transfer(TMEMBER(_transparent));
+ persistMgr->transferBool(TMEMBER(_2DOnly));
+ persistMgr->transferBool(TMEMBER(_3DOnly));
+ persistMgr->transferUint32(TMEMBER(_alpha));
+ persistMgr->transferBool(TMEMBER(_decoration));
+ persistMgr->transferBool(TMEMBER(_editorSelected));
+ persistMgr->transferSint32(TMEMBER(_hotspotX));
+ persistMgr->transferSint32(TMEMBER(_hotspotY));
+ persistMgr->transferRect32(TMEMBER(_rect));
+ persistMgr->transferBool(TMEMBER(_wantsDefaultRect));
+
+ persistMgr->transferCharPtr(TMEMBER(_surfaceFilename));
+ persistMgr->transferBool(TMEMBER(_cKDefault));
+ persistMgr->transferByte(TMEMBER(_cKRed));
+ persistMgr->transferByte(TMEMBER(_cKGreen));
+ persistMgr->transferByte(TMEMBER(_cKBlue));
+ persistMgr->transferSint32(TMEMBER(_lifeTime));
+
+ persistMgr->transferBool(TMEMBER(_keepLoaded));
+ persistMgr->transferBool(TMEMBER(_mirrorX));
+ persistMgr->transferBool(TMEMBER(_mirrorY));
+ persistMgr->transferUint32(TMEMBER(_transparent));
return STATUS_OK;
}
@@ -657,4 +671,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..4e164467e2 100644
--- a/engines/wintermute/base/base_sub_frame.h
+++ b/engines/wintermute/base/base_sub_frame.h
@@ -51,7 +51,7 @@ public:
bool _editorSelected;
BaseSubFrame(BaseGame *inGame);
virtual ~BaseSubFrame();
- bool loadBuffer(byte *buffer, int lifeTime, bool keepLoaded);
+ bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = 100, float scaleY = 100);
const char* getSurfaceFilename();
@@ -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..a6e8b17927 100644
--- a/engines/wintermute/base/base_viewport.cpp
+++ b/engines/wintermute/base/base_viewport.cpp
@@ -29,7 +29,6 @@
#include "engines/wintermute/base/base_viewport.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_persistence_manager.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
namespace Wintermute {
@@ -38,7 +37,7 @@ IMPLEMENT_PERSISTENT(BaseViewport, false)
//////////////////////////////////////////////////////////////////////////
BaseViewport::BaseViewport(BaseGame *inGame) : BaseClass(inGame) {
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_mainObject = nullptr;
_offsetX = _offsetY = 0;
}
@@ -56,9 +55,9 @@ bool BaseViewport::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
persistMgr->transferPtr(TMEMBER_PTR(_mainObject));
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_rect));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
+ persistMgr->transferRect32(TMEMBER(_rect));
return STATUS_OK;
}
@@ -73,7 +72,7 @@ bool BaseViewport::setRect(int32 left, int32 top, int32 right, int32 bottom, boo
bottom = MIN(bottom, BaseEngine::instance().getRenderer()->getHeight());
}
- BasePlatform::setRect(&_rect, left, top, right, bottom);
+ _rect.setRect(left, top, right, bottom);
_offsetX = left;
_offsetY = top;
return STATUS_OK;
@@ -97,4 +96,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..808dc9e00d 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 '\\'
@@ -123,6 +117,8 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
if (fixedFilename.contains(':')) {
if (fixedFilename.hasPrefix("c:/windows/fonts/")) { // East Side Story refers to "c:\windows\fonts\framd.ttf"
fixedFilename = filename.c_str() + 14;
+ } else if (fixedFilename.hasPrefix("c:/carol6/svn/data/")) { // Carol Reed 6: Black Circle refers to "c:\carol6\svn\data\sprites\system\help.png"
+ fixedFilename = fixedFilename.c_str() + 19;
} else {
error("openDiskFile::Absolute path or invalid filename used in %s", filename.c_str());
}
@@ -155,7 +151,8 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
}
if (compressed) {
- uint32 dataOffset, compSize, uncompSize;
+ uint32 dataOffset, compSize;
+ unsigned long uncompSize;
dataOffset = file->readUint32LE();
compSize = file->readUint32LE();
uncompSize = file->readUint32LE();
@@ -177,7 +174,7 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
file->seek(dataOffset + prefixSize, SEEK_SET);
file->read(compBuffer, compSize);
- if (Common::uncompress(data, (unsigned long *)&uncompSize, compBuffer, compSize) != true) {
+ if (Common::uncompress(data, &uncompSize, compBuffer, compSize) != true) {
error("Error uncompressing file '%s'", filename.c_str());
delete[] compBuffer;
delete file;
@@ -198,4 +195,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..2a394616d1 100644
--- a/engines/wintermute/base/font/base_font.cpp
+++ b/engines/wintermute/base/font/base_font.cpp
@@ -118,18 +118,18 @@ bool BaseFont::isTrueType(BaseGame *gameRef, const Common::String &filename) {
TOKEN_TABLE_END
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
return false;
}
- byte *workBuffer = buffer;
+ char *workBuffer = buffer;
char *params;
BaseParser parser;
bool ret = false;
- if (parser.getCommand((char **)&workBuffer, commands, (char **)&params) == TOKEN_TTFONT) {
+ if (parser.getCommand(&workBuffer, commands, &params) == TOKEN_TTFONT) {
ret = true;
}
@@ -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..95f9a83a6a 100644
--- a/engines/wintermute/base/font/base_font_bitmap.cpp
+++ b/engines/wintermute/base/font/base_font_bitmap.cpp
@@ -37,7 +37,6 @@
#include "engines/wintermute/base/base_frame.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
namespace Wintermute {
@@ -253,7 +252,7 @@ void BaseFontBitmap::drawChar(byte c, int x, int y) {
tileWidth = _widths[c];
}
- BasePlatform::setRect(&rect, col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1)*_tileHeight);
+ rect.setRect(col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1) * _tileHeight);
bool handled = false;
if (_sprite) {
_sprite->getCurrentFrame();
@@ -272,7 +271,7 @@ void BaseFontBitmap::drawChar(byte c, int x, int y) {
//////////////////////////////////////////////////////////////////////
bool BaseFontBitmap::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseFontBitmap::LoadFile failed for file '%s'", filename.c_str());
return STATUS_FAILED;
@@ -311,7 +310,7 @@ TOKEN_DEF(WIDTHS_FRAME)
TOKEN_DEF(PAINT_WHOLE_CELL)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::loadBuffer(byte *buffer) {
+bool BaseFontBitmap::loadBuffer(char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(FONTEXT_FIX)
TOKEN_TABLE(FONT)
@@ -335,11 +334,11 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
int cmd;
BaseParser parser;
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_FONT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_FONT) {
_gameRef->LOG(0, "'FONT' keyword expected.");
return STATUS_FAILED;
}
- buffer = (byte *)params;
+ buffer = params;
int widths[300];
int num = 0, defaultWidth = 8;
@@ -354,15 +353,15 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
int spaceWidth = 0;
int expandWidth = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_IMAGE:
- surfaceFile = (char *)params;
+ surfaceFile = params;
break;
case TOKEN_SPRITE:
- spriteFile = (char *)params;
+ spriteFile = params;
break;
case TOKEN_TRANSPARENT:
@@ -418,7 +417,7 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
@@ -496,13 +495,13 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
BaseFont::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_numColumns));
+ persistMgr->transferSint32(TMEMBER(_numColumns));
persistMgr->transferPtr(TMEMBER_PTR(_subframe));
- persistMgr->transfer(TMEMBER(_tileHeight));
- persistMgr->transfer(TMEMBER(_tileWidth));
+ persistMgr->transferSint32(TMEMBER(_tileHeight));
+ persistMgr->transferSint32(TMEMBER(_tileWidth));
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
- persistMgr->transfer(TMEMBER(_widthsFrame));
+ persistMgr->transferSint32(TMEMBER(_widthsFrame));
if (persistMgr->getIsSaving()) {
persistMgr->putBytes(_widths, sizeof(_widths));
@@ -511,8 +510,8 @@ bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
}
- persistMgr->transfer(TMEMBER(_fontextFix));
- persistMgr->transfer(TMEMBER(_wholeCell));
+ persistMgr->transferBool(TMEMBER(_fontextFix));
+ persistMgr->transferBool(TMEMBER(_wholeCell));
return STATUS_OK;
@@ -587,4 +586,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..77620d8b88 100644
--- a/engines/wintermute/base/font/base_font_bitmap.h
+++ b/engines/wintermute/base/font/base_font_bitmap.h
@@ -37,7 +37,7 @@ class BaseSubFrame;
class BaseFontBitmap : public BaseFont {
public:
DECLARE_PERSISTENT(BaseFontBitmap, BaseFont)
- bool loadBuffer(byte *Buffer);
+ bool loadBuffer(char *buffer);
bool loadFile(const Common::String &filename);
virtual int getTextWidth(const byte *text, int maxLength = -1) override;
virtual int getTextHeight(const byte *text, int width) override;
@@ -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..b879e789e3 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -34,7 +34,6 @@
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/wintermute.h"
#include "graphics/fonts/ttf.h"
#include "graphics/fontman.h"
@@ -122,7 +121,7 @@ int BaseFontTT::getTextWidth(const byte *text, int maxLength) {
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -156,19 +155,19 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
return;
}
- WideString textStr = (const char *)text;
+ WideString textStr;
// TODO: Why do we still insist on Widestrings everywhere?
- /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
- else text = StringUtil::AnsiToWide((char *)Text);*/
// HACK: J.U.L.I.A. uses CP1252, we need to fix that,
// And we still don't have any UTF8-support.
- if (_gameRef->_textEncoding != TEXT_UTF8) {
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ textStr = StringUtil::utf8ToWide((const char *)text);
+ } else {
textStr = StringUtil::ansiToWide((const char *)text);
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -227,7 +226,7 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
// and paint it
if (surface) {
Rect32 rc;
- BasePlatform::setRect(&rc, 0, 0, surface->getWidth(), surface->getHeight());
+ rc.setRect(0, 0, surface->getWidth(), surface->getHeight());
for (uint32 i = 0; i < _layers.size(); i++) {
uint32 color = _layers[i]->_color;
uint32 origForceAlpha = renderer->_forceAlphaColor;
@@ -249,7 +248,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
//TextLineList lines;
// TODO: Use WideString-conversion here.
//WrapText(text, width, maxHeight, lines);
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, width, lines);
while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
@@ -268,16 +267,17 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
alignment = Graphics::kTextAlignRight;
}
- debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
+ // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array.
+ //debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
Graphics::Surface *surface = new Graphics::Surface();
if (_deletableFont) { // We actually have a TTF
- 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));
}
uint32 useColor = 0xffffffff;
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
int heightOffset = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
_font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
@@ -285,7 +285,27 @@ 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());
+
+ if (_deletableFont) {
+ // Reconstruct the alpha channel of the font.
+
+ // Since we painted it with color 0xFFFFFFFF onto a black background,
+ // the alpha channel is gone, but the color value of each pixel corresponds
+ // to its original alpha value.
+
+ Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
+ uint32 *pixels = (uint32 *)convertedSurface->getPixels();
+
+ // This is a Surface we created ourselves, so no empty space between rows.
+ for (int i = 0; i < surface->w * surface->h; ++i) {
+ uint8 a, r, g, b;
+ format.colorToRGB(*pixels, r, g, b);
+ a = r;
+ *pixels++ = format.ARGBToColor(a, r, g, b);
+ }
+ }
+
retSurface->putSurface(*convertedSurface, true);
convertedSurface->free();
surface->free();
@@ -304,7 +324,7 @@ int BaseFontTT::getLetterHeight() {
//////////////////////////////////////////////////////////////////////
bool BaseFontTT::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseFontTT::LoadFile failed for file '%s'", filename.c_str());
return STATUS_FAILED;
@@ -341,7 +361,7 @@ TOKEN_DEF(OFFSET_X)
TOKEN_DEF(OFFSET_Y)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFontTT::loadBuffer(byte *buffer) {
+bool BaseFontTT::loadBuffer(char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TTFONT)
TOKEN_TABLE(SIZE)
@@ -361,15 +381,15 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
int cmd;
BaseParser parser;
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TTFONT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TTFONT) {
_gameRef->LOG(0, "'TTFONT' keyword expected.");
return STATUS_FAILED;
}
- buffer = (byte *)params;
+ buffer = params;
uint32 baseColor = 0x00000000;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_SIZE:
parser.scanStr(params, "%d", &_fontHeight);
@@ -419,7 +439,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
case TOKEN_LAYER: {
BaseTTFontLayer *layer = new BaseTTFontLayer;
- if (layer && DID_SUCCEED(parseLayer(layer, (byte *)params))) {
+ if (layer && DID_SUCCEED(parseLayer(layer, params))) {
_layers.add(layer);
} else {
delete layer;
@@ -452,7 +472,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
//////////////////////////////////////////////////////////////////////////
-bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
+bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(OFFSET_X)
TOKEN_TABLE(OFFSET_Y)
@@ -464,7 +484,7 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
int cmd;
BaseParser parser;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_OFFSET_X:
parser.scanStr(params, "%d", &layer->_offsetX);
@@ -501,25 +521,25 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
bool BaseFontTT::persist(BasePersistenceManager *persistMgr) {
BaseFont::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_isBold));
- persistMgr->transfer(TMEMBER(_isItalic));
- persistMgr->transfer(TMEMBER(_isUnderline));
- persistMgr->transfer(TMEMBER(_isStriked));
- persistMgr->transfer(TMEMBER(_fontHeight));
- persistMgr->transfer(TMEMBER(_fontFile));
+ persistMgr->transferBool(TMEMBER(_isBold));
+ persistMgr->transferBool(TMEMBER(_isItalic));
+ persistMgr->transferBool(TMEMBER(_isUnderline));
+ persistMgr->transferBool(TMEMBER(_isStriked));
+ persistMgr->transferSint32(TMEMBER(_fontHeight));
+ persistMgr->transferCharPtr(TMEMBER(_fontFile));
// persist layers
int32 numLayers;
if (persistMgr->getIsSaving()) {
numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
+ persistMgr->transferSint32(TMEMBER(numLayers));
for (int i = 0; i < numLayers; i++) {
_layers[i]->persist(persistMgr);
}
} else {
numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
+ persistMgr->transferSint32(TMEMBER(numLayers));
for (int i = 0; i < numLayers; i++) {
BaseTTFontLayer *layer = new BaseTTFontLayer;
layer->persist(persistMgr);
@@ -549,17 +569,26 @@ bool BaseFontTT::initFont() {
return STATUS_FAILED;
}
#ifdef USE_FREETYPE2
+ Common::String fallbackFilename;
+ // Handle Bold atleast for the fallback-case.
+ // TODO: Handle italic. (Needs a test-case)
+ if (_isBold) {
+ fallbackFilename = "FreeSansBold.ttf";
+ } else {
+ fallbackFilename = "FreeSans.ttf";
+ }
+
Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile);
if (!file) {
if (Common::String(_fontFile) != "arial.ttf") {
warning("%s has no replacement font yet, using FreeSans for now (if available)", _fontFile);
}
// Fallback1: Try to find FreeSans.ttf
- file = SearchMan.createReadStreamForMember("FreeSans.ttf");
+ file = SearchMan.createReadStreamForMember(fallbackFilename);
}
if (file) {
- _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
+ _deletableFont = Graphics::loadTTFFont(*file, _fontHeight, 96); // Use the same dpi as WME (96 vs 72).
_font = _deletableFont;
BaseFileManager::getEngineInstance()->closeFile(file);
file = nullptr;
@@ -582,9 +611,9 @@ bool BaseFontTT::initFont() {
}
if (themeFile) {
Common::Archive *themeArchive = Common::makeZipArchive(themeFile);
- if (themeArchive->hasFile("FreeSans.ttf")) {
+ if (themeArchive->hasFile(fallbackFilename)) {
file = nullptr;
- file = themeArchive->createReadStreamForMember("FreeSans.ttf");
+ file = themeArchive->createReadStreamForMember(fallbackFilename);
_deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
_font = _deletableFont;
}
@@ -599,7 +628,7 @@ bool BaseFontTT::initFont() {
// Fallback3: Try to ask FontMan for the FreeSans.ttf ScummModern.zip uses:
if (!_font) {
// Really not desireable, as we will get a font with dpi-72 then
- Common::String fontName = Common::String::format("%s-%s@%d", "FreeSans.ttf", "ASCII", _fontHeight);
+ Common::String fontName = Common::String::format("%s-%s@%d", fallbackFilename.c_str(), "ASCII", _fontHeight);
warning("Looking for %s", fontName.c_str());
_font = FontMan.getFontByName(fontName);
}
@@ -619,9 +648,9 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight
//TextLineList lines;
if (maxWidth >= 0) {
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, maxWidth, lines);
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
textWidth = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
textWidth = MAX(textWidth, _font->getStringWidth(*it));
@@ -644,4 +673,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..edb41a155f 100644
--- a/engines/wintermute/base/font/base_font_truetype.h
+++ b/engines/wintermute/base/font/base_font_truetype.h
@@ -56,9 +56,8 @@ private:
bool _marked;
uint32 _lastUsed;
- BaseCachedTTFontText() {
+ BaseCachedTTFontText() : _text() {
//_text = L"";
- _text = "";
_width = _maxHeight = _maxLength = -1;
_align = TAL_LEFT;
_surface = nullptr;
@@ -84,9 +83,9 @@ public:
}
bool persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_color));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
+ persistMgr->transferUint32(TMEMBER(_color));
return STATUS_OK;
}
@@ -105,7 +104,7 @@ public:
virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1) override;
virtual int getLetterHeight() override;
- bool loadBuffer(byte *buffer);
+ bool loadBuffer(char *buffer);
bool loadFile(const Common::String &filename);
float getLineHeight() const {
@@ -116,7 +115,7 @@ public:
void initLoop();
private:
- bool parseLayer(BaseTTFontLayer *layer, byte *buffer);
+ bool parseLayer(BaseTTFontLayer *layer, char *buffer);
void measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight);
@@ -135,7 +134,7 @@ private:
size_t _maxCharWidth;
size_t _maxCharHeight;
-public:
+private:
bool _isBold;
bool _isItalic;
bool _isUnderline;
@@ -148,6 +147,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..858a7fc6dc 100644
--- a/engines/wintermute/base/gfx/base_renderer.cpp
+++ b/engines/wintermute/base/gfx/base_renderer.cpp
@@ -65,7 +65,7 @@ BaseRenderer::BaseRenderer(BaseGame *inGame) : BaseClass(inGame) {
_loadImageX = _loadImageY = 0;
_width = _height = _bPP = 0;
- BasePlatform::setRectEmpty(&_monitorRect);
+ _monitorRect.setEmpty();
_realWidth = _realHeight = 0;
_drawOffsetX = _drawOffsetY = 0;
@@ -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;
}
@@ -167,12 +173,12 @@ void BaseRenderer::endSaveLoad() {
}
void BaseRenderer::persistSaveLoadImages(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_loadImageName));
- persistMgr->transfer(TMEMBER(_saveImageName));
- persistMgr->transfer(TMEMBER(_saveImageX));
- persistMgr->transfer(TMEMBER(_saveImageY));
- persistMgr->transfer(TMEMBER(_loadImageX));
- persistMgr->transfer(TMEMBER(_loadImageY));
+ persistMgr->transferString(TMEMBER(_loadImageName));
+ persistMgr->transferString(TMEMBER(_saveImageName));
+ persistMgr->transferSint32(TMEMBER(_saveImageX));
+ persistMgr->transferSint32(TMEMBER(_saveImageY));
+ persistMgr->transferSint32(TMEMBER(_loadImageX));
+ persistMgr->transferSint32(TMEMBER(_loadImageY));
}
//////////////////////////////////////////////////////////////////////
@@ -368,7 +374,7 @@ bool BaseRenderer::displayIndicator() {
}
if (_saveLoadImage && !_hasDrawnSaveLoadImage) {
Rect32 rc;
- BasePlatform::setRect(&rc, 0, 0, _saveLoadImage->getWidth(), _saveLoadImage->getHeight());
+ rc.setRect(0, 0, _saveLoadImage->getWidth(), _saveLoadImage->getHeight());
if (_loadInProgress) {
_saveLoadImage->displayTrans(_loadImageX, _loadImageY, rc);
} else {
@@ -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..b6615bc8fc 100644
--- a/engines/wintermute/base/gfx/base_renderer.h
+++ b/engines/wintermute/base/gfx/base_renderer.h
@@ -84,7 +84,7 @@ public:
* @param a the alpha component to fade too.
* @param rect the portion of the screen to fade (if nullptr, the entire screen will be faded).
*/
- virtual void fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect = nullptr) = 0;
+ virtual void fadeToColor(byte r, byte g, byte b, byte a) = 0;
virtual bool drawLine(int x1, int y1, int x2, int y2, uint32 color); // Unused outside indicator-display
virtual bool drawRect(int x1, int y1, int x2, int y2, uint32 color, int width = 1); // Unused outside indicator-display
@@ -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..a53748e9aa 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 {
@@ -53,9 +54,9 @@ public:
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 displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) = 0;
virtual bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
- virtual bool 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 repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) = 0;
+ virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) = 0;
virtual bool restore();
virtual bool create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime = -1, bool keepLoaded = false) = 0;
virtual bool create(int width, int height);
@@ -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..ff63789d18 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -51,23 +51,19 @@ BaseRenderer *makeOSystemRenderer(BaseGame *inGame) {
BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_renderSurface = new Graphics::Surface();
_blankSurface = new Graphics::Surface();
- _drawNum = 1;
+ _lastFrameIter = _renderQueue.end();
_needsFlip = true;
- _spriteBatch = false;
- _batchNum = 0;
_skipThisFrame = false;
- _previousTicket = nullptr;
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
- setAlphaMod(255);
- setColorMod(255, 255, 255);
_dirtyRect = nullptr;
_disableDirtyRects = false;
- _tempDisableDirtyRects = 0;
if (ConfMan.hasKey("dirty_rects")) {
_disableDirtyRects = !ConfMan.getBool("dirty_rects");
}
+
+ _lastScreenChangeID = g_system->getScreenChangeID();
}
//////////////////////////////////////////////////////////////////////////
@@ -85,7 +81,6 @@ BaseRenderOSystem::~BaseRenderOSystem() {
delete _renderSurface;
_blankSurface->free();
delete _blankSurface;
- TransparentSurface::destroyLookup();
}
//////////////////////////////////////////////////////////////////////////
@@ -128,7 +123,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 +145,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();
@@ -169,20 +152,24 @@ bool BaseRenderOSystem::indicatorFlip() {
}
bool BaseRenderOSystem::flip() {
- if (_renderQueue.size() > DIRTY_RECT_LIMIT) {
- _tempDisableDirtyRects++;
- }
if (_skipThisFrame) {
_skipThisFrame = false;
delete _dirtyRect;
_dirtyRect = nullptr;
g_system->updateScreen();
_needsFlip = false;
- _drawNum = 1;
+
+ // Reset ticketing state
+ _lastFrameIter = _renderQueue.end();
+ RenderQueueIterator it;
+ for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) {
+ (*it)->_wantsDraw = false;
+ }
+
addDirtyRect(_renderRect);
return true;
}
- if (!_tempDisableDirtyRects && !_disableDirtyRects) {
+ if (!_disableDirtyRects) {
drawTickets();
} else {
// Clear the scale-buffered tickets that wasn't reused.
@@ -198,33 +185,23 @@ bool BaseRenderOSystem::flip() {
}
}
}
- if (_needsFlip || _disableDirtyRects || _tempDisableDirtyRects) {
- if (_disableDirtyRects || _tempDisableDirtyRects) {
- g_system->copyRectToScreen((byte *)_renderSurface->pixels, _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
+
+ int oldScreenChangeID = _lastScreenChangeID;
+ _lastScreenChangeID = g_system->getScreenChangeID();
+ bool screenChanged = _lastScreenChangeID != oldScreenChangeID;
+
+ if (_needsFlip || _disableDirtyRects || screenChanged) {
+ if (_disableDirtyRects || screenChanged) {
+ g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
}
- // g_system->copyRectToScreen((byte *)_renderSurface->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();
_needsFlip = false;
}
- _drawNum = 1;
-
- if (_tempDisableDirtyRects && !_disableDirtyRects) {
- _tempDisableDirtyRects--;
- if (!_tempDisableDirtyRects) {
- Common::Rect screen(_screenRect.top, _screenRect.left, _screenRect.bottom, _screenRect.right);
- addDirtyRect(screen);
-
- // The queue has been ignored but updated, and is guaranteed to be in draw-order when run without dirty-rects.
- RenderQueueIterator it = _renderQueue.begin();
- int drawNum = 1;
- while (it != _renderQueue.end()) {
- (*it)->_drawNum = drawNum++;
- ++it;
- }
- }
- }
+ _lastFrameIter = _renderQueue.end();
+
+ g_system->updateScreen();
return STATUS_OK;
}
@@ -232,7 +209,7 @@ bool BaseRenderOSystem::flip() {
//////////////////////////////////////////////////////////////////////////
bool BaseRenderOSystem::fill(byte r, byte g, byte b, Common::Rect *rect) {
_clearColor = _renderSurface->format.ARGBToColor(0xFF, r, g, b);
- if (!_disableDirtyRects && !_tempDisableDirtyRects) {
+ if (!_disableDirtyRects) {
return STATUS_OK;
}
if (!rect) {
@@ -256,37 +233,30 @@ 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) {
+void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a) {
Common::Rect fillRect;
- if (rect) {
- fillRect.left = rect->left;
- fillRect.top = rect->top;
- fillRect.setWidth(rect->width());
- fillRect.setHeight(rect->height());
- } else {
- Rect32 rc;
- _gameRef->getCurrentViewportRect(&rc);
- fillRect.left = (int16)rc.left;
- fillRect.top = (int16)rc.top;
- fillRect.setWidth((int16)(rc.right - rc.left));
- fillRect.setHeight((int16)(rc.bottom - rc.top));
- }
+ Rect32 rc;
+ _gameRef->getCurrentViewportRect(&rc);
+ fillRect.left = (int16)rc.left;
+ fillRect.top = (int16)rc.top;
+ fillRect.setWidth((int16)(rc.right - rc.left));
+ fillRect.setHeight((int16)(rc.bottom - rc.top));
+
modTargetRect(&fillRect);
//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,21 +268,15 @@ 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) {
- if (_tempDisableDirtyRects || _disableDirtyRects) {
- RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
- ticket->_colorMod = _colorMod;
+void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) {
+
+ if (_disableDirtyRects) {
+ RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(ticket);
return;
}
- // Start searching from the beginning for the first and second items (since it's empty the first time around
- // then keep incrementing the start-position, to avoid comparing against already used tickets.
- if (_drawNum == 0 || _drawNum == 1) {
- _lastAddedTicket = _renderQueue.begin();
- }
// Skip rects that are completely outside the screen:
if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
@@ -320,88 +284,35 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
}
if (owner) { // Fade-tickets are owner-less
- RenderTicket compare(owner, nullptr, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
- compare._batchNum = _batchNum;
- if (_spriteBatch) {
- _batchNum++;
- }
- compare._colorMod = _colorMod;
- RenderQueueIterator it;
+ RenderTicket compare(owner, nullptr, srcRect, dstRect, transform);
+ RenderQueueIterator it = _lastFrameIter;
+ ++it;
// Avoid calling end() and operator* every time, when potentially going through
// LOTS of tickets.
RenderQueueIterator endIterator = _renderQueue.end();
RenderTicket *compareTicket = nullptr;
- for (it = _lastAddedTicket; it != endIterator; ++it) {
+ for (; it != endIterator; ++it) {
compareTicket = *it;
if (*(compareTicket) == compare && compareTicket->_isValid) {
- compareTicket->_colorMod = _colorMod;
if (_disableDirtyRects) {
drawFromSurface(compareTicket);
} else {
- drawFromTicket(compareTicket);
- _previousTicket = compareTicket;
- }
- if (_renderQueue.size() > DIRTY_RECT_LIMIT) {
- drawTickets();
- _tempDisableDirtyRects = 3;
+ drawFromQueuedTicket(it);
}
return;
}
}
}
- 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;
} else {
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(ticket);
}
}
-void BaseRenderOSystem::repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY) {
- if (_previousTicket && _lastAddedTicket != _renderQueue.end()) {
- RenderTicket *origTicket = _previousTicket;
-
- // Make sure drawSurface WILL start from the correct _lastAddedTicket
- if (!_tempDisableDirtyRects && !_disableDirtyRects && *_lastAddedTicket != origTicket) {
- RenderQueueIterator it;
- RenderQueueIterator endIterator = _renderQueue.end();
- for (it = _renderQueue.begin(); it != endIterator; ++it) {
- if ((*it) == _previousTicket) {
- _lastAddedTicket = it;
- break;
- }
- }
- }
- Common::Rect srcRect(0, 0, 0, 0);
- srcRect.setWidth(origTicket->getSrcRect()->width());
- srcRect.setHeight(origTicket->getSrcRect()->height());
-
- Common::Rect dstRect = origTicket->_dstRect;
- int initLeft = dstRect.left;
- int initRight = dstRect.right;
-
- 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);
- dstRect.translate(offsetX, 0);
- }
- dstRect.left = initLeft;
- dstRect.right = initRight;
- dstRect.translate(0, offsetY);
- }
- } else {
- error("Repeat-draw failed (did you forget to draw something before this?)");
- }
-}
-
void BaseRenderOSystem::invalidateTicket(RenderTicket *renderTicket) {
addDirtyRect(renderTicket->_dstRect);
renderTicket->_isValid = false;
@@ -419,59 +330,37 @@ void BaseRenderOSystem::invalidateTicketsFromSurface(BaseSurfaceOSystem *surf) {
void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
renderTicket->_wantsDraw = true;
- // A new item always has _drawNum == 0
- if (renderTicket->_drawNum == 0) {
- // In-order
- if (_renderQueue.empty() || _drawNum > (_renderQueue.back())->_drawNum) {
- renderTicket->_drawNum = _drawNum++;
- _renderQueue.push_back(renderTicket);
- addDirtyRect(renderTicket->_dstRect);
- ++_lastAddedTicket;
- } else {
- // Before something
- RenderQueueIterator pos;
- for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) {
- if ((*pos)->_drawNum >= _drawNum) {
- break;
- }
- }
- _renderQueue.insert(pos, renderTicket);
- renderTicket->_drawNum = _drawNum++;
- // Increment the following tickets, so they still are in line
- RenderQueueIterator it;
- for (it = pos; it != _renderQueue.end(); ++it) {
- (*it)->_drawNum++;
- (*it)->_wantsDraw = false;
- }
- addDirtyRect(renderTicket->_dstRect);
- _lastAddedTicket = pos;
- }
+
+ ++_lastFrameIter;
+ // In-order
+ if (_renderQueue.empty() || _lastFrameIter == _renderQueue.end()) {
+ _lastFrameIter--;
+ _renderQueue.push_back(renderTicket);
+ ++_lastFrameIter;
+ addDirtyRect(renderTicket->_dstRect);
} else {
- // Was drawn last round, still in the same order
- if (_drawNum == renderTicket->_drawNum) {
- _drawNum++;
- ++_lastAddedTicket;
- } else {
- // Remove the ticket from the list
- RenderQueueIterator it = _renderQueue.begin();
- while (it != _renderQueue.end()) {
- if ((*it) == renderTicket) {
- it = _renderQueue.erase(it);
- break;
- } else {
- ++it;
- }
- }
- if (it != _renderQueue.end()) {
- // Decreement the following tickets.
- for (; it != _renderQueue.end(); ++it) {
- (*it)->_drawNum--;
- }
- }
- // Is not in order, so readd it as if it was a new ticket
- renderTicket->_drawNum = 0;
- drawFromTicket(renderTicket);
- }
+ // Before something
+ RenderQueueIterator pos = _lastFrameIter;
+ _renderQueue.insert(pos, renderTicket);
+ --_lastFrameIter;
+ addDirtyRect(renderTicket->_dstRect);
+ }
+}
+
+void BaseRenderOSystem::drawFromQueuedTicket(const RenderQueueIterator &ticket) {
+ RenderTicket *renderTicket = *ticket;
+ assert(!renderTicket->_wantsDraw);
+ renderTicket->_wantsDraw = true;
+
+ ++_lastFrameIter;
+ // Not in the same order?
+ if (*_lastFrameIter != renderTicket) {
+ --_lastFrameIter;
+ // Remove the ticket from the list
+ assert(*_lastFrameIter != renderTicket);
+ _renderQueue.erase(ticket);
+ // Is not in order, so readd it as if it was a new ticket
+ drawFromTicket(renderTicket);
}
}
@@ -490,16 +379,13 @@ void BaseRenderOSystem::drawTickets() {
// Note: We draw invalid tickets too, otherwise we wouldn't be honouring
// the draw request they obviously made BEFORE becoming invalid, either way
// we have a copy of their data, so their invalidness won't affect us.
- uint32 decrement = 0;
while (it != _renderQueue.end()) {
if ((*it)->_wantsDraw == false) {
RenderTicket *ticket = *it;
addDirtyRect((*it)->_dstRect);
it = _renderQueue.erase(it);
delete ticket;
- decrement++;
} else {
- (*it)->_drawNum -= decrement;
++it;
}
}
@@ -512,17 +398,12 @@ void BaseRenderOSystem::drawTickets() {
}
return;
}
- // The color-mods are stored in the RenderTickets on add, since we set that state again during
- // draw, we need to keep track of what it was prior to draw.
- uint32 oldColorMod = _colorMod;
// Apply the clear-color to the dirty rect.
_renderSurface->fillRect(*_dirtyRect, _clearColor);
- _drawNum = 1;
+ _lastFrameIter = _renderQueue.end();
for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) {
RenderTicket *ticket = *it;
- assert(ticket->_drawNum == _drawNum);
- ++_drawNum;
if (ticket->_dstRect.intersects(*_dirtyRect)) {
// dstClip is the area we want redrawn.
Common::Rect dstClip(ticket->_dstRect);
@@ -535,7 +416,6 @@ void BaseRenderOSystem::drawTickets() {
// convert from screen-coords to surface-coords.
dstClip.translate(-offsetX, -offsetY);
- _colorMod = ticket->_colorMod;
drawFromSurface(ticket, &pos, &dstClip);
_needsFlip = true;
}
@@ -544,21 +424,15 @@ void BaseRenderOSystem::drawTickets() {
}
g_system->copyRectToScreen((byte *)_renderSurface->getBasePtr(_dirtyRect->left, _dirtyRect->top), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
- // Revert the colorMod-state.
- _colorMod = oldColorMod;
-
it = _renderQueue.begin();
// Clean out the old tickets
- decrement = 0;
while (it != _renderQueue.end()) {
if ((*it)->_isValid == false) {
RenderTicket *ticket = *it;
addDirtyRect((*it)->_dstRect);
it = _renderQueue.erase(it);
delete ticket;
- decrement++;
} else {
- (*it)->_drawNum -= decrement;
++it;
}
}
@@ -578,7 +452,7 @@ void BaseRenderOSystem::drawFromSurface(RenderTicket *ticket, Common::Rect *dstR
bool BaseRenderOSystem::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
// This function isn't used outside of indicator-displaying, and thus quite unused in
// BaseRenderOSystem when dirty-rects are enabled.
- if (!_tempDisableDirtyRects && !_disableDirtyRects && !_indicatorDisplay) {
+ if (!_disableDirtyRects && !_indicatorDisplay) {
error("BaseRenderOSystem::DrawLine - doesn't work for dirty rects yet");
}
@@ -625,8 +499,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 +517,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);
}
//////////////////////////////////////////////////////////////////////////
@@ -686,28 +558,22 @@ void BaseRenderOSystem::endSaveLoad() {
it = _renderQueue.erase(it);
delete ticket;
}
- _lastAddedTicket = _renderQueue.begin();
- _previousTicket = nullptr;
// HACK: After a save the buffer will be drawn before the scripts get to update it,
// so just skip this single frame.
_skipThisFrame = true;
- _drawNum = 1;
+ _lastFrameIter = _renderQueue.end();
_renderSurface->fillRect(Common::Rect(0, 0, _renderSurface->h, _renderSurface->w), _renderSurface->format.ARGBToColor(255, 0, 0, 0));
- g_system->copyRectToScreen((byte *)_renderSurface->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();
}
bool BaseRenderOSystem::startSpriteBatch() {
- _spriteBatch = true;
- _batchNum = 1;
return STATUS_OK;
}
bool BaseRenderOSystem::endSpriteBatch() {
- _spriteBatch = false;
- _batchNum = 0;
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..8996c8b2e8 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -33,15 +33,37 @@
#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);
~BaseRenderOSystem();
+ typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
+
Common::String getName() const;
bool initRenderer(int width, int height, bool windowed) override;
@@ -50,17 +72,25 @@ public:
bool fill(byte r, byte g, byte b, Common::Rect *rect = nullptr) override;
Graphics::PixelFormat getPixelFormat() const override;
void fade(uint16 alpha) override;
- void fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect = nullptr) override;
+ void fadeToColor(byte r, byte g, byte b, byte a) override;
bool drawLine(int x1, int y1, int x2, int y2, uint32 color) override;
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 new ticket into the queue, adding a dirty rect
+ * @param renderTicket the ticket to be added.
+ */
void drawFromTicket(RenderTicket *renderTicket);
+ /**
+ * Re-insert an existing ticket into the queue, adding a dirty rect
+ * out-of-order from last draw from the ticket.
+ * @param ticket iterator pointing to the ticket to be added.
+ */
+ void drawFromQueuedTicket(const RenderQueueIterator &ticket);
bool setViewport(int left, int top, int right, int bottom) override;
bool setViewport(Rect32 *rect) override { return BaseRenderer::setViewport(rect); }
@@ -80,24 +110,27 @@ 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 repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY);
+ void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
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);
// Dirty-rects:
void drawFromSurface(RenderTicket *ticket, Common::Rect *dstRect, Common::Rect *clipRect);
- typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
Common::Rect *_dirtyRect;
Common::List<RenderTicket *> _renderQueue;
- RenderQueueIterator _lastAddedTicket;
- RenderTicket *_previousTicket;
bool _needsFlip;
- uint32 _drawNum;
+ RenderQueueIterator _lastFrameIter;
Common::Rect _renderRect;
Graphics::Surface *_renderSurface;
Graphics::Surface *_blankSurface;
@@ -108,17 +141,14 @@ private:
int _borderBottom;
bool _disableDirtyRects;
- uint32 _tempDisableDirtyRects;
- bool _spriteBatch;
- uint32 _batchNum;
float _ratioX;
float _ratioY;
- uint32 _colorMod;
uint32 _clearColor;
bool _skipThisFrame;
+ int _lastScreenChangeID; // previous value of OSystem::getScreenChangeID()
};
-} // end of namespace Wintermute
+} // 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..9ec8573a87 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -37,6 +37,7 @@
#include "graphics/decoders/jpeg.h"
#include "graphics/decoders/tga.h"
#include "engines/wintermute/graphics/transparent_surface.h"
+#include "engines/wintermute/graphics/transform_tools.h"
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "common/stream.h"
@@ -48,10 +49,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 +72,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 +144,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 +247,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 +333,64 @@ 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);
+ _rotation = 0;
+ return drawSprite(x, y, &rect, nullptr, TransformStruct((int32)zoomX, (int32)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);
+ _rotation = 0;
+ TransformStruct transform;
+ if (transparent) {
+ transform = TransformStruct((int32)zoomX, (int32)zoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, blendMode, alpha, mirrorX, mirrorY);
+ } else {
+ transform = TransformStruct((int32)zoomX, (int32)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::displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) {
+ assert(numTimesX > 0 && numTimesY > 0);
+ TransformStruct transform(numTimesX, numTimesY);
+ return drawSprite(x, y, &rect, nullptr, transform);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transform) {
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
if (!_loaded) {
@@ -359,24 +398,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);
- } else {
- SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND);
- }
-#endif
// TODO: This _might_ miss the intended behaviour by 1 in each direction
// But I think it fits the model used in Wintermute.
Common::Rect srcRect;
@@ -386,47 +410,38 @@ 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;
- // Crop off-by-ones:
- if (position.left == -1) {
- position.left = 0; // TODO: Something is wrong
- }
- if (position.top == -1) {
- position.top = 0; // TODO: Something is wrong
- }
+ if (newRect) {
+ position.top = y;
+ position.left = x;
+ position.setWidth(newRect->width());
+ position.setHeight(newRect->height());
+ } else {
- position.setWidth((int16)((float)srcRect.width() * zoomX / 100.f));
- position.setHeight((int16)((float)srcRect.height() * zoomX / 100.f));
+ Rect32 r;
+ r.top = 0;
+ r.left = 0;
+ r.setWidth(rect->width());
+ r.setHeight(rect->height());
- renderer->modTargetRect(&position);
+ r = TransformTools::newRect(r, transform, 0);
- /* position.left += offsetX;
- position.top += offsetY;*/
+ position.top = r.top + y + transform._offset.y;
+ position.left = r.left + x + transform._offset.x;
+ position.setWidth(r.width() * transform._numTimesX);
+ position.setHeight(r.height() * transform._numTimesY);
+ }
+ renderer->modTargetRect(&position);
// 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);
-
- return STATUS_OK;
-}
-
-bool BaseSurfaceOSystem::repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) {
- BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
- renderer->repeatLastDraw(offsetX, offsetY, numTimesX, numTimesY);
+ renderer->drawSurface(this, _surface, &srcRect, &position, transform);
return STATUS_OK;
}
@@ -434,11 +449,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..67f45f66db 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,13 +52,13 @@ 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, float zoomX, float 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 repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) override;
+ bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = kDefaultRgbaMod, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+ bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) override;
+ virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY);
virtual bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin);
@@ -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..1cd35e3b04 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,21 @@
* 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;
- _batchNum = 0;
- _mirror = TransparentSurface::FLIP_NONE;
- if (mirrorX) {
- _mirror |= TransparentSurface::FLIP_V;
- }
- if (mirrorY) {
- _mirror |= TransparentSurface::FLIP_H;
- }
+RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct transform) :
+ _owner(owner),
+ _srcRect(*srcRect),
+ _dstRect(*dstRect),
+ _isValid(true),
+ _wantsDraw(true),
+ _transform(transform) {
if (surf) {
_surface = new Graphics::Surface();
_surface->create((uint16)srcRect->width(), (uint16)srcRect->height(), surf->format);
@@ -51,7 +50,22 @@ _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()) {
+ //
+ // NB: The numTimesX/numTimesY properties don't yet mix well with
+ // scaling and rotation, but there is no need for that functionality at
+ // the moment.
+ // NB: Mirroring and rotation are probably done in the wrong order.
+ // (Mirroring should most likely be done before rotation. See also
+ // TransformTools.)
+ if (_transform._angle != kDefaultAngle) {
+ TransparentSurface src(*_surface, false);
+ Graphics::Surface *temp = src.rotoscale(transform);
+ _surface->free();
+ delete _surface;
+ _surface = temp;
+ } else if ((dstRect->width() != srcRect->width() ||
+ dstRect->height() != srcRect->height()) &&
+ _transform._numTimesX * _transform._numTimesY == 1) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
_surface->free();
@@ -70,46 +84,108 @@ 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.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
+ } else {
+ src.setAlphaMode(_owner->getAlphaType());
+ }
+ }
+
+ int y = _dstRect.top;
+ int w = _dstRect.width() / _transform._numTimesX;
+ int h = _dstRect.height() / _transform._numTimesY;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = _dstRect.left;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+ src.blit(*_targetSurface, x, y, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
+ x += w;
+ }
+ y += h;
+ }
}
-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) {
doDelete = true;
clipRect = new Common::Rect();
- clipRect->setWidth(getSurface()->w);
- clipRect->setHeight(getSurface()->h);
+ clipRect->setWidth(getSurface()->w * _transform._numTimesX);
+ clipRect->setHeight(getSurface()->h * _transform._numTimesY);
+ }
+
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
+ } else {
+ src.setAlphaMode(_owner->getAlphaType());
+ }
+ }
+
+ if (_transform._numTimesX * _transform._numTimesY == 1) {
+
+ src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
+
+ } else {
+
+ // clipRect is a subrect of the full numTimesX*numTimesY rect
+ Common::Rect subRect;
+
+ int y = 0;
+ int w = getSurface()->w;
+ int h = getSurface()->h;
+ assert(w == _dstRect.width() / _transform._numTimesX);
+ assert(h == _dstRect.height() / _transform._numTimesY);
+
+ int basex = dstRect->left - clipRect->left;
+ int basey = dstRect->top - clipRect->top;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = 0;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+
+ subRect.left = x;
+ subRect.top = y;
+ subRect.setWidth(w);
+ subRect.setHeight(h);
+
+ if (subRect.intersects(*clipRect)) {
+ subRect.clip(*clipRect);
+ subRect.translate(-x, -y);
+ src.blit(*_targetSurface, basex + x + subRect.left, basey + y + subRect.top, _transform._flip, &subRect, _transform._rgbaMod, subRect.width(), subRect.height(), _transform._blendMode);
+
+ }
+
+ x += w;
+ }
+ y += h;
+ }
}
- src._enableAlphaBlit = _hasAlpha;
- src.blit(*_targetSurface, dstRect->left, dstRect->top, _mirror, clipRect, _colorMod, 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..e824c09fe7 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,41 +29,52 @@
#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), _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;
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..061352b60f 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -38,7 +38,6 @@
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
#include "common/str.h"
#include "common/math.h"
@@ -50,7 +49,7 @@ IMPLEMENT_PERSISTENT(PartEmitter, false)
PartEmitter::PartEmitter(BaseGame *inGame, BaseScriptHolder *owner) : BaseObject(inGame) {
_width = _height = 0;
- BasePlatform::setRectEmpty(&_border);
+ _border.setEmpty();
_borderThicknessLeft = _borderThicknessRight = _borderThicknessTop = _borderThicknessBottom = 0;
_angle1 = _angle2 = 0;
@@ -198,7 +197,7 @@ bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint3
float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2);
float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2);
- if (!BasePlatform::isRectEmpty(&_border)) {
+ if (!_border.isRectEmpty()) {
int thicknessLeft = (int)(_borderThicknessLeft - (float)_borderThicknessLeft * posZ / 100.0f);
int thicknessRight = (int)(_borderThicknessRight - (float)_borderThicknessRight * posZ / 100.0f);
int thicknessTop = (int)(_borderThicknessTop - (float)_borderThicknessTop * posZ / 100.0f);
@@ -386,7 +385,7 @@ bool PartEmitter::compareZ(const PartParticle *p1, const PartParticle *p2) {
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::setBorder(int x, int y, int width, int height) {
- BasePlatform::setRect(&_border, x, y, x + width, y + height);
+ _border.setRect(x, y, x + width, y + height);
return STATUS_OK;
}
@@ -1157,61 +1156,61 @@ const char *PartEmitter::scToString() {
bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_width));
- persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transferSint32(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_angle1));
- persistMgr->transfer(TMEMBER(_angle2));
+ persistMgr->transferSint32(TMEMBER(_angle1));
+ persistMgr->transferSint32(TMEMBER(_angle2));
- persistMgr->transfer(TMEMBER(_velocity1));
- persistMgr->transfer(TMEMBER(_velocity2));
- persistMgr->transfer(TMEMBER(_velocityZBased));
+ persistMgr->transferFloat(TMEMBER(_velocity1));
+ persistMgr->transferFloat(TMEMBER(_velocity2));
+ persistMgr->transferBool(TMEMBER(_velocityZBased));
- persistMgr->transfer(TMEMBER(_scale1));
- persistMgr->transfer(TMEMBER(_scale2));
- persistMgr->transfer(TMEMBER(_scaleZBased));
+ persistMgr->transferFloat(TMEMBER(_scale1));
+ persistMgr->transferFloat(TMEMBER(_scale2));
+ persistMgr->transferBool(TMEMBER(_scaleZBased));
- persistMgr->transfer(TMEMBER(_maxParticles));
+ persistMgr->transferSint32(TMEMBER(_maxParticles));
- persistMgr->transfer(TMEMBER(_lifeTime1));
- persistMgr->transfer(TMEMBER(_lifeTime2));
- persistMgr->transfer(TMEMBER(_lifeTimeZBased));
+ persistMgr->transferSint32(TMEMBER(_lifeTime1));
+ persistMgr->transferSint32(TMEMBER(_lifeTime2));
+ persistMgr->transferBool(TMEMBER(_lifeTimeZBased));
- persistMgr->transfer(TMEMBER(_genInterval));
- persistMgr->transfer(TMEMBER(_genAmount));
+ persistMgr->transferSint32(TMEMBER(_genInterval));
+ persistMgr->transferSint32(TMEMBER(_genAmount));
- persistMgr->transfer(TMEMBER(_running));
- persistMgr->transfer(TMEMBER(_overheadTime));
+ persistMgr->transferBool(TMEMBER(_running));
+ persistMgr->transferSint32(TMEMBER(_overheadTime));
- persistMgr->transfer(TMEMBER(_border));
- persistMgr->transfer(TMEMBER(_borderThicknessLeft));
- persistMgr->transfer(TMEMBER(_borderThicknessRight));
- persistMgr->transfer(TMEMBER(_borderThicknessTop));
- persistMgr->transfer(TMEMBER(_borderThicknessBottom));
+ persistMgr->transferRect32(TMEMBER(_border));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessLeft));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessRight));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessTop));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessBottom));
- persistMgr->transfer(TMEMBER(_fadeInTime));
- persistMgr->transfer(TMEMBER(_fadeOutTime));
+ persistMgr->transferSint32(TMEMBER(_fadeInTime));
+ persistMgr->transferSint32(TMEMBER(_fadeOutTime));
- persistMgr->transfer(TMEMBER(_alpha1));
- persistMgr->transfer(TMEMBER(_alpha2));
- persistMgr->transfer(TMEMBER(_alphaTimeBased));
+ persistMgr->transferSint32(TMEMBER(_alpha1));
+ persistMgr->transferSint32(TMEMBER(_alpha2));
+ persistMgr->transferBool(TMEMBER(_alphaTimeBased));
- persistMgr->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->transfer(TMEMBER(_exponentialGrowth));
+ persistMgr->transferFloat(TMEMBER(_growthRate1));
+ persistMgr->transferFloat(TMEMBER(_growthRate2));
+ persistMgr->transferBool(TMEMBER(_exponentialGrowth));
- persistMgr->transfer(TMEMBER(_useRegion));
+ persistMgr->transferBool(TMEMBER(_useRegion));
- persistMgr->transfer(TMEMBER_INT(_maxBatches));
- persistMgr->transfer(TMEMBER_INT(_batchesGenerated));
+ persistMgr->transferSint32(TMEMBER_INT(_maxBatches));
+ persistMgr->transferSint32(TMEMBER_INT(_batchesGenerated));
- persistMgr->transfer(TMEMBER(_emitEvent));
+ persistMgr->transferCharPtr(TMEMBER(_emitEvent));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
@@ -1220,12 +1219,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
uint32 numForces;
if (persistMgr->getIsSaving()) {
numForces = _forces.size();
- persistMgr->transfer(TMEMBER(numForces));
+ persistMgr->transferUint32(TMEMBER(numForces));
for (uint32 i = 0; i < _forces.size(); i++) {
_forces[i]->persist(persistMgr);
}
} else {
- persistMgr->transfer(TMEMBER(numForces));
+ persistMgr->transferUint32(TMEMBER(numForces));
for (uint32 i = 0; i < numForces; i++) {
PartForce *force = new PartForce(_gameRef);
force->persist(persistMgr);
@@ -1236,12 +1235,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
uint32 numParticles;
if (persistMgr->getIsSaving()) {
numParticles = _particles.size();
- persistMgr->transfer(TMEMBER(numParticles));
+ persistMgr->transferUint32(TMEMBER(numParticles));
for (uint32 i = 0; i < _particles.size(); i++) {
_particles[i]->persist(persistMgr);
}
} else {
- persistMgr->transfer(TMEMBER(numParticles));
+ persistMgr->transferUint32(TMEMBER(numParticles));
for (uint32 i = 0; i < numParticles; i++) {
PartParticle *particle = new PartParticle(_gameRef);
particle->persist(persistMgr);
@@ -1252,4 +1251,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..39d98c182e 100644
--- a/engines/wintermute/base/particles/part_force.cpp
+++ b/engines/wintermute/base/particles/part_force.cpp
@@ -49,17 +49,17 @@ PartForce::~PartForce(void) {
bool PartForce::persist(BasePersistenceManager *persistMgr) {
if (persistMgr->getIsSaving()) {
const char *name = getName();
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
} else {
const char *name;
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
setName(name);
}
- persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_direction));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferVector2(TMEMBER(_pos));
+ persistMgr->transferVector2(TMEMBER(_direction));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
return STATUS_OK;
}
-} // 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..11470561f0 100644
--- a/engines/wintermute/base/particles/part_particle.cpp
+++ b/engines/wintermute/base/particles/part_particle.cpp
@@ -45,7 +45,7 @@ PartParticle::PartParticle(BaseGame *inGame) : BaseClass(inGame) {
_creationTime = 0;
_lifeTime = 0;
_isDead = true;
- BasePlatform::setRectEmpty(&_border);
+ _border.setEmpty();
_state = PARTICLE_NORMAL;
_fadeStart = 0;
@@ -125,7 +125,7 @@ bool PartParticle::update(PartEmitter *emitter, uint32 currentTime, uint32 timer
}
// particle hit the border
- if (!_isDead && !BasePlatform::isRectEmpty(&_border)) {
+ if (!_isDead && !_border.isRectEmpty()) {
Point32 p;
p.x = (int32)_pos.x;
p.y = (int32)_pos.y;
@@ -230,32 +230,32 @@ bool PartParticle::fadeOut(uint32 currentTime, int fadeTime) {
//////////////////////////////////////////////////////////////////////////
bool PartParticle::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_alpha1));
- persistMgr->transfer(TMEMBER(_alpha2));
- persistMgr->transfer(TMEMBER(_border));
- persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_posZ));
- persistMgr->transfer(TMEMBER(_velocity));
- persistMgr->transfer(TMEMBER(_scale));
- persistMgr->transfer(TMEMBER(_creationTime));
- persistMgr->transfer(TMEMBER(_lifeTime));
- persistMgr->transfer(TMEMBER(_isDead));
- persistMgr->transfer(TMEMBER_INT(_state));
- persistMgr->transfer(TMEMBER(_fadeStart));
- persistMgr->transfer(TMEMBER(_fadeTime));
- persistMgr->transfer(TMEMBER(_currentAlpha));
- persistMgr->transfer(TMEMBER(_angVelocity));
- persistMgr->transfer(TMEMBER(_rotation));
- persistMgr->transfer(TMEMBER(_growthRate));
- persistMgr->transfer(TMEMBER(_exponentialGrowth));
- persistMgr->transfer(TMEMBER(_fadeStartAlpha));
+ persistMgr->transferSint32(TMEMBER(_alpha1));
+ persistMgr->transferSint32(TMEMBER(_alpha2));
+ persistMgr->transferRect32(TMEMBER(_border));
+ persistMgr->transferVector2(TMEMBER(_pos));
+ persistMgr->transferFloat(TMEMBER(_posZ));
+ persistMgr->transferVector2(TMEMBER(_velocity));
+ persistMgr->transferFloat(TMEMBER(_scale));
+ persistMgr->transferUint32(TMEMBER(_creationTime));
+ persistMgr->transferSint32(TMEMBER(_lifeTime));
+ persistMgr->transferBool(TMEMBER(_isDead));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
+ persistMgr->transferUint32(TMEMBER(_fadeStart));
+ persistMgr->transferSint32(TMEMBER(_fadeTime));
+ persistMgr->transferSint32(TMEMBER(_currentAlpha));
+ persistMgr->transferFloat(TMEMBER(_angVelocity));
+ persistMgr->transferFloat(TMEMBER(_rotation));
+ persistMgr->transferFloat(TMEMBER(_growthRate));
+ persistMgr->transferBool(TMEMBER(_exponentialGrowth));
+ persistMgr->transferSint32(TMEMBER(_fadeStartAlpha));
if (persistMgr->getIsSaving()) {
const char *filename = _sprite->getFilename();
- persistMgr->transfer(TMEMBER(filename));
+ persistMgr->transferConstChar(TMEMBER(filename));
} else {
char *filename;
- persistMgr->transfer(TMEMBER(filename));
+ persistMgr->transferCharPtr(TMEMBER(filename));
SystemClassRegistry::getInstance()->_disabled = true;
setSprite(filename);
SystemClassRegistry::getInstance()->_disabled = false;
@@ -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..5e4ae3ea95 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;
}
@@ -1248,15 +1249,15 @@ bool ScScript::persist(BasePersistenceManager *persistMgr) {
// buffer
if (persistMgr->getIsSaving()) {
if (_state != SCRIPT_PERSISTENT && _state != SCRIPT_FINISHED && _state != SCRIPT_THREAD_FINISHED) {
- persistMgr->transfer(TMEMBER(_bufferSize));
+ persistMgr->transferUint32(TMEMBER(_bufferSize));
persistMgr->putBytes(_buffer, _bufferSize);
} else {
// don't save idle/finished scripts
int32 bufferSize = 0;
- persistMgr->transfer(TMEMBER(bufferSize));
+ persistMgr->transferSint32(TMEMBER(bufferSize));
}
} else {
- persistMgr->transfer(TMEMBER(_bufferSize));
+ persistMgr->transferUint32(TMEMBER(_bufferSize));
if (_bufferSize > 0) {
_buffer = new byte[_bufferSize];
persistMgr->getBytes(_buffer, _bufferSize);
@@ -1269,31 +1270,31 @@ bool ScScript::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_callStack));
- persistMgr->transfer(TMEMBER(_currentLine));
+ persistMgr->transferSint32(TMEMBER(_currentLine));
persistMgr->transferPtr(TMEMBER_PTR(_engine));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferBool(TMEMBER(_freezable));
persistMgr->transferPtr(TMEMBER_PTR(_globals));
- persistMgr->transfer(TMEMBER(_iP));
+ persistMgr->transferUint32(TMEMBER(_iP));
persistMgr->transferPtr(TMEMBER_PTR(_scopeStack));
persistMgr->transferPtr(TMEMBER_PTR(_stack));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
persistMgr->transferPtr(TMEMBER_PTR(_operand));
- persistMgr->transfer(TMEMBER_INT(_origState));
+ persistMgr->transferSint32(TMEMBER_INT(_origState));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
persistMgr->transferPtr(TMEMBER_PTR(_reg1));
- persistMgr->transfer(TMEMBER(_thread));
- persistMgr->transfer(TMEMBER(_threadEvent));
+ persistMgr->transferBool(TMEMBER(_thread));
+ persistMgr->transferCharPtr(TMEMBER(_threadEvent));
persistMgr->transferPtr(TMEMBER_PTR(_thisStack));
- persistMgr->transfer(TMEMBER(_timeSlice));
+ persistMgr->transferUint32(TMEMBER(_timeSlice));
persistMgr->transferPtr(TMEMBER_PTR(_waitObject));
persistMgr->transferPtr(TMEMBER_PTR(_waitScript));
- persistMgr->transfer(TMEMBER(_waitTime));
- persistMgr->transfer(TMEMBER(_waitFrozen));
+ persistMgr->transferUint32(TMEMBER(_waitTime));
+ persistMgr->transferBool(TMEMBER(_waitFrozen));
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_unbreakable));
+ persistMgr->transferBool(TMEMBER(_methodThread));
+ persistMgr->transferBool(TMEMBER(_methodThread)); // TODO-SAVE: Deduplicate.
+ persistMgr->transferBool(TMEMBER(_unbreakable));
persistMgr->transferPtr(TMEMBER_PTR(_parentScript));
if (!persistMgr->getIsSaving()) {
@@ -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..c4ad045557 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -214,7 +214,7 @@ bool SXArray::scSetProperty(const char *name, ScValue *value) {
bool SXArray::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_length));
+ persistMgr->transferSint32(TMEMBER(_length));
persistMgr->transferPtr(TMEMBER_PTR(_values));
return STATUS_OK;
@@ -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..6b9c5ff68a 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_date.cpp
@@ -243,15 +243,15 @@ bool SXDate::persist(BasePersistenceManager *persistMgr) {
int32 hour = _tm.tm_hour;
int32 min = _tm.tm_min;
int32 sec = _tm.tm_sec;
- persistMgr->transfer(TMEMBER(year));
- persistMgr->transfer(TMEMBER(mon));
- persistMgr->transfer(TMEMBER(mday));
- persistMgr->transfer(TMEMBER(hour));
- persistMgr->transfer(TMEMBER(min));
- persistMgr->transfer(TMEMBER(sec));
+ persistMgr->transferSint32(TMEMBER(year));
+ persistMgr->transferSint32(TMEMBER(mon));
+ persistMgr->transferSint32(TMEMBER(mday));
+ persistMgr->transferSint32(TMEMBER(hour));
+ persistMgr->transferSint32(TMEMBER(min));
+ persistMgr->transferSint32(TMEMBER(sec));
if (persistMgr->checkVersion(1, 2, 1)) {
int32 wday = _tm.tm_wday;
- persistMgr->transfer(TMEMBER(wday));
+ persistMgr->transferSint32(TMEMBER(wday));
_tm.tm_wday = wday;
}
_tm.tm_year = year;
@@ -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..dcd4f01f7c 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_file.cpp
@@ -766,16 +766,16 @@ bool SXFile::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_mode));
- persistMgr->transfer(TMEMBER(_textMode));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferSint32(TMEMBER(_mode));
+ persistMgr->transferBool(TMEMBER(_textMode));
uint32 pos = 0;
if (persistMgr->getIsSaving()) {
pos = getPos();
- persistMgr->transfer(TMEMBER(pos));
+ persistMgr->transferUint32(TMEMBER(pos));
} else {
- persistMgr->transfer(TMEMBER(pos));
+ persistMgr->transferUint32(TMEMBER(pos));
// try to re-open file if needed
_writeFile = nullptr;
@@ -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 d816fbec65..ec53b983e7 100644
--- a/engines/wintermute/base/scriptables/script_ext_math.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_math.cpp
@@ -31,7 +31,6 @@
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/persistent.h"
#include "common/math.h"
-#include <math.h>
namespace Wintermute {
@@ -292,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..39f8b58644 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
@@ -498,7 +498,7 @@ bool SXMemBuffer::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_size));
+ persistMgr->transferSint32(TMEMBER(_size));
if (persistMgr->getIsSaving()) {
if (_size > 0) {
@@ -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..65bec03bc1 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -298,21 +298,13 @@ bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
uint32 start = 0;
for(uint32 i = 0; i < str.size() + 1; i++) {
- char ch = str.c_str()[i];
- if(ch=='\0' || delims.contains(ch))
- {
- char *part = new char[i - start + 1];
- if(i != start) {
- Common::strlcpy(part, str.c_str() + start, i - start + 1);
- part[i - start] = '\0';
+ uint32 ch = str[i];
+ if (ch =='\0' || delims.contains(ch)) {
+ if (i != start) {
+ parts.push_back(WideString(str.c_str() + start, i - start + 1));
} else {
- part[0] = '\0';
+ parts.push_back(WideString());
}
- val = new ScValue(_gameRef, part);
- array->push(val);
- delete[] part;
- delete val;
- val = nullptr;
start = i + 1;
}
}
@@ -406,7 +398,7 @@ bool SXString::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_capacity));
+ persistMgr->transferSint32(TMEMBER(_capacity));
if (persistMgr->getIsSaving()) {
if (_capacity > 0) {
@@ -430,4 +422,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..c828b3918e 100644
--- a/engines/wintermute/base/scriptables/script_stack.cpp
+++ b/engines/wintermute/base/scriptables/script_stack.cpp
@@ -186,10 +186,10 @@ bool ScStack::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_sP));
+ persistMgr->transferSint32(TMEMBER(_sP));
_values.persist(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..52367646a5 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -791,32 +791,32 @@ void ScValue::setValue(ScValue *val) {
bool ScValue::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_persistent));
- persistMgr->transfer(TMEMBER(_isConstVar));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_valBool));
- persistMgr->transfer(TMEMBER(_valFloat));
- persistMgr->transfer(TMEMBER(_valInt));
+ persistMgr->transferBool(TMEMBER(_persistent));
+ persistMgr->transferBool(TMEMBER(_isConstVar));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
+ persistMgr->transferBool(TMEMBER(_valBool));
+ persistMgr->transferDouble(TMEMBER(_valFloat));
+ persistMgr->transferSint32(TMEMBER(_valInt));
persistMgr->transferPtr(TMEMBER_PTR(_valNative));
int32 size;
const char *str;
if (persistMgr->getIsSaving()) {
size = _valObject.size();
- persistMgr->transfer("", &size);
+ persistMgr->transferSint32("", &size);
_valIter = _valObject.begin();
while (_valIter != _valObject.end()) {
str = _valIter->_key.c_str();
- persistMgr->transfer("", &str);
+ persistMgr->transferConstChar("", &str);
persistMgr->transferPtr("", &_valIter->_value);
_valIter++;
}
} else {
ScValue *val = nullptr;
- persistMgr->transfer("", &size);
+ persistMgr->transferSint32("", &size);
for (int i = 0; i < size; i++) {
- persistMgr->transfer("", &str);
+ persistMgr->transferConstChar("", &str);
persistMgr->transferPtr("", &val);
_valObject[str] = val;
@@ -825,7 +825,18 @@ bool ScValue::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_valRef));
- persistMgr->transfer(TMEMBER(_valString));
+ persistMgr->transferCharPtr(TMEMBER(_valString));
+
+ if (!persistMgr->getIsSaving() && !persistMgr->checkVersion(1,2,2)) {
+ // Savegames prior to 1.2.2 stored empty strings as NULL.
+ // 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+");
@@ -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..f9cd59e4fb 100644
--- a/engines/wintermute/base/sound/base_sound.cpp
+++ b/engines/wintermute/base/sound/base_sound.cpp
@@ -166,16 +166,16 @@ bool BaseSound::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_soundFilename));
- persistMgr->transfer(TMEMBER(_soundLooping));
- persistMgr->transfer(TMEMBER(_soundPaused));
- persistMgr->transfer(TMEMBER(_soundFreezePaused));
- persistMgr->transfer(TMEMBER(_soundPlaying));
- persistMgr->transfer(TMEMBER(_soundPosition));
- persistMgr->transfer(TMEMBER(_soundPrivateVolume));
- persistMgr->transfer(TMEMBER(_soundStreamed));
- persistMgr->transfer(TMEMBER_INT(_soundType));
- persistMgr->transfer(TMEMBER(_soundLoopStart));
+ persistMgr->transferString(TMEMBER(_soundFilename));
+ persistMgr->transferBool(TMEMBER(_soundLooping));
+ persistMgr->transferBool(TMEMBER(_soundPaused));
+ persistMgr->transferBool(TMEMBER(_soundFreezePaused));
+ persistMgr->transferBool(TMEMBER(_soundPlaying));
+ persistMgr->transferUint32(TMEMBER(_soundPosition));
+ persistMgr->transferSint32(TMEMBER(_soundPrivateVolume));
+ persistMgr->transferBool(TMEMBER(_soundStreamed));
+ persistMgr->transferSint32(TMEMBER_INT(_soundType));
+ persistMgr->transferUint32(TMEMBER(_soundLoopStart));
return STATUS_OK;
}
@@ -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..f1f79af760 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.
@@ -66,9 +66,9 @@ uint32 Timer::getTimeLast() const {
}
void Timer::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_timer));
- persistMgr->transfer(TMEMBER(_timerDelta));
- persistMgr->transfer(TMEMBER(_timerLast));
+ persistMgr->transferUint32(TMEMBER(_timer));
+ persistMgr->transferUint32(TMEMBER(_timerDelta));
+ persistMgr->transferUint32(TMEMBER(_timerLast));
}
} // End of namespace Wintermute
diff --git a/engines/wintermute/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..307989e58d 100644
--- a/engines/wintermute/coll_templ.h
+++ b/engines/wintermute/coll_templ.h
@@ -67,7 +67,7 @@ class BaseArray : public BaseArrayBase<TYPE> {
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<TYPE>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
typename Common::Array<TYPE>::const_iterator it = Common::Array<TYPE>::begin();
for (; it != Common::Array<TYPE>::end(); ++it) {
TYPE obj = *it;
@@ -75,7 +75,7 @@ class BaseArray : public BaseArrayBase<TYPE> {
}
} else {
Common::Array<TYPE>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
TYPE obj = nullptr;
persistMgr->transferPtr("", &obj);
@@ -93,18 +93,18 @@ class BaseArray<char *> : public BaseArrayBase<char *> {
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<char *>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
Common::Array<char *>::const_iterator it = Common::Array<char *>::begin();
for (; it != Common::Array<char *>::end(); ++it) {
char * obj = *it;
- persistMgr->transfer("", &obj);
+ persistMgr->transferCharPtr("", &obj);
}
} else {
Common::Array<char *>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
char * obj = nullptr;
- persistMgr->transfer("", &obj);
+ persistMgr->transferCharPtr("", &obj);
add(obj);
}
}
@@ -119,18 +119,18 @@ public:
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<const char *>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
Common::Array<const char *>::const_iterator it = Common::Array<const char *>::begin();
for (; it != Common::Array<const char *>::end(); ++it) {
const char * obj = *it;
- persistMgr->transfer("", &obj);
+ persistMgr->transferConstChar("", &obj);
}
} else {
Common::Array<const char *>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
const char * obj = nullptr;
- persistMgr->transfer("", &obj);
+ persistMgr->transferConstChar("", &obj);
add(obj);
}
}
@@ -138,6 +138,6 @@ public:
}
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/configure.engine b/engines/wintermute/configure.engine
new file mode 100644
index 0000000000..673549b46b
--- /dev/null
+++ b/engines/wintermute/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine wintermute "Wintermute" no "" "" "jpeg png zlib vorbis 16bit"
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..4371ee4889 100644
--- a/engines/wintermute/dctypes.h
+++ b/engines/wintermute/dctypes.h
@@ -31,6 +31,7 @@
#include "common/str.h"
+#include "common/ustr.h"
#include "common/list.h"
#include "common/array.h"
@@ -41,7 +42,7 @@ namespace Wintermute {
//typedef std::wstring WideString;
typedef Common::String AnsiString;
typedef Common::String Utf8String;
-typedef Common::String WideString; // NB: Not actually true I presume.
+typedef Common::U32String WideString;
typedef Common::List<WideString> WideStringList;
typedef Common::List<AnsiString> AnsiStringList;
@@ -220,6 +221,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..f4bd437803 100644
--- a/engines/wintermute/detection.cpp
+++ b/engines/wintermute/detection.cpp
@@ -68,6 +68,7 @@ static char s_fallbackGameIdBuf[256];
static const char *directoryGlobs[] = {
"language", // To detect the various languages
+ "languages", // To detect the various languages
0
};
@@ -181,7 +182,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 00ec51a715..46e05f2768 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -27,6 +27,7 @@ namespace Wintermute {
static const PlainGameDescriptor wintermuteGames[] = {
{"5ld", "Five Lethal Demons"},
{"5ma", "Five Magical Amulets"},
+ {"bthreshold", "Beyond the Threshold"},
{"actualdest", "Actual Destination"},
{"carolreed4", "Carol Reed 4 - East Side Story"},
{"carolreed5", "Carol Reed 5 - The Colour of Murder"},
@@ -36,17 +37,29 @@ static const PlainGameDescriptor wintermuteGames[] = {
{"carolreed9", "Carol Reed 9 - Cold Case Summer"},
{"chivalry", "Chivalry is Not Dead"},
{"deadcity", "Dead City"},
+ {"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"},
+ {"helga", "Helga Deep In Trouble"},
+ {"jamesperis", "James Peris: No License Nor Control"},
+ {"looky", "Looky"},
{"julia", "J.U.L.I.A."},
{"mirage", "Mirage"},
+ {"paintaria", "Paintaria"},
{"pigeons", "Pigeons in the Park"},
{"reversion1", "Reversion: The Escape"},
- {"reversion2", "Reversion: The Meeting"},
+ {"reversion2", "Reversion: The Meeting"},
{"rosemary", "Rosemary"},
+ {"shaban", "Shaban"},
+ {"shinestar", "The Shine of a Star"},
+ {"spaceinvaders", "Space Invaders"},
+ {"spacemadness", "Space Madness"},
{"thebox", "The Box"},
+ {"tib", "Fairy Tales About Toshechka and Boshechka"},
+ {"tradestory", "The Trader of Stories"},
{"twc", "the white chamber"},
{"wintermute", "Wintermute engine game"},
{0, 0}
@@ -83,6 +96,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Beyond the Threshold
+ {
+ "bthreshold",
+ "",
+ AD_ENTRY1s("data.dcp", "d49bf9ccb2e74507447c82d6ad3e2bc4", 12773712),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Carol Reed 4 - East Side Story (Demo)
{
"carolreed4",
@@ -125,6 +148,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",
@@ -175,6 +209,22 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_TESTING,
GUIO0()
},
+ // Dead City (Czech)
+ {
+ "deadcity",
+ "",
+ {
+ // The Czech data are in data.dcp, so in this case we'll have to
+ // just detect the english version twice, to give the user a choice.
+ {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935},
+ {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205},
+ AD_LISTEND
+ },
+ Common::CZ_CZE,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Dead City (English)
{
"deadcity",
@@ -237,6 +287,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Des Reves Elastiques Avec Mille Insectes Nommes Georges
+ {
+ "dreaming",
+ "",
+ AD_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Dreamscape
{
"dreamscape",
@@ -247,6 +307,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",
@@ -268,6 +348,63 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Helga Deep In Trouble (Demo) (English)
+ {
+ "helga",
+ "Demo",
+ {
+ {"english.dcp", 0, "b3a93e678f0ef97200f691cd1724643f", 135864},
+ {"data.dcp", 0, "45134ed93bc391edf148b79cdcbf2a09", 154266028},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // James Peris: No License Nor Control (English)
+ {
+ "jamesperis",
+ "",
+ 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::ES_ESP,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// J.U.L.I.A. (English)
{
"julia",
@@ -289,6 +426,61 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO0()
},
+ // J.U.L.I.A. (English) (Greenlight Demo)
+ {
+ "julia",
+ "Greenlight Demo",
+ AD_ENTRY1s("data.dcp", "4befd448d36b0dae9c3ab1aa7cb8b78d", 7271886),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // Looky Demo (English)
+ {
+ "looky",
+ "Demo",
+ {
+ {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // Looky Demo (German)
+ {
+ "looky",
+ "Demo",
+ {
+ {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // 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",
@@ -299,6 +491,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Paintaria
+ {
+ "paintaria",
+ "",
+ AD_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Pigeons in the Park
{
"pigeons",
@@ -535,6 +737,47 @@ 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 Invaders (Demo)
+ {
+ "spaceinvaders",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
+ // Space Madness
+ {
+ "spacemadness",
+ "1.0.2",
+ AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Box
{
"thebox",
@@ -545,6 +788,27 @@ 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",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "0a0b51191636cc8ead89b905281c3218", 40401902),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// the white chamber (multi-language)
{
"twc",
diff --git a/engines/wintermute/graphics/transform_struct.cpp b/engines/wintermute/graphics/transform_struct.cpp
new file mode 100644
index 0000000000..822c06f42f
--- /dev/null
+++ b/engines/wintermute/graphics/transform_struct.cpp
@@ -0,0 +1,119 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#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;
+ _numTimesX = 1;
+ _numTimesY = 1;
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
+ init(Point32(zoomX, zoomY),
+ angle,
+ Point32(hotspotX, hotspotY),
+ false,
+ blendMode,
+ rgbaMod,
+ mirrorX, mirrorY,
+ Point32(offsetX, offsetY));
+}
+
+TransformStruct::TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
+ init(Point32((int32)(zoomX / 100.0 * kDefaultZoomX),
+ (int32)(zoomY / 100.0 * kDefaultZoomY)),
+ 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(int32 numTimesX, int32 numTimesY) {
+ init(Point32(kDefaultZoomX, kDefaultZoomY),
+ kDefaultAngle,
+ Point32(kDefaultHotspotX, kDefaultHotspotY),
+ false,
+ BLEND_NORMAL,
+ kDefaultRgbaMod,
+ false, false,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+ _numTimesX = numTimesX;
+ _numTimesY = numTimesY;
+}
+
+TransformStruct::TransformStruct() {
+ init(Point32(kDefaultZoomX, kDefaultZoomY),
+ kDefaultAngle,
+ 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..d5a03ea331
--- /dev/null
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef 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 int32 kDefaultZoomX = 100;
+const int32 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(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
+ TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false);
+ TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX = 0, int32 hotspotY = 0);
+ TransformStruct(int32 numTimesX, int32 numTimesY);
+ TransformStruct();
+
+ Point32 _zoom; ///< Zoom; 100 = no zoom
+ Point32 _hotspot; ///< Position of the hotspot
+ int32 _angle; ///< Rotation angle, in degrees
+ byte _flip; ///< Bitflag: see TransparentSurface::FLIP_XXX
+ bool _alphaDisable;
+ TSpriteBlendMode _blendMode;
+ uint32 _rgbaMod; ///< RGBa
+ Point32 _offset;
+ int32 _numTimesX;
+ int32 _numTimesY;
+
+ 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 &&
+ compare._numTimesX == _numTimesX &&
+ compare._numTimesY == _numTimesY
+ );
+ }
+
+ 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..dc92cdbbfd
--- /dev/null
+++ b/engines/wintermute/graphics/transform_tools.cpp
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "engines/wintermute/graphics/transform_tools.h"
+#include <math.h>
+
+namespace Wintermute {
+
+FloatPoint TransformTools::transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) {
+ float rotateRad = rotate * M_PI / 180.0f;
+ float x = point.x;
+ float y = point.y;
+ x = (x * zoom.x) / kDefaultZoomX;
+ y = (y * zoom.y) / kDefaultZoomY;
+#if 0
+ // TODO: Mirroring should be done before rotation, but the blitting
+ // code does the inverse, so we match that for now.
+ if (mirrorX)
+ x *= -1;
+ if (mirrorY)
+ y *= -1;
+#endif
+ FloatPoint newPoint;
+ newPoint.x = x * cos(rotateRad) - y * sin(rotateRad);
+ newPoint.y = x * sin(rotateRad) + y * cos(rotateRad);
+ 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)));
+
+ if (newHotspot) {
+ newHotspot->y = (uint32)(-floor(top));
+ newHotspot->x = (uint32)(-floor(left));
+ }
+
+ Rect32 res;
+ res.top = (int32)(floor(top)) + transform._hotspot.y;
+ res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y;
+ res.left = (int32)(floor(left)) + transform._hotspot.x;
+ 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..9a73e3b69f
--- /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(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..053acf29e9 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -17,28 +17,268 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * The bottom part of this is file is adapted from SDL_rotozoom.c. The
+ * relevant copyright notice for those specific functions can be found at the
+ * top of that section.
+ *
*/
+
+
#include "common/algorithm.h"
#include "common/endian.h"
#include "common/util.h"
#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"
+
+//#define ENABLE_BILINEAR
namespace Wintermute {
-byte *TransparentSurface::_lookup = nullptr;
+void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
+void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
+
+// These gather together various blendPixel functions for use with templates.
+
+class BlenderAdditive {
+public:
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+class BlenderSubtractive {
+public:
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+class BlenderNormal {
+public:
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+/**
+ * Perform additive blending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+ if (*ca != 255) {
+ ina = (ina) * (*ca) >> 8;
+ }
+
+ if (ina == 0) {
+ return;
+ } else {
+ if (*cb != 255)
+ *outb = MIN(*outb + ((inb * (*cb) * ina) >> 16), 255);
+ else
+ *outb = MIN(*outb + (inb * ina >> 8), 255);
+
+ if (*cg != 255)
+ *outg = MIN(*outg + ((ing * (*cg) * ina) >> 16), 255);
+ else
+ *outg = MIN(*outg + (ing * ina >> 8), 255);
+
+ if (*cr != 255)
+ *outr = MIN(*outr + ((inr * (*cr) * ina) >> 16), 255);
+ else
+ *outr = MIN(*outr + (inr * ina >> 8), 255);
+ }
+}
+
+/**
+ * Perform subtractive blending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+ //if (*ca != 255) {
+ // ina = ina * (*ca) >> 8;
+ // }
+
+ // As weird as it is, evidence suggests that alphamod is ignored when doing
+ // subtractive...
+
+ // TODO if ina == 255 fast version
+
+ if (ina == 0) {
+ return;
+ } else {
+ if (*cb != 255)
+ *outb = MAX(*outb - ((inb * (*cb) * (*outb) * ina) >> 24), 0);
+ else
+ *outb = MAX(*outb - (inb * (*outb) * ina >> 16), 0);
+
+ if (*cg != 255)
+ *outg = MAX(*outg - ((ing * (*cg) * (*outg) * ina) >> 24), 0);
+ else
+ *outg = MAX(*outg - (ing * (*outg) * ina >> 16), 0);
+
+ if (*cr != 255)
+ *outr = MAX(*outr - ((inr * (*cr) * (*outr) * ina) >> 24), 0);
+ else
+ *outr = MAX(*outr - (inr * (*outr) * ina >> 16), 0);
+ }
+}
+
+/**
+ * Perform "regular" alphablending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+
+void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+ if (*ca != 255) {
+ ina = ina * (*ca) >> 8;
+ }
+
+ if (ina == 0) {
+ return;
+ } else if (ina == 255) {
+ if (*cb != 255)
+ *outb = (inb * (*cb)) >> 8;
+ else
+ *outb = inb;
+
+ if (*cr != 255)
+ *outr = (inr * (*cr)) >> 8;
+ else
+ *outr = inr;
+
+ if (*cg != 255)
+ *outg = (ing * (*cg)) >> 8;
+ else
+ *outg = ing;
+
+ *outa = ina;
-void TransparentSurface::destroyLookup() {
- delete[] _lookup;
- _lookup = nullptr;
+ return;
+
+ } else {
+
+ *outa = 255;
+ *outb = (*outb * (255 - ina) >> 8);
+ *outr = (*outr * (255 - ina) >> 8);
+ *outg = (*outg * (255 - ina) >> 8);
+
+ if (*cb == 0)
+ *outb = *outb;
+ else if (*cb != 255)
+ *outb = *outb + (inb * ina * (*cb) >> 16);
+ else
+ *outb = *outb + (inb * ina >> 8);
+
+ if (*cr == 0)
+ *outr = *outr;
+ else if (*cr != 255)
+ *outr = *outr + (inr * ina * (*cr) >> 16);
+ else
+ *outr = *outr + (inr * ina >> 8);
+
+ if (*cg == 0)
+ *outg = *outg;
+ else if (*cg != 255)
+ *outg = *outg + (ing * ina * (*cg) >> 16);
+ else
+ *outg = *outg + (ing * ina >> 8);
+
+ return;
+ }
+}
+
+/**
+ * Perform "regular" alphablending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+
+void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+ if (ina == 0) {
+ return;
+ } else if (ina == 255) {
+ *outb = inb;
+ *outg = ing;
+ *outr = inr;
+ *outa = ina;
+ return;
+ } else {
+ *outa = 255;
+ *outb = ((inb * ina) + *outb * (255 - ina)) >> 8;
+ *outg = ((ing * ina) + *outg * (255 - ina)) >> 8;
+ *outr = ((inr * ina) + *outr * (255 - ina)) >> 8;
+ }
+}
+
+/**
+ * Perform subtractive blending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+ if (ina == 0) {
+ return;
+ } else if (ina == 255) {
+ *outa = *outa;
+ *outr = *outr - (inr * (*outr) >> 8);
+ *outg = *outg - (ing * (*outg) >> 8);
+ *outb = *outb - (inb * (*outb) >> 8);
+ return;
+ } else {
+ *outa = *outa;
+ *outb = MAX(*outb - ((inb * (*outb)) * ina >> 16), 0);
+ *outg = MAX(*outg - ((ing * (*outg)) * ina >> 16), 0);
+ *outr = MAX(*outr - ((inr * (*outr)) * ina >> 16), 0);
+ return;
+ }
+}
+
+/**
+ * Perform additive blending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+ if (ina == 0) {
+ return;
+ } else if (ina == 255) {
+ *outa = *outa;
+ *outr = MIN(*outr + inr, 255);
+ *outg = MIN(*outg + ing, 255);
+ *outb = MIN(*outb + inb, 255);
+ return;
+ } else {
+ *outa = *outa;
+ *outb = MIN((inb * ina >> 8) + *outb, 255);
+ *outg = MIN((ing * ina >> 8) + *outg, 255);
+ *outr = MIN((inr * ina >> 8) + *outr, 255);
+ return;
+ }
}
-TransparentSurface::TransparentSurface() : Surface(), _enableAlphaBlit(true) {}
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _enableAlphaBlit(true) {
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
+
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
if (copyData) {
copyFrom(surf);
} else {
@@ -46,25 +286,27 @@ 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) {
- byte *in, *out;
+/**
+ * Optimized version of doBlit to be used w/opaque blitting (no alpha).
+ */
+void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
-#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
-#else
- const int aIndex = 0;
-#endif
+ byte *in;
+ byte *out;
for (uint32 i = 0; i < height; i++) {
out = outo;
in = ino;
memcpy(out, in, width * 4);
for (uint32 j = 0; j < width; j++) {
- out[aIndex] = 0xFF;
+ out[TransparentSurface::kAIndex] = 0xFF;
out += 4;
}
outo += pitch;
@@ -72,98 +314,110 @@ 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 TransparentSurface::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 gIndex = 2;
- const int rIndex = 1;
-#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;
+/**
+ * Optimized version of doBlit to be used w/binary blitting (blit or no-blit, no blending).
+ */
+void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ byte *in;
+ byte *out;
for (uint32 i = 0; i < height; i++) {
out = outo;
in = ino;
for (uint32 j = 0; j < width; j++) {
uint32 pix = *(uint32 *)in;
- uint32 oPix = *(uint32 *) out;
- int b = (pix >> bShift) & 0xff;
- int g = (pix >> gShift) & 0xff;
- int r = (pix >> rShift) & 0xff;
- int a = (pix >> aShift) & 0xff;
- int outb, outg, outr, outa;
- in += inStep;
+ int a = (pix >> TransparentSurface::kAShift) & 0xff;
- switch (a) {
- case 0: // Full transparency
- out += 4;
- break;
- case 255: // Full opacity
- outb = b;
- outg = g;
- outr = r;
- outa = a;
-
- out[aIndex] = outa;
- out[bIndex] = outb;
- out[gIndex] = outg;
- out[rIndex] = outr;
- out += 4;
- break;
-
- 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)];
-
- out[aIndex] = outa;
- out[bIndex] = outb;
- out[gIndex] = outg;
- out[rIndex] = outr;
- out += 4;
+ if (a == 0) { // Full transparency
+ } else { // Full opacity (Any value not exactly 0 is Opaque here)
+ *(uint32 *)out = pix;
+ out[TransparentSurface::kAIndex] = 0xFF;
}
+ out += 4;
+ in += inStep;
}
outo += pitch;
ino += inoStep;
}
}
+/**
+ * What we have here is a template method that calls blendPixel() from a different
+ * class - the one we call it with - thus performing a different type of blending.
+ *
+ * @param ino a pointer to the input surface
+ * @param outo a pointer to the output surface
+ * @param width width of the input surface
+ * @param height height of the input surface
+ * @param pitch pitch of the output surface - that is, width in bytes of every row, usually bpp * width of the TARGET surface (the area we are blitting to might be smaller, do the math)
+ * @inStep size in bytes to skip to address each pixel, usually bpp of the source surface
+ * @inoStep width in bytes of every row on the *input* surface / kind of like pitch
+ * @color colormod in 0xAARRGGBB format - 0xFFFFFFFF for no colormod
+ */
-Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height) {
- int ca = (color >> 24) & 0xff;
+template<class Blender>
+void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+ Blender b;
+ byte *in;
+ byte *out;
+
+ if (color == 0xffffffff) {
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+
+ byte *outa = &out[TransparentSurface::kAIndex];
+ byte *outr = &out[TransparentSurface::kRIndex];
+ byte *outg = &out[TransparentSurface::kGIndex];
+ byte *outb = &out[TransparentSurface::kBIndex];
+
+ b.blendPixel(in[TransparentSurface::kAIndex],
+ in[TransparentSurface::kRIndex],
+ in[TransparentSurface::kGIndex],
+ in[TransparentSurface::kBIndex],
+ outa, outr, outg, outb);
+
+ in += inStep;
+ out += 4;
+ }
+ outo += pitch;
+ ino += inoStep;
+ }
+ } else {
+
+ byte ca = (color >> TransparentSurface::kAModShift) & 0xFF;
+ byte cr = (color >> TransparentSurface::kRModShift) & 0xFF;
+ byte cg = (color >> TransparentSurface::kGModShift) & 0xFF;
+ byte cb = (color >> TransparentSurface::kBModShift) & 0xFF;
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+
+ byte *outa = &out[TransparentSurface::kAIndex];
+ byte *outr = &out[TransparentSurface::kRIndex];
+ byte *outg = &out[TransparentSurface::kGIndex];
+ byte *outb = &out[TransparentSurface::kBIndex];
+
+ b.blendPixel(in[TransparentSurface::kAIndex],
+ in[TransparentSurface::kRIndex],
+ in[TransparentSurface::kGIndex],
+ in[TransparentSurface::kBIndex],
+ outa, outr, outg, outb, &ca, &cr, &cg, &cb);
+ in += inStep;
+ out += 4;
+ }
+ outo += pitch;
+ ino += inoStep;
+ }
+ }
+}
+
+Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height, TSpriteBlendMode blendMode) {
Common::Rect retSize;
retSize.top = 0;
@@ -171,21 +425,11 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
retSize.setWidth(0);
retSize.setHeight(0);
// Check if we need to draw anything at all
+ int ca = (color >> 24) & 0xff;
+
if (ca == 0)
return retSize;
- int cr = (color >> 16) & 0xff;
- 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,7 +439,19 @@ 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();
@@ -224,7 +480,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 +488,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,132 +506,41 @@ 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;
}
- byte *ino = (byte *)img->getBasePtr(xp, yp);
+ byte *ino= (byte *)img->getBasePtr(xp, yp);
byte *outo = (byte *)target.getBasePtr(posX, posY);
- 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 gIndex = 2;
- const int rIndex = 1;
-#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;
-
- if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
- if (_enableAlphaBlit) {
- doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else {
- doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- }
+ if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
+ doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
+ doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
} else {
- for (int i = 0; i < img->h; i++) {
- out = outo;
- in = ino;
- for (int j = 0; j < img->w; j++) {
- uint32 pix = *(uint32 *)in;
- uint32 o_pix = *(uint32 *) out;
- int b = (pix >> bShift) & 0xff;
- int g = (pix >> gShift) & 0xff;
- int r = (pix >> rShift) & 0xff;
- int a = (pix >> aShift) & 0xff;
- int outb, outg, outr, outa;
- in += inStep;
-
- if (ca != 255) {
- a = a * ca >> 8;
- }
-
- switch (a) {
- case 0: // Full transparency
- out += 4;
- break;
- case 255: // Full opacity
- if (cb != 255)
- outb = (b * cb) >> 8;
- else
- outb = b;
-
- if (cg != 255)
- outg = (g * cg) >> 8;
- else
- outg = g;
-
- if (cr != 255)
- outr = (r * cr) >> 8;
- else
- outr = r;
- outa = a;
- out[aIndex] = outa;
- out[bIndex] = outb;
- out[gIndex] = outg;
- out[rIndex] = outr;
- out += 4;
- break;
-
- default: // alpha blending
- outa = 255;
- outb = (o_pix >> bShiftTarget) & 0xff;
- outg = (o_pix >> gShiftTarget) & 0xff;
- outr = (o_pix >> rShiftTarget) & 0xff;
- if (cb == 0)
- outb = 0;
- else if (cb != 255)
- outb += ((b - outb) * a * cb) >> 16;
- else
- outb += ((b - outb) * a) >> 8;
- if (cg == 0)
- outg = 0;
- else if (cg != 255)
- outg += ((g - outg) * a * cg) >> 16;
- else
- outg += ((g - outg) * a) >> 8;
- if (cr == 0)
- outr = 0;
- else if (cr != 255)
- outr += ((r - outr) * a * cr) >> 16;
- else
- outr += ((r - outr) * a) >> 8;
- out[aIndex] = outa;
- out[bIndex] = outb;
- out[gIndex] = outg;
- out[rIndex] = outr;
- out += 4;
- }
- }
- outo += target.pitch;
- ino += inoStep;
+ if (blendMode == BLEND_ADDITIVE) {
+ doBlit<BlenderAdditive>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+ } else if (blendMode == BLEND_SUBTRACTIVE) {
+ doBlit<BlenderSubtractive>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+ } else {
+ assert(blendMode == BLEND_NORMAL);
+ doBlit<BlenderNormal>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
}
}
+
}
retSize.setWidth(img->w);
retSize.setHeight(img->h);
if (imgScaled) {
- imgScaled->pixels = savedPixels;
+ imgScaled->setPixels(savedPixels);
imgScaled->free();
delete imgScaled;
}
@@ -383,38 +548,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
return retSize;
}
-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);
-
- int srcW = srcRect.width();
- int srcH = srcRect.height();
- int dstW = dstRect.width();
- int dstH = dstRect.height();
-
- target->create((uint16)dstW, (uint16)dstH, this->format);
-
- 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);
- }
- }
- return target;
-
-}
-
/**
* Writes a color key to the alpha channel of the surface
* @param rKey the red component of the color key
@@ -440,4 +573,351 @@ void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool
}
}
-} // End of namespace Graphics
+TransparentSurface::AlphaType TransparentSurface::getAlphaMode() const {
+ return _alphaMode;
+}
+
+void TransparentSurface::setAlphaMode(TransparentSurface::AlphaType mode) {
+ _alphaMode = mode;
+}
+
+
+
+
+
+
+/*
+
+The below two functions are adapted from SDL_rotozoom.c,
+taken from SDL_gfx-2.0.18.
+
+Its copyright notice:
+
+=============================================================================
+SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012 Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+=============================================================================
+
+
+The functions have been adapted for different structures and coordinate
+systems.
+
+*/
+
+
+
+
+
+TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
+
+ assert(transform._angle != 0); // This would not be ideal; rotoscale() should never be called in conditional branches where angle = 0 anyway.
+
+ 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 srcW = w;
+ int srcH = h;
+ int dstW = dstRect.width();
+ int dstH = dstRect.height();
+
+ target->create((uint16)dstW, (uint16)dstH, this->format);
+
+ if (transform._zoom.x == 0 || transform._zoom.y == 0)
+ return target;
+
+ uint32 invAngle = 360 - (transform._angle % 360);
+ float invCos = cos(invAngle * M_PI / 180.0);
+ float invSin = sin(invAngle * M_PI / 180.0);
+
+ struct tColorRGBA { byte r; byte g; byte b; byte a; };
+ int icosx = (int)(invCos * (65536.0f * kDefaultZoomX / transform._zoom.x));
+ int isinx = (int)(invSin * (65536.0f * kDefaultZoomX / transform._zoom.x));
+ int icosy = (int)(invCos * (65536.0f * kDefaultZoomY / transform._zoom.y));
+ int isiny = (int)(invSin * (65536.0f * kDefaultZoomY / transform._zoom.y));
+
+
+ bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
+
+ int xd = (srcRect.left + transform._hotspot.x) << 16;
+ int yd = (srcRect.top + transform._hotspot.y) << 16;
+ int cx = newHotspot.x;
+ int cy = newHotspot.y;
+
+ int ax = -icosx * cx;
+ int ay = -isiny * cx;
+ int sw = srcW - 1;
+ int sh = srcH - 1;
+
+ tColorRGBA *pc = (tColorRGBA*)target->getBasePtr(0, 0);
+
+ for (int y = 0; y < dstH; y++) {
+ int t = cy - y;
+ int sdx = ax + (isinx * t) + xd;
+ int sdy = ay - (icosy * t) + yd;
+ for (int x = 0; x < dstW; x++) {
+ int dx = (sdx >> 16);
+ int dy = (sdy >> 16);
+ if (flipx) dx = sw - dx;
+ if (flipy) dy = sh - dy;
+
+#ifdef ENABLE_BILINEAR
+ if ((dx > -1) && (dy > -1) && (dx < sw) && (dy < sh)) {
+ const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+ tColorRGBA c00, c01, c10, c11, cswap;
+ c00 = *sp;
+ sp += 1;
+ c01 = *sp;
+ sp += (this->pitch/4);
+ c11 = *sp;
+ sp -= 1;
+ c10 = *sp;
+ if (flipx) {
+ cswap = c00; c00=c01; c01=cswap;
+ cswap = c10; c10=c11; c11=cswap;
+ }
+ if (flipy) {
+ cswap = c00; c00=c10; c10=cswap;
+ cswap = c01; c01=c11; c11=cswap;
+ }
+ /*
+ * Interpolate colors
+ */
+ int ex = (sdx & 0xffff);
+ int ey = (sdy & 0xffff);
+ int t1, t2;
+ t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+ t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+ pc->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+ t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+ pc->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+ t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+ pc->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+ t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+ pc->a = (((t2 - t1) * ey) >> 16) + t1;
+ }
+#else
+ if ((dx >= 0) && (dy >= 0) && (dx < srcW) && (dy < srcH)) {
+ const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+ *pc = *sp;
+ }
+#endif
+ sdx += icosx;
+ sdy += isiny;
+ pc++;
+ }
+ }
+ return target;
+}
+
+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);
+
+ TransparentSurface *target = new TransparentSurface();
+
+ assert(format.bytesPerPixel == 4);
+
+ int srcW = srcRect.width();
+ int srcH = srcRect.height();
+ int dstW = dstRect.width();
+ int dstH = dstRect.height();
+
+ target->create((uint16)dstW, (uint16)dstH, this->format);
+
+#ifdef ENABLE_BILINEAR
+
+ // NB: The actual order of these bytes may not be correct, but
+ // since all values are treated equal, that does not matter.
+ struct tColorRGBA { byte r; byte g; byte b; byte a; };
+
+ bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
+
+
+ int *sax = new int[dstW+1];
+ int *say = new int[dstH+1];
+ assert(sax && say);
+
+ /*
+ * Precalculate row increments
+ */
+ int spixelw = (srcW - 1);
+ int spixelh = (srcH - 1);
+ int sx = (int) (65536.0f * (float) spixelw / (float) (dstW - 1));
+ int sy = (int) (65536.0f * (float) spixelh / (float) (dstH - 1));
+
+ /* Maximum scaled source size */
+ int ssx = (srcW << 16) - 1;
+ int ssy = (srcH << 16) - 1;
+
+ /* Precalculate horizontal row increments */
+ int csx = 0;
+ int *csax = sax;
+ for (int x = 0; x <= dstW; x++) {
+ *csax = csx;
+ csax++;
+ csx += sx;
+
+ /* Guard from overflows */
+ if (csx > ssx) {
+ csx = ssx;
+ }
+ }
+
+ /* Precalculate vertical row increments */
+ int csy = 0;
+ int *csay = say;
+ for (int y = 0; y <= dstH; y++) {
+ *csay = csy;
+ csay++;
+ csy += sy;
+
+ /* Guard from overflows */
+ if (csy > ssy) {
+ csy = ssy;
+ }
+ }
+
+ const tColorRGBA *sp = (const tColorRGBA *) getBasePtr(0,0);
+ tColorRGBA *dp = (tColorRGBA *) target->getBasePtr(0,0);
+ int spixelgap = srcW;
+
+ if (flipx)
+ sp += spixelw;
+ if (flipy)
+ sp += spixelgap * spixelh;
+
+ csay = say;
+ for (int y = 0; y < dstH; y++) {
+ const tColorRGBA *csp = sp;
+ csax = sax;
+ for (int x = 0; x < dstW; x++) {
+ /*
+ * Setup color source pointers
+ */
+ int ex = (*csax & 0xffff);
+ int ey = (*csay & 0xffff);
+ int cx = (*csax >> 16);
+ int cy = (*csay >> 16);
+
+ const tColorRGBA *c00, *c01, *c10, *c11;
+ c00 = sp;
+ c01 = sp;
+ c10 = sp;
+ if (cy < spixelh) {
+ if (flipy)
+ c10 -= spixelgap;
+ else
+ c10 += spixelgap;
+ }
+ c11 = c10;
+ if (cx < spixelw) {
+ if (flipx) {
+ c01--;
+ c11--;
+ } else {
+ c01++;
+ c11++;
+ }
+ }
+
+ /*
+ * Draw and interpolate colors
+ */
+ int t1, t2;
+ t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+ t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+ dp->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+ t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+ dp->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+ t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+ dp->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+ t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+ dp->a = (((t2 - t1) * ey) >> 16) + t1;
+
+ /*
+ * Advance source pointer x
+ */
+ int *salastx = csax;
+ csax++;
+ int sstepx = (*csax >> 16) - (*salastx >> 16);
+ if (flipx)
+ sp -= sstepx;
+ else
+ sp += sstepx;
+
+ /*
+ * Advance destination pointer x
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer y
+ */
+ int *salasty = csay;
+ csay++;
+ int sstepy = (*csay >> 16) - (*salasty >> 16);
+ sstepy *= spixelgap;
+ if (flipy)
+ sp = csp - sstepy;
+ else
+ sp = csp + sstepy;
+ }
+
+ delete[] sax;
+ delete[] say;
+
+#else
+
+ int *scaleCacheX = new int[dstW];
+ for (int x = 0; x < dstW; x++)
+ scaleCacheX[x] = (x * srcW) / dstW;
+
+ for (int y = 0; y < dstH; y++) {
+ uint32 *destP = (uint32 *)target->getBasePtr(0, y);
+ const uint32 *srcP = (const uint32 *)getBasePtr(0, (y * srcH) / dstH);
+ for (int x = 0; x < dstW; x++)
+ *destP++ = srcP[scaleCacheX[x]];
+ }
+ delete[] scaleCacheX;
+
+#endif
+
+ return target;
+
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index dc079a1fbc..1f3827d1a9 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -23,6 +23,7 @@
#define GRAPHICS_TRANSPARENTSURFACE_H
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transform_struct.h"
/*
* This code is based on Broken Sword 2.5 engine
@@ -66,50 +67,94 @@ struct TransparentSurface : public Graphics::Surface {
FLIP_VH = FLIP_H | FLIP_V
};
- bool _enableAlphaBlit;
+ enum AlphaType {
+ ALPHA_OPAQUE = 0,
+ ALPHA_BINARY = 1,
+ ALPHA_FULL = 2
+ };
+
+ #ifdef SCUMM_LITTLE_ENDIAN
+ static const int kAIndex = 0;
+ static const int kBIndex = 1;
+ static const int kGIndex = 2;
+ static const int kRIndex = 3;
+ #else
+ static const int kAIndex = 3;
+ static const int kBIndex = 2;
+ static const int kGIndex = 1;
+ static const int kRIndex = 0;
+ #endif
+
+ static const int kBShift = 8;//img->format.bShift;
+ static const int kGShift = 16;//img->format.gShift;
+ static const int kRShift = 24;//img->format.rShift;
+ static const int kAShift = 0;//img->format.aShift;
+
+
+ static const int kBModShift = 0;//img->format.bShift;
+ static const int kGModShift = 8;//img->format.gShift;
+ static const int kRModShift = 16;//img->format.rShift;
+ static const int kAModShift = 24;//img->format.aShift;
+
/**
@brief renders the surface to another surface
- @param pDest a pointer to the target image. In most cases this is the framebuffer.
- @param PosX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
+ @param target a pointer to the target surface. In most cases this is the framebuffer.
+ @param posX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
The default value is 0.
- @param PosY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
+ @param posY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
The default value is 0.
- @param Flipping how the the image should be flipped.<br>
+ @param flipping how the the image should be flipped.<br>
The default value is BS_Image::FLIP_NONE (no flipping)
- @param pSrcPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
+ @param pPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
This referes to the unflipped and unscaled image.<br>
The default value is NULL.
- @param Color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
+ @param color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
The alpha component of the color determines the alpha blending parameter (0 = no covering, 255 = full covering).<br>
The color components determines the color for color modulation.<br>
The default value is BS_ARGB(255, 255, 255, 255) (full covering, no color modulation).
The macros BS_RGB and BS_ARGB can be used for the creation of the color value.
- @param Width the output width of the screen section.
+ @param width the output width of the screen section.
The images will be scaled if the output width of the screen section differs from the image section.<br>
The value -1 determines that the image should not be scaled.<br>
The default value is -1.
- @param Width the output height of the screen section.
+ @param height the output height of the screen section.
The images will be scaled if the output width of the screen section differs from the image section.<br>
The value -1 determines that the image should not be scaled.<br>
The default value is -1.
@return returns false if the rendering failed.
*/
-
Common::Rect blit(Graphics::Surface &target, int posX = 0, int posY = 0,
int flipping = FLIP_NONE,
Common::Rect *pPartRect = nullptr,
uint color = BS_ARGB(255, 255, 255, 255),
- int width = -1, int height = -1);
+ int width = -1, int height = -1,
+ TSpriteBlendMode blend = BLEND_NORMAL);
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)
+
+ /**
+ * @brief Scale function; this returns a transformed version of this surface after rotation and
+ * scaling. Please do not use this if angle != 0, use rotoscale.
+ *
+ * @param newWidth the resulting width.
+ * @param newHeight the resulting height.
+ * @see TransformStruct
+ */
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
- TransparentSurface *scale(const Common::Rect &srcRect, const Common::Rect &dstRect) const;
- static byte *_lookup;
- static void destroyLookup();
+
+ /**
+ * @brief Rotoscale function; this returns a transformed version of this surface after rotation and
+ * scaling. Please do not use this if angle == 0, use plain old scaling function.
+ *
+ * @param transform a TransformStruct wrapping the required info. @see TransformStruct
+ *
+ */
+ TransparentSurface *rotoscale(const TransformStruct &transform) const;
+ AlphaType getAlphaMode() const;
+ void setAlphaMode(AlphaType);
private:
- static void doBlitAlpha(byte *ino, byte* outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
- static void generateLookup();
+ AlphaType _alphaMode;
+
};
/**
@@ -124,8 +169,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 31af77538a..903cea6d39 100644
--- a/engines/wintermute/math/math_util.cpp
+++ b/engines/wintermute/math/math_util.cpp
@@ -27,7 +27,7 @@
*/
#include "engines/wintermute/math/math_util.h"
-#include <math.h>
+#include "common/scummsys.h"
namespace Wintermute {
@@ -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 ca1eae8813..011766f510 100644
--- a/engines/wintermute/math/matrix4.cpp
+++ b/engines/wintermute/math/matrix4.cpp
@@ -28,7 +28,7 @@
#include "engines/wintermute/math/matrix4.h"
#include "engines/wintermute/math/vector2.h"
-#include <math.h>
+#include "common/scummsys.h"
namespace Wintermute {
@@ -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..a4a64690e2 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());
}
@@ -67,12 +94,24 @@ struct Rect32 {
left = right = top = bottom = 0;
}
+ bool isRectEmpty() const {
+ return (left >= right) || (top >= bottom);
+ }
+
void offsetRect(int dx, int dy) {
left += dx;
top += dy;
right += dx;
bottom += dy;
}
+
+ void setRect(int32 newLeft, int32 newTop, int32 newRight, int32 newBottom) {
+ this->left = newLeft;
+ this->top = newTop;
+ this->right = newRight;
+ this->bottom = newBottom;
+ }
+
/**
* Check if the given rect is equal to this one.
*
@@ -89,6 +128,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 74c5586d62..618ee9bda9 100644
--- a/engines/wintermute/math/vector2.cpp
+++ b/engines/wintermute/math/vector2.cpp
@@ -27,7 +27,7 @@
*/
#include "engines/wintermute/math/vector2.h"
-#include <math.h>
+#include "common/scummsys.h"
namespace Wintermute {
@@ -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..9fa23c6074 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?
@@ -166,52 +169,16 @@ bool BasePlatform::setCursorPos(int x, int y) {
}
//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::showWindow(int nCmdShow) {
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void BasePlatform::setCapture() {
- return;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::releaseCapture() {
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::setRectEmpty(Rect32 *lprc) {
- lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::isRectEmpty(const Rect32 *lprc) {
- return (lprc->left >= lprc->right) || (lprc->top >= lprc->bottom);
-}
-
-//////////////////////////////////////////////////////////////////////////
bool BasePlatform::ptInRect(Rect32 *lprc, Point32 p) {
return (p.x >= lprc->left) && (p.x < lprc->right) && (p.y >= lprc->top) && (p.y < lprc->bottom);
}
//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::setRect(Rect32 *lprc, int left, int top, int right, int bottom) {
- lprc->left = left;
- lprc->top = top;
- lprc->right = right;
- lprc->bottom = bottom;
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////
bool BasePlatform::intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const Rect32 *lprcSrc2) {
- if (isRectEmpty(lprcSrc1) || isRectEmpty(lprcSrc2) ||
+ if (lprcSrc1->isRectEmpty() || lprcSrc2->isRectEmpty() ||
lprcSrc1->left >= lprcSrc2->right || lprcSrc2->left >= lprcSrc1->right ||
lprcSrc1->top >= lprcSrc2->bottom || lprcSrc2->top >= lprcSrc1->bottom) {
- setRectEmpty(lprcDst);
+ lprcDst->setEmpty();
return false;
}
lprcDst->left = MAX(lprcSrc1->left, lprcSrc2->left);
@@ -224,15 +191,15 @@ bool BasePlatform::intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const
//////////////////////////////////////////////////////////////////////////
bool BasePlatform::unionRect(Rect32 *lprcDst, Rect32 *lprcSrc1, Rect32 *lprcSrc2) {
- if (isRectEmpty(lprcSrc1)) {
- if (isRectEmpty(lprcSrc2)) {
- setRectEmpty(lprcDst);
+ if (lprcSrc1->isRectEmpty()) {
+ if (lprcSrc2->isRectEmpty()) {
+ lprcDst->setEmpty();
return false;
} else {
*lprcDst = *lprcSrc2;
}
} else {
- if (isRectEmpty(lprcSrc2)) {
+ if (lprcSrc2->isRectEmpty()) {
*lprcDst = *lprcSrc1;
} else {
lprcDst->left = MIN(lprcSrc1->left, lprcSrc2->left);
@@ -272,4 +239,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..16d55745b9 100644
--- a/engines/wintermute/platform_osystem.h
+++ b/engines/wintermute/platform_osystem.h
@@ -48,13 +48,7 @@ public:
// Win32 API bindings
static bool getCursorPos(Point32 *lpPoint);
static bool setCursorPos(int x, int y);
- static bool showWindow(int nCmdShow);
- static void setCapture();
- static bool releaseCapture();
-
- static bool setRectEmpty(Rect32 *lprc);
- static bool isRectEmpty(const Rect32 *lprc);
static bool ptInRect(Rect32 *lprc, Point32 p);
static bool setRect(Rect32 *lprc, int left, int top, int right, int bottom);
static bool intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const Rect32 *lprcSrc2);
@@ -70,6 +64,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..7526174b64 100644
--- a/engines/wintermute/ui/ui_button.cpp
+++ b/engines/wintermute/ui/ui_button.cpp
@@ -103,7 +103,7 @@ UIButton::~UIButton() {
//////////////////////////////////////////////////////////////////////////
bool UIButton::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIButton::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -162,7 +162,7 @@ TOKEN_DEF(PIXEL_PERFECT)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIButton::loadBuffer(byte *buffer, bool complete) {
+bool UIButton::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(BUTTON)
TOKEN_TABLE(TEMPLATE)
@@ -202,38 +202,38 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_BUTTON) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_BUTTON) {
_gameRef->LOG(0, "'BUTTON' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -243,7 +243,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_HOVER:
delete _backHover;
_backHover = new UITiledImage(_gameRef);
- if (!_backHover || DID_FAIL(_backHover->loadFile((char *)params))) {
+ if (!_backHover || DID_FAIL(_backHover->loadFile(params))) {
delete _backHover;
_backHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -253,7 +253,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_PRESS:
delete _backPress;
_backPress = new UITiledImage(_gameRef);
- if (!_backPress || DID_FAIL(_backPress->loadFile((char *)params))) {
+ if (!_backPress || DID_FAIL(_backPress->loadFile(params))) {
delete _backPress;
_backPress = nullptr;
cmd = PARSERR_GENERIC;
@@ -263,7 +263,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_DISABLE:
delete _backDisable;
_backDisable = new UITiledImage(_gameRef);
- if (!_backDisable || DID_FAIL(_backDisable->loadFile((char *)params))) {
+ if (!_backDisable || DID_FAIL(_backDisable->loadFile(params))) {
delete _backDisable;
_backDisable = nullptr;
cmd = PARSERR_GENERIC;
@@ -273,7 +273,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_FOCUS:
delete _backFocus;
_backFocus = new UITiledImage(_gameRef);
- if (!_backFocus || DID_FAIL(_backFocus->loadFile((char *)params))) {
+ if (!_backFocus || DID_FAIL(_backFocus->loadFile(params))) {
delete _backFocus;
_backFocus = nullptr;
cmd = PARSERR_GENERIC;
@@ -283,7 +283,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -293,7 +293,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_HOVER:
delete _imageHover;
_imageHover = new BaseSprite(_gameRef);
- if (!_imageHover || DID_FAIL(_imageHover->loadFile((char *)params))) {
+ if (!_imageHover || DID_FAIL(_imageHover->loadFile(params))) {
delete _imageHover;
_imageHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -303,7 +303,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_PRESS:
delete _imagePress;
_imagePress = new BaseSprite(_gameRef);
- if (!_imagePress || DID_FAIL(_imagePress->loadFile((char *)params))) {
+ if (!_imagePress || DID_FAIL(_imagePress->loadFile(params))) {
delete _imagePress;
_imagePress = nullptr;
cmd = PARSERR_GENERIC;
@@ -313,7 +313,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_DISABLE:
delete _imageDisable;
_imageDisable = new BaseSprite(_gameRef);
- if (!_imageDisable || DID_FAIL(_imageDisable->loadFile((char *)params))) {
+ if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(params))) {
delete _imageDisable;
_imageDisable = nullptr;
cmd = PARSERR_GENERIC;
@@ -323,7 +323,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_FOCUS:
delete _imageFocus;
_imageFocus = new BaseSprite(_gameRef);
- if (!_imageFocus || DID_FAIL(_imageFocus->loadFile((char *)params))) {
+ if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(params))) {
delete _imageFocus;
_imageFocus = nullptr;
cmd = PARSERR_GENERIC;
@@ -334,7 +334,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -344,7 +344,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontHover) {
_gameRef->_fontStorage->removeFont(_fontHover);
}
- _fontHover = _gameRef->_fontStorage->addFont((char *)params);
+ _fontHover = _gameRef->_fontStorage->addFont(params);
if (!_fontHover) {
cmd = PARSERR_GENERIC;
}
@@ -354,7 +354,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontPress) {
_gameRef->_fontStorage->removeFont(_fontPress);
}
- _fontPress = _gameRef->_fontStorage->addFont((char *)params);
+ _fontPress = _gameRef->_fontStorage->addFont(params);
if (!_fontPress) {
cmd = PARSERR_GENERIC;
}
@@ -364,7 +364,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontDisable) {
_gameRef->_fontStorage->removeFont(_fontDisable);
}
- _fontDisable = _gameRef->_fontStorage->addFont((char *)params);
+ _fontDisable = _gameRef->_fontStorage->addFont(params);
if (!_fontDisable) {
cmd = PARSERR_GENERIC;
}
@@ -374,21 +374,21 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontFocus) {
_gameRef->_fontStorage->removeFont(_fontFocus);
}
- _fontFocus = _gameRef->_fontStorage->addFont((char *)params);
+ _fontFocus = _gameRef->_fontStorage->addFont(params);
if (!_fontFocus) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_align = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_align = TAL_RIGHT;
} else {
_align = TAL_CENTER;
@@ -396,25 +396,25 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -422,35 +422,35 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_FOCUSABLE:
- parser.scanStr((char *)params, "%b", &_canFocus);
+ parser.scanStr(params, "%b", &_canFocus);
break;
case TOKEN_CENTER_IMAGE:
- parser.scanStr((char *)params, "%b", &_centerImage);
+ parser.scanStr(params, "%b", &_centerImage);
break;
case TOKEN_PRESSED:
- parser.scanStr((char *)params, "%b", &_stayPressed);
+ parser.scanStr(params, "%b", &_stayPressed);
break;
case TOKEN_PIXEL_PERFECT:
- parser.scanStr((char *)params, "%b", &_pixelPerfect);
+ parser.scanStr(params, "%b", &_pixelPerfect);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -655,12 +655,12 @@ bool UIButton::display(int offsetX, int offsetY) {
BaseFont *font = 0;
//RECT rect;
- //BasePlatform::setRect(&rect, OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height);
+ //rect.setRect(OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height);
//_hover = (!_disable && BasePlatform::ptInRect(&rect, _gameRef->_mousePos)!=FALSE);
_hover = (!_disable && _gameRef->_activeObject == this && (_gameRef->_interactive || _gameRef->_state == GAME_SEMI_FROZEN));
if ((_press && _hover && !_gameRef->_mouseLeftDown) ||
- (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) {
+ (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) {
press();
}
@@ -1178,25 +1178,25 @@ bool UIButton::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
persistMgr->transferPtr(TMEMBER_PTR(_backDisable));
persistMgr->transferPtr(TMEMBER_PTR(_backFocus));
persistMgr->transferPtr(TMEMBER_PTR(_backHover));
persistMgr->transferPtr(TMEMBER_PTR(_backPress));
- persistMgr->transfer(TMEMBER(_centerImage));
+ persistMgr->transferBool(TMEMBER(_centerImage));
persistMgr->transferPtr(TMEMBER_PTR(_fontDisable));
persistMgr->transferPtr(TMEMBER_PTR(_fontFocus));
persistMgr->transferPtr(TMEMBER_PTR(_fontHover));
persistMgr->transferPtr(TMEMBER_PTR(_fontPress));
- persistMgr->transfer(TMEMBER(_hover));
+ persistMgr->transferBool(TMEMBER(_hover));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferPtr(TMEMBER_PTR(_imageDisable));
persistMgr->transferPtr(TMEMBER_PTR(_imageFocus));
persistMgr->transferPtr(TMEMBER_PTR(_imageHover));
persistMgr->transferPtr(TMEMBER_PTR(_imagePress));
- persistMgr->transfer(TMEMBER(_pixelPerfect));
- persistMgr->transfer(TMEMBER(_press));
- persistMgr->transfer(TMEMBER(_stayPressed));
+ persistMgr->transferBool(TMEMBER(_pixelPerfect));
+ persistMgr->transferBool(TMEMBER(_press));
+ persistMgr->transferBool(TMEMBER(_stayPressed));
if (!persistMgr->getIsSaving()) {
_oneTimePress = false;
@@ -1206,4 +1206,28 @@ bool UIButton::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
-} // end of namespace Wintermute
+void UIButton::setFontHover(BaseFont *font) {
+ _fontHover = font;
+}
+
+BaseFont *UIButton::getFontHover() {
+ return _fontHover;
+}
+
+void UIButton::setFontPress(BaseFont *font) {
+ _fontPress = font;
+}
+
+void UIButton::setImageHover(BaseSprite *sprite) {
+ _imageHover = sprite;
+}
+
+void UIButton::setImagePress(BaseSprite *sprite) {
+ _imagePress = sprite;
+}
+
+void UIButton::setTextAlign(TTextAlign align) {
+ _align = align;
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_button.h b/engines/wintermute/ui/ui_button.h
index 5db9356ef9..6452cfc4f7 100644
--- a/engines/wintermute/ui/ui_button.h
+++ b/engines/wintermute/ui/ui_button.h
@@ -37,35 +37,18 @@ namespace Wintermute {
class UIButton : public UIObject {
public:
- bool _pixelPerfect;
- bool _stayPressed;
- bool _centerImage;
- bool _oneTimePress;
- uint32 _oneTimePressTime;
+
DECLARE_PERSISTENT(UIButton, UIObject)
void press();
virtual bool display() { return display(0, 0); }
virtual bool display(int offsetX, int offsetY);
- bool _press;
- bool _hover;
+
void correctSize();
- TTextAlign _align;
- BaseSprite *_imageHover;
- BaseSprite *_imagePress;
- BaseSprite *_imageDisable;
- BaseSprite *_imageFocus;
- BaseFont *_fontDisable;
- BaseFont *_fontPress;
- BaseFont *_fontHover;
- BaseFont *_fontFocus;
- UITiledImage *_backPress;
- UITiledImage *_backHover;
- UITiledImage *_backDisable;
- UITiledImage *_backFocus;
+
UIButton(BaseGame *inGame = nullptr);
virtual ~UIButton();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
@@ -73,8 +56,41 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+
+
+ void setFontHover(BaseFont *font);
+ BaseFont *getFontHover();
+ void setFontPress(BaseFont *font);
+
+ void setTextAlign(TTextAlign align);
+
+ void setImageHover(BaseSprite *sprite);
+ void setImagePress(BaseSprite *sprite);
+
+private:
+ bool _pixelPerfect;
+ bool _stayPressed;
+ bool _centerImage;
+ bool _oneTimePress;
+ UITiledImage *_backPress;
+ UITiledImage *_backHover;
+ UITiledImage *_backDisable;
+ UITiledImage *_backFocus;
+ bool _press;
+ bool _hover;
+ BaseFont *_fontDisable;
+ BaseFont *_fontPress;
+ BaseFont *_fontHover;
+ BaseFont *_fontFocus;
+ BaseSprite *_imageHover;
+ BaseSprite *_imagePress;
+ BaseSprite *_imageDisable;
+ BaseSprite *_imageFocus;
+ uint32 _oneTimePressTime;
+ TTextAlign _align;
+
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_edit.cpp b/engines/wintermute/ui/ui_edit.cpp
index 91ca7326cb..1f224c79c8 100644
--- a/engines/wintermute/ui/ui_edit.cpp
+++ b/engines/wintermute/ui/ui_edit.cpp
@@ -94,7 +94,7 @@ UIEdit::~UIEdit() {
//////////////////////////////////////////////////////////////////////////
bool UIEdit::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIEdit::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -139,7 +139,7 @@ TOKEN_DEF(EDIT)
TOKEN_DEF(CAPTION)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIEdit::loadBuffer(byte *buffer, bool complete) {
+bool UIEdit::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(DISABLED)
@@ -165,34 +165,34 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(CAPTION)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_EDIT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDIT) {
_gameRef->LOG(0, "'EDIT' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -202,7 +202,7 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -213,7 +213,7 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -223,45 +223,45 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
if (_fontSelected) {
_gameRef->_fontStorage->removeFont(_fontSelected);
}
- _fontSelected = _gameRef->_fontStorage->addFont((char *)params);
+ _fontSelected = _gameRef->_fontStorage->addFont(params);
if (!_fontSelected) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_MAX_LENGTH:
- parser.scanStr((char *)params, "%d", &_maxLength);
+ parser.scanStr(params, "%d", &_maxLength);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -269,27 +269,27 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CURSOR_BLINK_RATE:
- parser.scanStr((char *)params, "%d", &_cursorBlinkRate);
+ parser.scanStr(params, "%d", &_cursorBlinkRate);
break;
case TOKEN_FRAME_WIDTH:
- parser.scanStr((char *)params, "%d", &_frameWidth);
+ parser.scanStr(params, "%d", &_frameWidth);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -627,9 +627,9 @@ bool UIEdit::display(int offsetX, int offsetY) {
curFirst = true;
} else {
while (font->getTextWidth((byte *)_text + _scrollOffset, MAX<int32>(0, _selStart - _scrollOffset)) +
- sfont->getTextWidth((byte *)(_text + MAX<int32>(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart))
+ sfont->getTextWidth((byte *)(_text + MAX<int32>(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart))
- > _width - cursorWidth - 2 * _frameWidth) {
+ > _width - cursorWidth - 2 * _frameWidth) {
_scrollOffset++;
if (_scrollOffset >= (int)strlen(_text)) {
break;
@@ -932,14 +932,14 @@ bool UIEdit::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_cursorBlinkRate));
- persistMgr->transfer(TMEMBER(_cursorChar));
+ persistMgr->transferUint32(TMEMBER(_cursorBlinkRate));
+ persistMgr->transferCharPtr(TMEMBER(_cursorChar));
persistMgr->transferPtr(TMEMBER_PTR(_fontSelected));
- persistMgr->transfer(TMEMBER(_frameWidth));
- persistMgr->transfer(TMEMBER(_maxLength));
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_selEnd));
- persistMgr->transfer(TMEMBER(_selStart));
+ persistMgr->transferSint32(TMEMBER(_frameWidth));
+ persistMgr->transferSint32(TMEMBER(_maxLength));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_selEnd));
+ persistMgr->transferSint32(TMEMBER(_selStart));
if (!persistMgr->getIsSaving()) {
_cursorVisible = false;
@@ -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..19ea5ecc5d 100644
--- a/engines/wintermute/ui/ui_edit.h
+++ b/engines/wintermute/ui/ui_edit.h
@@ -38,26 +38,20 @@ class BaseFont;
class UIEdit : public UIObject {
public:
DECLARE_PERSISTENT(UIEdit, UIObject)
- int32 _maxLength;
+
int insertChars(int pos, const byte *chars, int num);
int deleteChars(int start, int end);
- bool _cursorVisible;
- uint32 _lastBlinkTime;
+
virtual bool display(int offsetX, int offsetY);
virtual bool handleKeypress(Common::Event *event, bool printable = false);
- int32 _scrollOffset;
- int32 _frameWidth;
- uint32 _cursorBlinkRate;
+
void setCursorChar(const char *character);
- char *_cursorChar;
- int32 _selEnd;
- int32 _selStart;
- BaseFont *_fontSelected;
+
UIEdit(BaseGame *inGame);
virtual ~UIEdit();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
// scripting interface
@@ -65,8 +59,19 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+private:
+ uint32 _cursorBlinkRate;
+ uint32 _lastBlinkTime;
+ int32 _selEnd;
+ int32 _selStart;
+ int32 _scrollOffset;
+ int32 _frameWidth;
+ BaseFont *_fontSelected;
+ int32 _maxLength;
+ bool _cursorVisible;
+ char *_cursorChar;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_entity.cpp b/engines/wintermute/ui/ui_entity.cpp
index 1872400cdd..0dbf8df00b 100644
--- a/engines/wintermute/ui/ui_entity.cpp
+++ b/engines/wintermute/ui/ui_entity.cpp
@@ -58,7 +58,7 @@ UIEntity::~UIEntity() {
//////////////////////////////////////////////////////////////////////////
bool UIEntity::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIEntity::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -92,7 +92,7 @@ TOKEN_DEF(SCRIPT)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIEntity::loadBuffer(byte *buffer, bool complete) {
+bool UIEntity::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ENTITY_CONTAINER)
TOKEN_TABLE(TEMPLATE)
@@ -106,54 +106,54 @@ bool UIEntity::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY_CONTAINER) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ENTITY_CONTAINER) {
_gameRef->LOG(0, "'ENTITY_CONTAINER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_ENTITY:
- if (DID_FAIL(setEntity((char *)params))) {
+ if (DID_FAIL(setEntity(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -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..63f0026412 100644
--- a/engines/wintermute/ui/ui_entity.h
+++ b/engines/wintermute/ui/ui_entity.h
@@ -39,12 +39,11 @@ public:
UIEntity(BaseGame *inGame);
virtual ~UIEntity();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete);
+ bool loadBuffer(char *buffer, bool complete);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
virtual bool display() override { return display(0, 0); }
virtual bool display(int offsetX, int offsetY) override;
- AdEntity *_entity;
bool setEntity(const char *filename);
// scripting interface
@@ -52,8 +51,11 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
virtual const char *scToString();
+
+private:
+ AdEntity *_entity;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_object.cpp b/engines/wintermute/ui/ui_object.cpp
index 07efc5e4cb..c04c7cbd28 100644
--- a/engines/wintermute/ui/ui_object.cpp
+++ b/engines/wintermute/ui/ui_object.cpp
@@ -622,23 +622,23 @@ bool UIObject::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_back));
- persistMgr->transfer(TMEMBER(_canFocus));
- persistMgr->transfer(TMEMBER(_disable));
+ persistMgr->transferBool(TMEMBER(_canFocus));
+ persistMgr->transferBool(TMEMBER(_disable));
persistMgr->transferPtr(TMEMBER_PTR(_focusedWidget));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transferSint32(TMEMBER(_height));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferPtr(TMEMBER_PTR(_listenerObject));
persistMgr->transferPtr(TMEMBER_PTR(_listenerParamObject));
- persistMgr->transfer(TMEMBER(_listenerParamDWORD));
+ persistMgr->transferUint32(TMEMBER(_listenerParamDWORD));
persistMgr->transferPtr(TMEMBER_PTR(_parent));
- persistMgr->transfer(TMEMBER(_parentNotify));
- persistMgr->transfer(TMEMBER(_sharedFonts));
- persistMgr->transfer(TMEMBER(_sharedImages));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_visible));
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferBool(TMEMBER(_parentNotify));
+ persistMgr->transferBool(TMEMBER(_sharedFonts));
+ persistMgr->transferBool(TMEMBER(_sharedImages));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
+ persistMgr->transferBool(TMEMBER(_visible));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
@@ -648,4 +648,82 @@ bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
return STATUS_FAILED;
}
-} // end of namespace Wintermute
+int32 UIObject::getWidth() const {
+ return _width;
+}
+
+// Has to be non-const to allow the virtual override to work,
+// as other getHeight()-functions currently have the potential
+// of having side-effects.
+int32 UIObject::getHeight() {
+ return _height;
+}
+
+void UIObject::setWidth(int32 width) {
+ assert(width >= 0);
+ _width = width;
+}
+
+void UIObject::setHeight(int32 height) {
+ assert(height >= 0);
+ _height = height;
+}
+
+bool UIObject::isDisabled() const {
+ return _disable;
+}
+
+bool UIObject::isVisible() const {
+ return _visible;
+}
+
+void UIObject::setVisible(bool visible) {
+ _visible = visible;
+}
+
+void UIObject::setDisabled(bool disable) {
+ _disable = disable;
+}
+
+bool UIObject::hasSharedFonts() const {
+ return _sharedFonts;
+}
+
+void UIObject::setSharedFonts(bool shared) {
+ _sharedFonts = shared;
+}
+
+bool UIObject::hasSharedImages() const {
+ return _sharedImages;
+}
+
+void UIObject::setSharedImages(bool shared) {
+ _sharedImages = shared;
+}
+
+BaseSprite *UIObject::getImage() const {
+ return _image;
+}
+
+void UIObject::setImage(BaseSprite *image) {
+ _image = image;
+}
+
+bool UIObject::canFocus() const {
+ return _canFocus;
+}
+
+void UIObject::setFont(BaseFont *font) {
+ _font = font;
+}
+
+BaseFont *UIObject::getFont() {
+ return _font;
+}
+
+BaseScriptHolder *UIObject::getListener() const {
+ return _listenerObject;
+}
+
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_object.h b/engines/wintermute/ui/ui_object.h
index 935c27613c..ecbaebcee6 100644
--- a/engines/wintermute/ui/ui_object.h
+++ b/engines/wintermute/ui/ui_object.h
@@ -41,35 +41,23 @@ class UIObject : public BaseObject {
public:
bool getTotalOffset(int *offsetX, int *offsetY);
- bool _canFocus;
bool focus();
virtual bool handleMouse(TMouseEvent event, TMouseButton button);
bool isFocused();
- bool _parentNotify;
+
DECLARE_PERSISTENT(UIObject, BaseObject)
UIObject *_parent;
virtual bool display() override { return display(0, 0); }
virtual bool display(int offsetX) { return display(offsetX, 0); }
virtual bool display(int offsetX, int offsetY);
virtual void correctSize();
- bool _sharedFonts;
- bool _sharedImages;
void setText(const char *text);
- char *_text;
- BaseFont *_font;
- bool _visible;
- UITiledImage *_back;
- bool _disable;
+
UIObject(BaseGame *inGame = nullptr);
virtual ~UIObject();
- int32 _width;
- int32 _height;
- TUIObjectType _type;
- BaseSprite *_image;
void setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam);
- BaseScriptHolder *_listenerParamObject;
- uint32 _listenerParamDWORD;
- BaseScriptHolder *_listenerObject;
+ BaseScriptHolder *getListener() const;
+
UIObject *_focusedWidget;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
@@ -78,8 +66,44 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+ TUIObjectType _type;
+
+ int32 getWidth() const;
+ int32 getHeight() override;
+ void setHeight(int32 height);
+ void setWidth(int32 width);
+ bool isDisabled() const;
+ void setDisabled(bool disable);
+ bool isVisible() const;
+ void setVisible(bool visible);
+ bool hasSharedFonts() const;
+ void setSharedFonts(bool shared);
+ bool hasSharedImages() const;
+ void setSharedImages(bool shared);
+ BaseSprite *getImage() const;
+ void setImage(BaseSprite *image);
+ void setFont(BaseFont *font);
+ BaseFont *getFont();
+ bool canFocus() const;
+
+protected:
+ BaseScriptHolder *_listenerParamObject;
+ uint32 _listenerParamDWORD;
+ BaseScriptHolder *_listenerObject;
+ BaseSprite *_image;
+ BaseFont *_font;
+ bool _sharedFonts;
+ bool _sharedImages;
+ char *_text;
+ bool _visible;
+ bool _disable;
+ int32 _width;
+ int32 _height;
+ bool _canFocus;
+ bool _parentNotify;
+ UITiledImage *_back;
};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
#endif
diff --git a/engines/wintermute/ui/ui_text.cpp b/engines/wintermute/ui/ui_text.cpp
index 98d70b770e..b255e6e790 100644
--- a/engines/wintermute/ui/ui_text.cpp
+++ b/engines/wintermute/ui/ui_text.cpp
@@ -103,7 +103,7 @@ bool UIText::display(int offsetX, int offsetY) {
//////////////////////////////////////////////////////////////////////////
bool UIText::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIText::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -146,7 +146,7 @@ TOKEN_DEF(PARENT_NOTIFY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIText::loadBuffer(byte *buffer, bool complete) {
+bool UIText::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(STATIC)
TOKEN_TABLE(TEMPLATE)
@@ -170,38 +170,38 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_STATIC) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_STATIC) {
_gameRef->LOG(0, "'STATIC' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -211,7 +211,7 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -222,21 +222,21 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_textAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_textAlign = TAL_RIGHT;
} else {
_textAlign = TAL_CENTER;
@@ -244,9 +244,9 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_VERTICAL_ALIGN:
- if (scumm_stricmp((char *)params, "top") == 0) {
+ if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
- } else if (scumm_stricmp((char *)params, "bottom") == 0) {
+ } else if (scumm_stricmp(params, "bottom") == 0) {
_verticalAlign = VAL_BOTTOM;
} else {
_verticalAlign = VAL_CENTER;
@@ -254,25 +254,25 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -280,19 +280,19 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -503,8 +503,8 @@ const char *UIText::scToString() {
bool UIText::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_textAlign));
- persistMgr->transfer(TMEMBER_INT(_verticalAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_textAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
return STATUS_OK;
}
@@ -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..c39260b228 100644
--- a/engines/wintermute/ui/ui_text.h
+++ b/engines/wintermute/ui/ui_text.h
@@ -37,15 +37,15 @@ namespace Wintermute {
class UIText : public UIObject {
private:
bool sizeToFit();
+ TTextAlign _textAlign;
+ TVerticalAlign _verticalAlign;
public:
virtual bool display(int offsetX, int offsetY);
DECLARE_PERSISTENT(UIText, UIObject)
UIText(BaseGame *inGame = nullptr);
virtual ~UIText();
- TTextAlign _textAlign;
- TVerticalAlign _verticalAlign;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
@@ -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..e895477a36 100644
--- a/engines/wintermute/ui/ui_tiled_image.cpp
+++ b/engines/wintermute/ui/ui_tiled_image.cpp
@@ -44,15 +44,15 @@ IMPLEMENT_PERSISTENT(UITiledImage, false)
UITiledImage::UITiledImage(BaseGame *inGame) : BaseObject(inGame) {
_image = nullptr;
- BasePlatform::setRectEmpty(&_upLeft);
- BasePlatform::setRectEmpty(&_upMiddle);
- BasePlatform::setRectEmpty(&_upRight);
- BasePlatform::setRectEmpty(&_middleLeft);
- BasePlatform::setRectEmpty(&_middleMiddle);
- BasePlatform::setRectEmpty(&_middleRight);
- BasePlatform::setRectEmpty(&_downLeft);
- BasePlatform::setRectEmpty(&_downMiddle);
- BasePlatform::setRectEmpty(&_downRight);
+ _upLeft.setEmpty();
+ _upMiddle.setEmpty();
+ _upRight.setEmpty();
+ _middleLeft.setEmpty();
+ _middleMiddle.setEmpty();
+ _middleRight.setEmpty();
+ _downLeft.setEmpty();
+ _downMiddle.setEmpty();
+ _downRight.setEmpty();
}
@@ -75,8 +75,6 @@ bool UITiledImage::display(int x, int y, int width, int height) {
int nuColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth;
int nuRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight;
- int col, row;
-
_gameRef->_renderer->startSpriteBatch();
// top left/right
@@ -88,27 +86,24 @@ bool UITiledImage::display(int x, int y, int width, int height) {
_image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downRight);
// left/right
- int yyy = y + (_upMiddle.bottom - _upMiddle.top);
- for (row = 0; row < nuRows; row++) {
- _image->_surface->displayTrans(x, yyy, _middleLeft);
- _image->_surface->displayTrans(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight);
- yyy += tileWidth;
+ if (nuRows > 0) {
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ _image->_surface->displayTiled(x, yyy, _middleLeft, 1, nuRows);
+ _image->_surface->displayTiled(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight, 1, nuRows);
}
// top/bottom
- int xxx = x + (_upLeft.right - _upLeft.left);
- for (col = 0; col < nuColumns; col++) {
- _image->_surface->displayTrans(xxx, y, _upMiddle);
- _image->_surface->displayTrans(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle);
- xxx += tileWidth;
+ if (nuColumns > 0) {
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, y, _upMiddle, nuColumns, 1);
+ _image->_surface->displayTiled(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle, nuColumns, 1);
}
// tiles
if (nuRows > 0 && nuColumns > 0) {
- yyy = y + (_upMiddle.bottom - _upMiddle.top);
- xxx = x + (_upLeft.right - _upLeft.left);
- _image->_surface->displayTrans(xxx, yyy, _middleMiddle);
- _image->_surface->repeatLastDisplayOp(tileWidth, tileWidth, nuColumns, nuRows);
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, yyy, _middleMiddle, nuColumns, nuRows);
}
_gameRef->_renderer->endSpriteBatch();
@@ -119,7 +114,7 @@ bool UITiledImage::display(int x, int y, int width, int height) {
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UITiledImage::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -158,7 +153,7 @@ TOKEN_DEF(HORIZONTAL_TILES)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
+bool UITiledImage::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TILED_IMAGE)
TOKEN_TABLE(TEMPLATE)
@@ -177,7 +172,7 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
bool hTiles = false, vTiles = false;
@@ -185,17 +180,17 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
int v1 = 0, v2 = 0, v3 = 0;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TILED_IMAGE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TILED_IMAGE) {
_gameRef->LOG(0, "'TILED_IMAGE' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -203,7 +198,7 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSubFrame(_gameRef);
- if (!_image || DID_FAIL(_image->setSurface((char *)params))) {
+ if (!_image || DID_FAIL(_image->setSurface(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -211,48 +206,48 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_UP_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom);
break;
case TOKEN_UP_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom);
break;
case TOKEN_UP_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom);
break;
case TOKEN_DOWN_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom);
break;
case TOKEN_DOWN_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom);
break;
case TOKEN_DOWN_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom);
break;
case TOKEN_MIDDLE_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom);
break;
case TOKEN_MIDDLE_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom);
break;
case TOKEN_MIDDLE_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom);
break;
case TOKEN_HORIZONTAL_TILES:
- parser.scanStr((char *)params, "%d,%d,%d", &h1, &h2, &h3);
+ parser.scanStr(params, "%d,%d,%d", &h1, &h2, &h3);
hTiles = true;
break;
case TOKEN_VERTICAL_TILES:
- parser.scanStr((char *)params, "%d,%d,%d", &v1, &v2, &v3);
+ parser.scanStr(params, "%d,%d,%d", &v1, &v2, &v3);
vTiles = true;
break;
@@ -272,19 +267,19 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
if (vTiles && hTiles) {
// up row
- BasePlatform::setRect(&_upLeft, 0, 0, h1, v1);
- BasePlatform::setRect(&_upMiddle, h1, 0, h1 + h2, v1);
- BasePlatform::setRect(&_upRight, h1 + h2, 0, h1 + h2 + h3, v1);
+ _upLeft.setRect(0, 0, h1, v1);
+ _upMiddle.setRect(h1, 0, h1 + h2, v1);
+ _upRight.setRect(h1 + h2, 0, h1 + h2 + h3, v1);
// middle row
- BasePlatform::setRect(&_middleLeft, 0, v1, h1, v1 + v2);
- BasePlatform::setRect(&_middleMiddle, h1, v1, h1 + h2, v1 + v2);
- BasePlatform::setRect(&_middleRight, h1 + h2, v1, h1 + h2 + h3, v1 + v2);
+ _middleLeft.setRect(0, v1, h1, v1 + v2);
+ _middleMiddle.setRect(h1, v1, h1 + h2, v1 + v2);
+ _middleRight.setRect(h1 + h2, v1, h1 + h2 + h3, v1 + v2);
// down row
- BasePlatform::setRect(&_downLeft, 0, v1 + v2, h1, v1 + v2 + v3);
- BasePlatform::setRect(&_downMiddle, h1, v1 + v2, h1 + h2, v1 + v2 + v3);
- BasePlatform::setRect(&_downRight, h1 + h2, v1 + v2, h1 + h2 + h3, v1 + v2 + v3);
+ _downLeft.setRect(0, v1 + v2, h1, v1 + v2 + v3);
+ _downMiddle.setRect(h1, v1 + v2, h1 + h2, v1 + v2 + v3);
+ _downRight.setRect(h1 + h2, v1 + v2, h1 + h2 + h3, v1 + v2 + v3);
}
// default
@@ -292,34 +287,34 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
int width = _image->_surface->getWidth() / 3;
int height = _image->_surface->getHeight() / 3;
- if (BasePlatform::isRectEmpty(&_upLeft)) {
- BasePlatform::setRect(&_upLeft, 0, 0, width, height);
+ if (_upLeft.isRectEmpty()) {
+ _upLeft.setRect(0, 0, width, height);
}
- if (BasePlatform::isRectEmpty(&_upMiddle)) {
- BasePlatform::setRect(&_upMiddle, width, 0, 2 * width, height);
+ if (_upMiddle.isRectEmpty()) {
+ _upMiddle.setRect(width, 0, 2 * width, height);
}
- if (BasePlatform::isRectEmpty(&_upRight)) {
- BasePlatform::setRect(&_upRight, 2 * width, 0, 3 * width, height);
+ if (_upRight.isRectEmpty()) {
+ _upRight.setRect(2 * width, 0, 3 * width, height);
}
- if (BasePlatform::isRectEmpty(&_middleLeft)) {
- BasePlatform::setRect(&_middleLeft, 0, height, width, 2 * height);
+ if (_middleLeft.isRectEmpty()) {
+ _middleLeft.setRect(0, height, width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_middleMiddle)) {
- BasePlatform::setRect(&_middleMiddle, width, height, 2 * width, 2 * height);
+ if (_middleMiddle.isRectEmpty()) {
+ _middleMiddle.setRect(width, height, 2 * width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_middleRight)) {
- BasePlatform::setRect(&_middleRight, 2 * width, height, 3 * width, 2 * height);
+ if (_middleRight.isRectEmpty()) {
+ _middleRight.setRect(2 * width, height, 3 * width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_downLeft)) {
- BasePlatform::setRect(&_downLeft, 0, 2 * height, width, 3 * height);
+ if (_downLeft.isRectEmpty()) {
+ _downLeft.setRect(0, 2 * height, width, 3 * height);
}
- if (BasePlatform::isRectEmpty(&_downMiddle)) {
- BasePlatform::setRect(&_downMiddle, width, 2 * height, 2 * width, 3 * height);
+ if (_downMiddle.isRectEmpty()) {
+ _downMiddle.setRect(width, 2 * height, 2 * width, 3 * height);
}
- if (BasePlatform::isRectEmpty(&_downRight)) {
- BasePlatform::setRect(&_downRight, 2 * width, 2 * height, 3 * width, 3 * height);
+ if (_downRight.isRectEmpty()) {
+ _downRight.setRect(2 * width, 2 * height, 3 * width, 3 * height);
}
}
@@ -374,18 +369,18 @@ void UITiledImage::correctSize(int32 *width, int32 *height) {
bool UITiledImage::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_downLeft));
- persistMgr->transfer(TMEMBER(_downMiddle));
- persistMgr->transfer(TMEMBER(_downRight));
+ persistMgr->transferRect32(TMEMBER(_downLeft));
+ persistMgr->transferRect32(TMEMBER(_downMiddle));
+ persistMgr->transferRect32(TMEMBER(_downRight));
persistMgr->transferPtr(TMEMBER_PTR(_image));
- persistMgr->transfer(TMEMBER(_middleLeft));
- persistMgr->transfer(TMEMBER(_middleMiddle));
- persistMgr->transfer(TMEMBER(_middleRight));
- persistMgr->transfer(TMEMBER(_upLeft));
- persistMgr->transfer(TMEMBER(_upMiddle));
- persistMgr->transfer(TMEMBER(_upRight));
+ persistMgr->transferRect32(TMEMBER(_middleLeft));
+ persistMgr->transferRect32(TMEMBER(_middleMiddle));
+ persistMgr->transferRect32(TMEMBER(_middleRight));
+ persistMgr->transferRect32(TMEMBER(_upLeft));
+ persistMgr->transferRect32(TMEMBER(_upMiddle));
+ persistMgr->transferRect32(TMEMBER(_upRight));
return STATUS_OK;
}
-} // 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..fa92c46781 100644
--- a/engines/wintermute/ui/ui_tiled_image.h
+++ b/engines/wintermute/ui/ui_tiled_image.h
@@ -36,11 +36,13 @@
namespace Wintermute {
class BaseSubFrame;
class UITiledImage : public BaseObject {
+ using Wintermute::BaseObject::display;
+
public:
DECLARE_PERSISTENT(UITiledImage, BaseObject)
void correctSize(int32 *width, int32 *height);
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool display(int x, int y, int width, int height);
@@ -59,6 +61,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..842bf700b5 100644
--- a/engines/wintermute/ui/ui_window.cpp
+++ b/engines/wintermute/ui/ui_window.cpp
@@ -54,8 +54,8 @@ IMPLEMENT_PERSISTENT(UIWindow, false)
//////////////////////////////////////////////////////////////////////////
UIWindow::UIWindow(BaseGame *inGame) : UIObject(inGame) {
- BasePlatform::setRectEmpty(&_titleRect);
- BasePlatform::setRectEmpty(&_dragRect);
+ _titleRect.setEmpty();
+ _dragRect.setEmpty();
_titleAlign = TAL_LEFT;
_transparent = false;
@@ -141,8 +141,8 @@ bool UIWindow::display(int offsetX, int offsetY) {
}
if (_shieldButton) {
_shieldButton->_posX = _shieldButton->_posY = 0;
- _shieldButton->_width = _gameRef->_renderer->getWidth();
- _shieldButton->_height = _gameRef->_renderer->getHeight();
+ _shieldButton->setWidth(_gameRef->_renderer->getWidth());
+ _shieldButton->setHeight(_gameRef->_renderer->getHeight());
_shieldButton->display();
}
@@ -170,7 +170,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
_dragFrom.y = _gameRef->_mousePos.y;
}
- if (!_focusedWidget || (!_focusedWidget->_canFocus || _focusedWidget->_disable || !_focusedWidget->_visible)) {
+ if (!_focusedWidget || (!_focusedWidget->canFocus() || _focusedWidget->isDisabled() || !_focusedWidget->isVisible())) {
moveFocus();
}
@@ -213,7 +213,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
image->draw(_posX + offsetX, _posY + offsetY, _transparent ? nullptr : this);
}
- if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) {
+ if (!_titleRect.isRectEmpty() && font && _text) {
font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top);
}
@@ -239,7 +239,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
//////////////////////////////////////////////////////////////////////////
bool UIWindow::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIWindow::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -298,7 +298,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(EDIT)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIWindow::loadBuffer(byte *buffer, bool complete) {
+bool UIWindow::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(WINDOW)
TOKEN_TABLE(ALPHA_COLOR)
@@ -338,7 +338,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDIT)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
@@ -346,33 +346,33 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
int ar = 0, ag = 0, ab = 0, alpha = 0;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WINDOW) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_WINDOW) {
_gameRef->LOG(0, "'WINDOW' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) >= PARSERR_TOKENNOTFOUND) {
+ while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand(&buffer, commands, &params)) >= PARSERR_TOKENNOTFOUND) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -382,7 +382,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_INACTIVE:
delete _backInactive;
_backInactive = new UITiledImage(_gameRef);
- if (!_backInactive || DID_FAIL(_backInactive->loadFile((char *)params))) {
+ if (!_backInactive || DID_FAIL(_backInactive->loadFile(params))) {
delete _backInactive;
_backInactive = nullptr;
cmd = PARSERR_GENERIC;
@@ -392,7 +392,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -400,9 +400,9 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IMAGE_INACTIVE:
- delete _imageInactive,
- _imageInactive = new BaseSprite(_gameRef);
- if (!_imageInactive || DID_FAIL(_imageInactive->loadFile((char *)params))) {
+ delete _imageInactive;
+ _imageInactive = new BaseSprite(_gameRef);
+ if (!_imageInactive || DID_FAIL(_imageInactive->loadFile(params))) {
delete _imageInactive;
_imageInactive = nullptr;
cmd = PARSERR_GENERIC;
@@ -413,7 +413,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -423,21 +423,21 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
if (_fontInactive) {
_gameRef->_fontStorage->removeFont(_fontInactive);
}
- _fontInactive = _gameRef->_fontStorage->addFont((char *)params);
+ _fontInactive = _gameRef->_fontStorage->addFont(params);
if (!_fontInactive) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TITLE:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TITLE_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_titleAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_titleAlign = TAL_RIGHT;
} else {
_titleAlign = TAL_CENTER;
@@ -445,33 +445,33 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_TITLE_RECT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom);
break;
case TOKEN_DRAG_RECT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -532,48 +532,48 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TRANSPARENT:
- parser.scanStr((char *)params, "%b", &_transparent);
+ parser.scanStr(params, "%b", &_transparent);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_PAUSE_MUSIC:
- parser.scanStr((char *)params, "%b", &_pauseMusic);
+ parser.scanStr(params, "%b", &_pauseMusic);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_MENU:
- parser.scanStr((char *)params, "%b", &_isMenu);
+ parser.scanStr(params, "%b", &_isMenu);
break;
case TOKEN_IN_GAME:
- parser.scanStr((char *)params, "%b", &_inGame);
+ parser.scanStr(params, "%b", &_inGame);
break;
case TOKEN_CLIP_CONTENTS:
- parser.scanStr((char *)params, "%b", &_clipContents);
+ parser.scanStr(params, "%b", &_clipContents);
break;
case TOKEN_FADE_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &fadeR, &fadeG, &fadeB);
+ parser.scanStr(params, "%d,%d,%d", &fadeR, &fadeG, &fadeB);
_fadeBackground = true;
break;
case TOKEN_FADE_ALPHA:
- parser.scanStr((char *)params, "%d", &fadeA);
+ parser.scanStr(params, "%d", &fadeA);
_fadeBackground = true;
break;
@@ -582,16 +582,16 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
default:
- if (DID_FAIL(_gameRef->windowLoadHook(this, (char **)&buffer, (char **)params))) {
+ if (DID_FAIL(_gameRef->windowLoadHook(this, &buffer, &params))) {
cmd = PARSERR_GENERIC;
}
}
@@ -676,11 +676,11 @@ bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) {
error("UIWindow::SaveAsText - Unhandled enum-value NUM_TEXT_ALIGN");
}
- if (!BasePlatform::isRectEmpty(&_titleRect)) {
+ if (!_titleRect.isRectEmpty()) {
buffer->putTextIndent(indent + 2, "TITLE_RECT { %d, %d, %d, %d }\n", _titleRect.left, _titleRect.top, _titleRect.right, _titleRect.bottom);
}
- if (!BasePlatform::isRectEmpty(&_dragRect)) {
+ if (!_dragRect.isRectEmpty()) {
buffer->putTextIndent(indent + 2, "DRAG_RECT { %d, %d, %d, %d }\n", _dragRect.left, _dragRect.top, _dragRect.right, _dragRect.bottom);
}
@@ -737,7 +737,7 @@ bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool UIWindow::enableWidget(const char *name, bool enable) {
for (uint32 i = 0; i < _widgets.size(); i++) {
if (scumm_stricmp(_widgets[i]->getName(), name) == 0) {
- _widgets[i]->_disable = !enable;
+ _widgets[i]->setDisabled(!enable);
}
}
return STATUS_OK;
@@ -748,7 +748,7 @@ bool UIWindow::enableWidget(const char *name, bool enable) {
bool UIWindow::showWidget(const char *name, bool visible) {
for (uint32 i = 0; i < _widgets.size(); i++) {
if (scumm_stricmp(_widgets[i]->getName(), name) == 0) {
- _widgets[i]->_visible = visible;
+ _widgets[i]->setVisible(visible);
}
}
return STATUS_OK;
@@ -1227,7 +1227,7 @@ bool UIWindow::handleMouse(TMouseEvent event, TMouseButton button) {
bool res = UIObject::handleMouse(event, button);
// handle window dragging
- if (!BasePlatform::isRectEmpty(&_dragRect)) {
+ if (!_dragRect.isRectEmpty()) {
// start drag
if (event == MOUSE_CLICK && button == MOUSE_BUTTON_LEFT) {
Rect32 dragRect = _dragRect;
@@ -1258,24 +1258,24 @@ bool UIWindow::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_backInactive));
- persistMgr->transfer(TMEMBER(_clipContents));
- persistMgr->transfer(TMEMBER(_dragFrom));
- persistMgr->transfer(TMEMBER(_dragging));
- persistMgr->transfer(TMEMBER(_dragRect));
- persistMgr->transfer(TMEMBER(_fadeBackground));
- persistMgr->transfer(TMEMBER(_fadeColor));
+ persistMgr->transferBool(TMEMBER(_clipContents));
+ persistMgr->transferPoint32(TMEMBER(_dragFrom));
+ persistMgr->transferBool(TMEMBER(_dragging));
+ persistMgr->transferRect32(TMEMBER(_dragRect));
+ persistMgr->transferBool(TMEMBER(_fadeBackground));
+ persistMgr->transferUint32(TMEMBER(_fadeColor));
persistMgr->transferPtr(TMEMBER_PTR(_fontInactive));
persistMgr->transferPtr(TMEMBER_PTR(_imageInactive));
- persistMgr->transfer(TMEMBER(_inGame));
- persistMgr->transfer(TMEMBER(_isMenu));
- persistMgr->transfer(TMEMBER_INT(_mode));
+ persistMgr->transferBool(TMEMBER(_inGame));
+ persistMgr->transferBool(TMEMBER(_isMenu));
+ persistMgr->transferSint32(TMEMBER_INT(_mode));
persistMgr->transferPtr(TMEMBER_PTR(_shieldButton));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER_INT(_titleAlign));
- persistMgr->transfer(TMEMBER(_titleRect));
- persistMgr->transfer(TMEMBER(_transparent));
+ persistMgr->transferSint32(TMEMBER_INT(_titleAlign));
+ persistMgr->transferRect32(TMEMBER(_titleRect));
+ persistMgr->transferBool(TMEMBER(_transparent));
persistMgr->transferPtr(TMEMBER_PTR(_viewport));
- persistMgr->transfer(TMEMBER(_pauseMusic));
+ persistMgr->transferBool(TMEMBER(_pauseMusic));
_widgets.persist(persistMgr);
@@ -1309,7 +1309,7 @@ bool UIWindow::moveFocus(bool forward) {
bool done = false;
while (numTries <= (int32)_widgets.size()) {
- if (_widgets[i] != _focusedWidget && _widgets[i]->_canFocus && _widgets[i]->_visible && !_widgets[i]->_disable) {
+ if (_widgets[i] != _focusedWidget && _widgets[i]->canFocus() && _widgets[i]->isVisible() && !_widgets[i]->isDisabled()) {
_focusedWidget = _widgets[i];
done = true;
break;
@@ -1419,7 +1419,7 @@ void UIWindow::makeFreezable(bool freezable) {
bool UIWindow::getWindowObjects(BaseArray<UIObject *> &objects, bool interactiveOnly) {
for (uint32 i = 0; i < _widgets.size(); i++) {
UIObject *control = _widgets[i];
- if (control->_disable && interactiveOnly) {
+ if (control->isDisabled() && interactiveOnly) {
continue;
}
@@ -1442,4 +1442,14 @@ bool UIWindow::getWindowObjects(BaseArray<UIObject *> &objects, bool interactive
return STATUS_OK;
}
-} // end of namespace Wintermute
+bool UIWindow::getInGame() const {
+ return _inGame;
+}
+
+TWindowMode UIWindow::getMode() const {
+ return _mode;
+}
+
+
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_window.h b/engines/wintermute/ui/ui_window.h
index 70799cea25..6b4d970581 100644
--- a/engines/wintermute/ui/ui_window.h
+++ b/engines/wintermute/ui/ui_window.h
@@ -38,47 +38,32 @@ namespace Wintermute {
class UIButton;
class BaseViewport;
class UIWindow : public UIObject {
- uint32 _fadeColor;
public:
bool getWindowObjects(BaseArray<UIObject *> &Objects, bool InteractiveOnly);
- bool _pauseMusic;
void cleanup();
virtual void makeFreezable(bool freezable);
- BaseViewport *_viewport;
- bool _clipContents;
- bool _inGame;
- bool _isMenu;
- bool _fadeBackground;
virtual bool handleMouseWheel(int delta);
- UIWindow *_shieldWindow;
- UIButton *_shieldButton;
+
bool close();
bool goSystemExclusive();
bool goExclusive();
- TWindowMode _mode;
bool moveFocus(bool forward = true);
virtual bool handleMouse(TMouseEvent Event, TMouseButton Button);
- Point32 _dragFrom;
- bool _dragging;
DECLARE_PERSISTENT(UIWindow, UIObject)
- bool _transparent;
bool showWidget(const char *name, bool visible = true);
bool enableWidget(const char *name, bool enable = true);
- Rect32 _titleRect;
- Rect32 _dragRect;
+
virtual bool display(int offsetX = 0, int offsetY = 0) override;
UIWindow(BaseGame *inGame);
virtual ~UIWindow();
virtual bool handleKeypress(Common::Event *event, bool printable = false) override;
BaseArray<UIObject *> _widgets;
- TTextAlign _titleAlign;
+
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- UITiledImage *_backInactive;
- BaseFont *_fontInactive;
- BaseSprite *_imageInactive;
+ bool loadBuffer(char *buffer, bool complete = true);
+
virtual bool listen(BaseScriptHolder *param1, uint32 param2);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
@@ -87,8 +72,32 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString();
+
+ bool getInGame() const;
+ TWindowMode getMode() const;
+
+private:
+ bool _pauseMusic;
+ BaseViewport *_viewport;
+ bool _clipContents;
+ bool _inGame;
+ bool _isMenu;
+ bool _fadeBackground;
+ TWindowMode _mode;
+ Point32 _dragFrom;
+ bool _dragging;
+ bool _transparent;
+ uint32 _fadeColor;
+ UIWindow *_shieldWindow;
+ UIButton *_shieldButton;
+ Rect32 _titleRect;
+ Rect32 _dragRect;
+ UITiledImage *_backInactive;
+ BaseFont *_fontInactive;
+ BaseSprite *_imageInactive;
+ TTextAlign _titleAlign;
};
-} // end of namespace Wintermute
+} // 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..702dd04c27 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -50,147 +50,94 @@ bool StringUtil::compareNoCase(const AnsiString &str1, const AnsiString &str2) {
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::utf8ToWide(const Utf8String &Utf8Str) {
- error("StringUtil::Utf8ToWide - WideString not supported yet");
- /* size_t WideSize = Utf8Str.size();
-
- if (sizeof(wchar_t) == 2) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
-
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
-
- UTF16 *TargetStart = reinterpret_cast<UTF16 *>(WideStringNative);
- UTF16 *TargetEnd = TargetStart + WideSize + 1;
-
- ConversionResult res = ConvertUTF8toUTF16(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
-
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
-
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
-
- UTF32 *TargetStart = reinterpret_cast<UTF32 *>(WideStringNative);
- UTF32 *TargetEnd = TargetStart + WideSize;
-
- ConversionResult res = ConvertUTF8toUTF32(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
-
- return ResultString;
- } else {
- return L"";
- }*/
- return "";
+ size_t wideSize = Utf8Str.size();
+
+ uint32 *wideStringNative = new uint32[wideSize + 1];
+
+ const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
+ const UTF8 *sourceEnd = sourceStart + wideSize;
+
+ UTF32 *targetStart = reinterpret_cast<UTF32 *>(wideStringNative);
+ UTF32 *targetEnd = targetStart + wideSize;
+
+ ConversionResult res = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] wideStringNative;
+ return WideString();
+ }
+ *targetStart = 0;
+ WideString resultString(wideStringNative);
+ delete[] wideStringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
- error("StringUtil::wideToUtf8 - Widestring not supported yet");
- /* size_t WideSize = WideStr.length();
-
- if (sizeof(wchar_t) == 2) {
- size_t utf8Size = 3 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
-
- const UTF16 *SourceStart = reinterpret_cast<const UTF16 *>(WideStr.c_str());
- const UTF16 *SourceEnd = SourceStart + WideSize;
-
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF16toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- size_t utf8Size = 4 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
-
- const UTF32 *SourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
- const UTF32 *SourceEnd = SourceStart + WideSize;
-
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF32toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else {
- return (Utf8String)"";
- }*/
- return "";
-}
+ size_t wideSize = WideStr.size();
-// Currently this only does Ansi->ISO 8859, and only for carets.
-char simpleAnsiToWide(const AnsiString &str, uint32 &offset) {
- byte c = str[offset];
+ size_t utf8Size = 4 * wideSize + 1;
+ char *utf8StringNative = new char[utf8Size];
- if (c == 146) {
- offset++;
- return 39; // Replace right-quote with apostrophe
- } else {
- offset++;
- return c;
+ const UTF32 *sourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
+ const UTF32 *sourceEnd = sourceStart + wideSize;
+
+ UTF8 *targetStart = reinterpret_cast<UTF8 *>(utf8StringNative);
+ UTF8 *targetEnd = targetStart + utf8Size;
+
+ ConversionResult res = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] utf8StringNative;
+ return Utf8String();
}
+ *targetStart = 0;
+ Utf8String resultString(utf8StringNative);
+ delete[] utf8StringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::ansiToWide(const AnsiString &str) {
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- Common::String converted = "";
- uint32 index = 0;
- while (index != str.size()) {
- converted += simpleAnsiToWide(str, index);
+ WideString result;
+ for (AnsiString::const_iterator i = str.begin(), end = str.end(); i != end; ++i) {
+ const byte c = *i;
+ if (c < 0x80 || c >= 0xA0) {
+ result += c;
+ } else {
+ uint32 utf32 = _ansiToUTF32[c - 0x80];
+ if (utf32) {
+ result += utf32;
+ } else {
+ // It's an invalid CP1252 character...
+ }
+ }
}
- // using default os locale!
-
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = mbstowcs(NULL, str.c_str(), 0) + 1;
- wchar_t *wstr = new wchar_t[WideSize];
- mbstowcs(wstr, str.c_str(), WideSize);
- WideString ResultString(wstr);
- delete[] wstr;
- return ResultString;*/
- return WideString(converted);
+ return result;
}
//////////////////////////////////////////////////////////////////////////
AnsiString StringUtil::wideToAnsi(const WideString &wstr) {
- // using default os locale!
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = wcstombs(NULL, wstr.c_str(), 0) + 1;
- char *str = new char[WideSize];
- wcstombs(str, wstr.c_str(), WideSize);
- AnsiString ResultString(str);
- delete[] str;
- return ResultString;*/
- return AnsiString(wstr);
+ AnsiString result;
+ for (WideString::const_iterator i = wstr.begin(), end = wstr.end(); i != end; ++i) {
+ const uint32 c = *i;
+ if (c < 0x80 || (c >= 0xA0 && c <= 0xFF)) {
+ result += c;
+ } else {
+ uint32 ansi = 0xFFFFFFFF;
+ for (uint j = 0; j < ARRAYSIZE(_ansiToUTF32); ++j) {
+ if (_ansiToUTF32[j] == c) {
+ ansi = j + 0x80;
+ break;
+ }
+ }
+
+ if (ansi != 0xFFFFFFFF) {
+ result += ansi;
+ } else {
+ // There's no valid CP1252 code for this character...
+ }
+ }
+ }
+ return result;
}
//////////////////////////////////////////////////////////////////////////
@@ -204,12 +151,7 @@ bool StringUtil::isUtf8BOM(const byte *buffer, uint32 bufferSize) {
//////////////////////////////////////////////////////////////////////////
int StringUtil::indexOf(const WideString &str, const WideString &toFind, size_t startFrom) {
- const char *index = strstr(str.c_str(), toFind.c_str());
- if (index == nullptr) {
- return -1;
- } else {
- return index - str.c_str();
- }
+ return str.find(toFind, startFrom);
}
Common::String StringUtil::encodeSetting(const Common::String &str) {
@@ -230,5 +172,10 @@ AnsiString StringUtil::toString(int val) {
return Common::String::format("%d", val);
}
+// Mapping of CP1252 characters 0x80...0x9F into UTF-32
+uint32 StringUtil::_ansiToUTF32[32] = {
+ 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178
+};
-} // end of namespace Wintermute
+} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/string_util.h b/engines/wintermute/utils/string_util.h
index e419e2bca8..14c40fcb2b 100644
--- a/engines/wintermute/utils/string_util.h
+++ b/engines/wintermute/utils/string_util.h
@@ -49,8 +49,11 @@ public:
static Common::String decodeSetting(const Common::String &str);
static AnsiString toString(int val);
+
+private:
+ static uint32 _ansiToUTF32[32];
};
-} // 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..44eecf93a8 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -34,7 +34,6 @@
#include "engines/wintermute/base/gfx/base_image.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/sound/base_sound_manager.h"
-#include "engines/wintermute/platform_osystem.h"
#include "video/theora_decoder.h"
#include "engines/wintermute/wintermute.h"
#include "common/system.h"
@@ -163,14 +162,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 +368,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
@@ -396,7 +395,7 @@ bool VideoTheoraPlayer::display(uint32 alpha) {
bool res;
if (_texture && _videoFrameReady) {
- BasePlatform::setRect(&rc, 0, 0, _texture->getWidth(), _texture->getHeight());
+ rc.setRect(0, 0, _texture->getWidth(), _texture->getHeight());
if (_playZoom == 100.0f) {
res = _texture->displayTrans(_posX, _posY, rc, alpha);
} else {
@@ -417,7 +416,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 = "";
@@ -492,16 +491,16 @@ bool VideoTheoraPlayer::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_savedPos));
- persistMgr->transfer(TMEMBER(_savedState));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_alphaFilename));
- persistMgr->transfer(TMEMBER(_posX));
- persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_playZoom));
- persistMgr->transfer(TMEMBER_INT(_playbackType));
- persistMgr->transfer(TMEMBER(_looping));
- persistMgr->transfer(TMEMBER(_volume));
+ persistMgr->transferUint32(TMEMBER(_savedPos));
+ persistMgr->transferSint32(TMEMBER(_savedState));
+ persistMgr->transferString(TMEMBER(_filename));
+ persistMgr->transferString(TMEMBER(_alphaFilename));
+ persistMgr->transferSint32(TMEMBER(_posX));
+ persistMgr->transferSint32(TMEMBER(_posY));
+ persistMgr->transferFloat(TMEMBER(_playZoom));
+ persistMgr->transferSint32(TMEMBER_INT(_playbackType));
+ persistMgr->transferBool(TMEMBER(_looping));
+ persistMgr->transferSint32(TMEMBER(_volume));
if (!persistMgr->getIsSaving() && (_savedState != THEORA_STATE_NONE)) {
initializeSimple();
@@ -529,4 +528,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..7b28a71e17 100644
--- a/engines/wintermute/video/video_theora_player.h
+++ b/engines/wintermute/video/video_theora_player.h
@@ -62,7 +62,7 @@ public:
//CVidSubtitler *_subtitler;
// control methods
- bool initialize(const Common::String &filename, const Common::String &subtitleFile = nullptr);
+ bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String());
bool initializeSimple();
bool update();
bool play(TVideoPlayback type = VID_PLAY_CENTER, int x = 0, int y = 0, bool freezeGame = false, bool freezeMusic = true, bool looping = false, uint32 startTime = 0, float forceZoom = -1.0f, int volume = -1);
@@ -90,7 +90,7 @@ public:
BaseImage *_alphaImage;
Common::String _alphaFilename;
bool setAlphaImage(const Common::String &filename);
- __inline byte getAlphaAt(int x, int y) const;
+ byte getAlphaAt(int x, int y) const;
void writeAlpha();
bool seekToTime(uint32 Time);
@@ -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 89a6f1b3e0..0a6be4caf8 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -26,7 +26,6 @@
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
-#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/tokenizer.h"
@@ -106,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");
@@ -134,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;
@@ -148,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.");
@@ -251,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/engines/zvision/animation/rlf_animation.cpp b/engines/zvision/animation/rlf_animation.cpp
new file mode 100644
index 0000000000..c7307265c0
--- /dev/null
+++ b/engines/zvision/animation/rlf_animation.cpp
@@ -0,0 +1,331 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/animation/rlf_animation.h"
+
+#include "common/str.h"
+#include "common/file.h"
+#include "common/textconsole.h"
+#include "common/debug.h"
+#include "common/endian.h"
+
+#include "graphics/colormasks.h"
+
+
+namespace ZVision {
+
+RlfAnimation::RlfAnimation(const Common::String &fileName, bool stream)
+ : _stream(stream),
+ _lastFrameRead(0),
+ _frameCount(0),
+ _width(0),
+ _height(0),
+ _frameTime(0),
+ _frames(0),
+ _currentFrame(-1),
+ _frameBufferByteSize(0) {
+ if (!_file.open(fileName)) {
+ warning("RLF animation file %s could not be opened", fileName.c_str());
+ return;
+ }
+
+ if (!readHeader()) {
+ warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str());
+ return;
+ }
+
+ _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
+ _frameBufferByteSize = _width * _height * sizeof(uint16);
+
+ if (!stream) {
+ _frames = new Frame[_frameCount];
+
+ // Read in each frame
+ for (uint i = 0; i < _frameCount; ++i) {
+ _frames[i] = readNextFrame();
+ }
+ }
+}
+
+RlfAnimation::~RlfAnimation() {
+ for (uint i = 0; i < _frameCount; ++i) {
+ delete[] _frames[i].encodedData;
+ }
+ delete[] _frames;
+ _currentFrameBuffer.free();
+}
+
+bool RlfAnimation::readHeader() {
+ if (_file.readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
+ return false;
+ }
+
+ // Read the header
+ _file.readUint32LE(); // Size1
+ _file.readUint32LE(); // Unknown1
+ _file.readUint32LE(); // Unknown2
+ _frameCount = _file.readUint32LE(); // Frame count
+
+ // Since we don't need any of the data, we can just seek right to the
+ // entries we need rather than read in all the individual entries.
+ _file.seek(136, SEEK_CUR);
+
+ //// Read CIN header
+ //_file.readUint32BE(); // Magic number FNIC
+ //_file.readUint32LE(); // Size2
+ //_file.readUint32LE(); // Unknown3
+ //_file.readUint32LE(); // Unknown4
+ //_file.readUint32LE(); // Unknown5
+ //_file.seek(0x18, SEEK_CUR); // VRLE
+ //_file.readUint32LE(); // LRVD
+ //_file.readUint32LE(); // Unknown6
+ //_file.seek(0x18, SEEK_CUR); // HRLE
+ //_file.readUint32LE(); // ELHD
+ //_file.readUint32LE(); // Unknown7
+ //_file.seek(0x18, SEEK_CUR); // HKEY
+ //_file.readUint32LE(); // ELRH
+
+ //// Read MIN info header
+ //_file.readUint32BE(); // Magic number FNIM
+ //_file.readUint32LE(); // Size3
+ //_file.readUint32LE(); // OEDV
+ //_file.readUint32LE(); // Unknown8
+ //_file.readUint32LE(); // Unknown9
+ //_file.readUint32LE(); // Unknown10
+ _width = _file.readUint32LE(); // Width
+ _height = _file.readUint32LE(); // Height
+
+ // Read time header
+ _file.readUint32BE(); // Magic number EMIT
+ _file.readUint32LE(); // Size4
+ _file.readUint32LE(); // Unknown11
+ _frameTime = _file.readUint32LE() / 10; // Frame time in microseconds
+
+ return true;
+}
+
+RlfAnimation::Frame RlfAnimation::readNextFrame() {
+ RlfAnimation::Frame frame;
+
+ _file.readUint32BE(); // Magic number MARF
+ uint32 size = _file.readUint32LE(); // Size
+ _file.readUint32LE(); // Unknown1
+ _file.readUint32LE(); // Unknown2
+ uint32 type = _file.readUint32BE(); // Either ELHD or ELRH
+ uint32 headerSize = _file.readUint32LE(); // Offset from the beginning of this frame to the frame data. Should always be 28
+ _file.readUint32LE(); // Unknown3
+
+ frame.encodedSize = size - headerSize;
+ frame.encodedData = new int8[frame.encodedSize];
+ _file.read(frame.encodedData, frame.encodedSize);
+
+ if (type == MKTAG('E', 'L', 'H', 'D')) {
+ frame.type = Masked;
+ } else if (type == MKTAG('E', 'L', 'R', 'H')) {
+ frame.type = Simple;
+ _completeFrames.push_back(_lastFrameRead);
+ } else {
+ warning("Frame %u doesn't have type that can be decoded", _lastFrameRead);
+ }
+
+ _lastFrameRead++;
+ return frame;
+}
+
+void RlfAnimation::seekToFrame(int frameNumber) {
+ assert(!_stream);
+ assert(frameNumber < (int)_frameCount || frameNumber >= -1);
+
+ if (frameNumber == -1) {
+ _currentFrame = -1;
+ return;
+ }
+
+ int closestFrame = _currentFrame;
+ int distance = (int)frameNumber - _currentFrame;
+ for (uint i = 0; i < _completeFrames.size(); ++i) {
+ int newDistance = (int)frameNumber - (int)(_completeFrames[i]);
+ if (newDistance > 0 && (closestFrame == -1 || newDistance < distance)) {
+ closestFrame = _completeFrames[i];
+ distance = newDistance;
+ }
+ }
+
+ for (int i = closestFrame; i <= frameNumber; ++i) {
+ applyFrameToCurrent(i);
+ }
+
+ _currentFrame = frameNumber;
+}
+
+const Graphics::Surface *RlfAnimation::getFrameData(uint frameNumber) {
+ assert(!_stream);
+ assert(frameNumber < _frameCount);
+
+ // Since this method is so expensive, first check to see if we can use
+ // getNextFrame() it's cheap.
+ if ((int)frameNumber == _currentFrame) {
+ return &_currentFrameBuffer;
+ } else if (_currentFrame + 1 == (int)frameNumber) {
+ return getNextFrame();
+ }
+
+ seekToFrame(frameNumber);
+ return &_currentFrameBuffer;
+}
+
+const Graphics::Surface *RlfAnimation::getNextFrame() {
+ assert(_currentFrame + 1 < (int)_frameCount);
+
+ if (_stream) {
+ applyFrameToCurrent(readNextFrame());
+ } else {
+ applyFrameToCurrent(_currentFrame + 1);
+ }
+
+ _currentFrame++;
+ return &_currentFrameBuffer;
+}
+
+void RlfAnimation::applyFrameToCurrent(uint frameNumber) {
+ if (_frames[frameNumber].type == Masked) {
+ decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
+ } else if (_frames[frameNumber].type == Simple) {
+ decodeSimpleRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
+ }
+}
+
+void RlfAnimation::applyFrameToCurrent(const RlfAnimation::Frame &frame) {
+ if (frame.type == Masked) {
+ decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
+ } else if (frame.type == Simple) {
+ decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
+ }
+}
+
+void RlfAnimation::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+
+ while (sourceOffset < sourceSize) {
+ int8 numberOfSamples = source[sourceOffset];
+ sourceOffset++;
+
+ // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
+ // be copied directly from source to dest
+ if (numberOfSamples < 0) {
+ numberOfSamples = ABS(numberOfSamples);
+
+ while (numberOfSamples > 0) {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ byte r, g, b;
+ Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ WRITE_UINT16(dest + destOffset, destColor);
+
+ sourceOffset += 2;
+ destOffset += 2;
+ numberOfSamples--;
+ }
+
+ // If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2)
+ // This function assumes the dest buffer has been memset with 0's.
+ } else {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ destOffset += (numberOfSamples * 2) + 2;
+ }
+ }
+}
+
+void RlfAnimation::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+
+ while (sourceOffset < sourceSize) {
+ int8 numberOfSamples = source[sourceOffset];
+ sourceOffset++;
+
+ // If numberOfSamples is negative, the next abs(numberOfSamples) samples should
+ // be copied directly from source to dest
+ if (numberOfSamples < 0) {
+ numberOfSamples = ABS(numberOfSamples);
+
+ while (numberOfSamples > 0) {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ } else if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ byte r, g, b;
+ Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ WRITE_UINT16(dest + destOffset, destColor);
+
+ sourceOffset += 2;
+ destOffset += 2;
+ numberOfSamples--;
+ }
+
+ // If numberOfSamples is >= 0, copy one sample from source to the
+ // next (numberOfSamples + 2) dest spots
+ } else {
+ if (sourceOffset + 1 >= sourceSize) {
+ return;
+ }
+
+ byte r, g, b;
+ Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
+ uint16 sampleColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ sourceOffset += 2;
+
+ numberOfSamples += 2;
+ while (numberOfSamples > 0) {
+ if (destOffset + 1 >= destSize) {
+ debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
+ return;
+ }
+
+ WRITE_UINT16(dest + destOffset, sampleColor);
+ destOffset += 2;
+ numberOfSamples--;
+ }
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/animation/rlf_animation.h b/engines/zvision/animation/rlf_animation.h
new file mode 100644
index 0000000000..fe5b0d68b4
--- /dev/null
+++ b/engines/zvision/animation/rlf_animation.h
@@ -0,0 +1,163 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_RLF_ANIMATION_H
+#define ZVISION_RLF_ANIMATION_H
+
+#include "common/file.h"
+
+#include "graphics/surface.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+class RlfAnimation {
+public:
+ RlfAnimation(const Common::String &fileName, bool stream = true);
+ ~RlfAnimation();
+
+private:
+ enum EncodingType {
+ Masked,
+ Simple
+ };
+
+ struct Frame {
+ EncodingType type;
+ int8 *encodedData;
+ uint32 encodedSize;
+ };
+
+private:
+ Common::File _file;
+ bool _stream;
+ uint _lastFrameRead;
+
+ uint _frameCount;
+ uint _width;
+ uint _height;
+ uint32 _frameTime; // In milliseconds
+ Frame *_frames;
+ Common::Array<uint> _completeFrames;
+
+ int _currentFrame;
+ Graphics::Surface _currentFrameBuffer;
+ uint32 _frameBufferByteSize;
+
+public:
+ uint frameCount() { return _frameCount; }
+ uint width() { return _width; }
+ uint height() { return _height; }
+ uint32 frameTime() { return _frameTime; }
+
+ /**
+ * Seeks to the frameNumber and updates the internal Surface with
+ * the new frame data. If frameNumber == -1, it only sets _currentFrame,
+ * the internal Surface is unchanged. This function requires _stream = false
+ *
+ * @param frameNumber The frame number to seek to
+ */
+ void seekToFrame(int frameNumber);
+
+ /**
+ * Returns the pixel data of the frame specified. It will try to use
+ * getNextFrame() if possible. If not, it uses seekToFrame() to
+ * update the internal Surface and then returns a pointer to it.
+ * This function requires _stream = false
+ *
+ * @param frameNumber The frame number to get data for
+ * @return A pointer to the pixel data. Do NOT delete this.
+ */
+ const Graphics::Surface *getFrameData(uint frameNumber);
+ /**
+ * Returns the pixel data of the next frame. It is up to the user to
+ * check if the next frame is valid before calling this.
+ * IE. Use endOfAnimation()
+ *
+ * @return A pointer to the pixel data. Do NOT delete this.
+ */
+ const Graphics::Surface *getNextFrame();
+
+ /**
+ * @return Is the currentFrame is the last frame in the animation?
+ */
+ bool endOfAnimation() { return _currentFrame == (int)_frameCount - 1; }
+
+private:
+ /**
+ * Reads in the header of the RLF file
+ *
+ * @return Will return false if the header magic number is wrong
+ */
+ bool readHeader();
+ /**
+ * Reads the next frame from the RLF file, stores the data in
+ * a Frame object, then returns the object
+ *
+ * @return A Frame object representing the frame data
+ */
+ Frame readNextFrame();
+
+ /**
+ * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer.
+ * This function requires _stream = false so it can look up the Frame object
+ * referenced by frameNumber.
+ *
+ * @param frameNumber The frame number to apply to _currentFrameBuffer
+ */
+ void applyFrameToCurrent(uint frameNumber);
+ /**
+ * Applies the data from a Frame object on top of a _currentFrameBuffer.
+ *
+ * @param frame A Frame object to apply to _currentFrameBuffer
+ */
+ void applyFrameToCurrent(const RlfAnimation::Frame &frame);
+
+ /**
+ * Decode frame data that uses masked run length encoding. This is the encoding
+ * used by P-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+ /**
+ * Decode frame data that uses simple run length encoding. This is the encoding
+ * used by I-frames.
+ *
+ * @param source The source pixel data
+ * @param dest The destination buffer
+ * @param sourceSize The size of the source pixel data
+ * @param destSize The size of the destination buffer
+ */
+ void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/archives/zfs_archive.cpp b/engines/zvision/archives/zfs_archive.cpp
new file mode 100644
index 0000000000..b8175b4903
--- /dev/null
+++ b/engines/zvision/archives/zfs_archive.cpp
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/archives/zfs_archive.h"
+
+#include "common/memstream.h"
+#include "common/debug.h"
+#include "common/file.h"
+
+namespace ZVision {
+
+ZfsArchive::ZfsArchive(const Common::String &fileName) : _fileName(fileName) {
+ Common::File zfsFile;
+
+ if (!zfsFile.open(_fileName)) {
+ warning("ZFSArchive::ZFSArchive(): Could not find the archive file");
+ return;
+ }
+
+ readHeaders(&zfsFile);
+
+ debug(1, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size());
+}
+
+ZfsArchive::ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream) : _fileName(fileName) {
+ readHeaders(stream);
+
+ debug(1, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size());
+}
+
+ZfsArchive::~ZfsArchive() {
+ debug(1, "ZfsArchive Destructor Called");
+ ZfsEntryHeaderMap::iterator it = _entryHeaders.begin();
+ for ( ; it != _entryHeaders.end(); ++it) {
+ delete it->_value;
+ }
+}
+
+void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
+ // Don't do a straight struct cast since we can't guarantee endianness
+ _header.magic = stream->readUint32LE();
+ _header.unknown1 = stream->readUint32LE();
+ _header.maxNameLength = stream->readUint32LE();
+ _header.filesPerBlock = stream->readUint32LE();
+ _header.fileCount = stream->readUint32LE();
+ _header.xorKey[0] = stream->readByte();
+ _header.xorKey[1] = stream->readByte();
+ _header.xorKey[2] = stream->readByte();
+ _header.xorKey[3] = stream->readByte();
+ _header.fileSectionOffset = stream->readUint32LE();
+
+ uint32 nextOffset;
+
+ do {
+ // Read the offset to the next block
+ nextOffset = stream->readUint32LE();
+
+ // Read in each entry header
+ for (uint32 i = 0; i < _header.filesPerBlock; ++i) {
+ ZfsEntryHeader entryHeader;
+
+ entryHeader.name = readEntryName(stream);
+ entryHeader.offset = stream->readUint32LE();
+ entryHeader.id = stream->readUint32LE();
+ entryHeader.size = stream->readUint32LE();
+ entryHeader.time = stream->readUint32LE();
+ entryHeader.unknown = stream->readUint32LE();
+
+ if (entryHeader.size != 0)
+ _entryHeaders[entryHeader.name] = new ZfsEntryHeader(entryHeader);
+ }
+
+ // Seek to the next block of headers
+ stream->seek(nextOffset);
+ } while (nextOffset != 0);
+}
+
+Common::String ZfsArchive::readEntryName(Common::SeekableReadStream *stream) const {
+ // Entry Names are at most 16 bytes and are null padded
+ char buffer[16];
+ stream->read(buffer, 16);
+
+ return Common::String(buffer);
+}
+
+bool ZfsArchive::hasFile(const Common::String &name) const {
+ return _entryHeaders.contains(name);
+}
+
+int ZfsArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int matches = 0;
+
+ for (ZfsEntryHeaderMap::const_iterator it = _entryHeaders.begin(); it != _entryHeaders.end(); ++it) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->name, this)));
+ matches++;
+ }
+
+ return matches;
+}
+
+const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::String &name) const {
+ if (!_entryHeaders.contains(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::String &name) const {
+ if (!_entryHeaders.contains(name)) {
+ return 0;
+ }
+
+ ZfsEntryHeader *entryHeader = _entryHeaders[name];
+
+ Common::File zfsArchive;
+ zfsArchive.open(_fileName);
+ zfsArchive.seek(entryHeader->offset);
+
+ // This *HAS* to be malloc (not new[]) because MemoryReadStream uses free() to free the memory
+ byte* buffer = (byte *)malloc(entryHeader->size);
+ zfsArchive.read(buffer, entryHeader->size);
+ // Decrypt the data in place
+ if (_header.xorKey != 0)
+ unXor(buffer, entryHeader->size, _header.xorKey);
+
+ return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES);
+}
+
+void ZfsArchive::unXor(byte *buffer, uint32 length, const byte *xorKey) const {
+ for (uint32 i = 0; i < length; ++i)
+ buffer[i] ^= xorKey[i % 4];
+}
+
+} // End of namespace ZVision
+
+
diff --git a/engines/zvision/archives/zfs_archive.h b/engines/zvision/archives/zfs_archive.h
new file mode 100644
index 0000000000..d7b45e4b47
--- /dev/null
+++ b/engines/zvision/archives/zfs_archive.h
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ZFS_ARCHIVE_H
+#define ZVISION_ZFS_ARCHIVE_H
+
+#include "common/archive.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+struct ZfsHeader {
+ uint32 magic;
+ uint32 unknown1;
+ uint32 maxNameLength;
+ uint32 filesPerBlock;
+ uint32 fileCount;
+ byte xorKey[4];
+ uint32 fileSectionOffset;
+};
+
+struct ZfsEntryHeader {
+ Common::String name;
+ uint32 offset;
+ uint32 id;
+ uint32 size;
+ uint32 time;
+ uint32 unknown;
+};
+
+typedef Common::HashMap<Common::String, ZfsEntryHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap;
+
+class ZfsArchive : public Common::Archive {
+public:
+ ZfsArchive(const Common::String &fileName);
+ ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream);
+ ~ZfsArchive();
+
+ /**
+ * Check if a member with the given name is present in the Archive.
+ * Patterns are not allowed, as this is meant to be a quick File::exists()
+ * replacement.
+ */
+ bool hasFile(const Common::String &fileName) const;
+
+ /**
+ * Add all members of the Archive to list.
+ * Must only append to list, and not remove elements from it.
+ *
+ * @return The number of names added to list
+ */
+ int listMembers(Common::ArchiveMemberList &list) const;
+
+ /**
+ * Returns a ArchiveMember representation of the given file.
+ */
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+
+ /**
+ * Create a stream bound to a member with the specified name in the
+ * archive. If no member with this name exists, 0 is returned.
+ *
+ * @return The newly created input stream
+ */
+ Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+
+private:
+ const Common::String _fileName;
+ ZfsHeader _header;
+ ZfsEntryHeaderMap _entryHeaders;
+
+ /**
+ * Parses the zfs file into file entry headers that can be used later
+ * to get the entry data.
+ *
+ * @param stream The contents of the zfs file
+ */
+ void readHeaders(Common::SeekableReadStream *stream);
+
+ /**
+ * Entry names are contained within a 16 byte block. This reads the block
+ * and converts it the name to a Common::String
+ *
+ * @param stream The zfs file stream
+ * @return The entry file name
+ */
+ Common::String readEntryName(Common::SeekableReadStream *stream) const;
+
+ /**
+ * ZFS file entries can be encrypted using XOR encoding. This method
+ * decodes the buffer in place using the supplied xorKey.
+ *
+ * @param buffer The data to decode
+ * @param length Length of buffer
+ */
+ void unXor(byte *buffer, uint32 length, const byte *xorKey) const;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/configure.engine b/engines/zvision/configure.engine
new file mode 100644
index 0000000000..02e31943af
--- /dev/null
+++ b/engines/zvision/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine zvision "ZVision" no "" "" "freetype2 16bit"
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
new file mode 100644
index 0000000000..0d325ef7f7
--- /dev/null
+++ b/engines/zvision/core/console.cpp
@@ -0,0 +1,218 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/core/console.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/strings/string_manager.h"
+#include "zvision/video/zork_avi_decoder.h"
+#include "zvision/sound/zork_raw.h"
+#include "zvision/utility/utility.h"
+#include "zvision/cursors/cursor.h"
+
+#include "common/system.h"
+#include "common/file.h"
+#include "common/bufferedstream.h"
+
+#include "gui/debugger.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
+ DCmd_Register("loadimage", WRAP_METHOD(Console, cmdLoadImage));
+ DCmd_Register("loadvideo", WRAP_METHOD(Console, cmdLoadVideo));
+ DCmd_Register("loadsound", WRAP_METHOD(Console, cmdLoadSound));
+ DCmd_Register("raw2wav", WRAP_METHOD(Console, cmdRawToWav));
+ DCmd_Register("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState));
+ DCmd_Register("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable));
+ DCmd_Register("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV));
+ DCmd_Register("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
+ DCmd_Register("changelocation", WRAP_METHOD(Console, cmdChangeLocation));
+ DCmd_Register("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
+ DCmd_Register("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles));
+ DCmd_Register("rendertext", WRAP_METHOD(Console, cmdRenderText));
+}
+
+bool Console::cmdLoadImage(int argc, const char **argv) {
+ if (argc == 4)
+ _engine->getRenderManager()->renderImageToScreen(argv[1], atoi(argv[2]), atoi(argv[3]));
+ else {
+ DebugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n");
+ return true;
+ }
+
+ return true;
+}
+
+bool Console::cmdLoadVideo(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use loadvideo <fileName> to load a video to the screen\n");
+ return true;
+ }
+
+ ZorkAVIDecoder videoDecoder;
+ if (videoDecoder.loadFile(argv[1])) {
+ _engine->playVideo(videoDecoder);
+ }
+
+ return true;
+}
+
+bool Console::cmdLoadSound(int argc, const char **argv) {
+ if (!Common::File::exists(argv[1])) {
+ DebugPrintf("File does not exist\n");
+ return true;
+ }
+
+ if (argc == 2) {
+ Audio::AudioStream *soundStream = makeRawZorkStream(argv[1], _engine);
+ Audio::SoundHandle handle;
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
+
+ } else if (argc == 4) {
+ int isStereo = atoi(argv[3]);
+
+ Common::File *file = new Common::File();
+ file->open(argv[1]);
+
+ Audio::AudioStream *soundStream = makeRawZorkStream(file, atoi(argv[2]), isStereo == 0 ? false : true);
+ Audio::SoundHandle handle;
+ _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
+ } else {
+ DebugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n");
+ return true;
+ }
+
+ return true;
+}
+
+bool Console::cmdRawToWav(int argc, const char **argv) {
+ if (argc != 3) {
+ DebugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n");
+ return true;
+ }
+
+ convertRawToWav(argv[1], _engine, argv[2]);
+ return true;
+}
+
+bool Console::cmdSetRenderState(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+ return true;
+ }
+
+ Common::String renderState(argv[1]);
+
+ if (renderState.matchString("panorama", true))
+ _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::PANORAMA);
+ else if (renderState.matchString("tilt", true))
+ _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::TILT);
+ else if (renderState.matchString("flat", true))
+ _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT);
+ else
+ DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+
+ return true;
+}
+
+bool Console::cmdGenerateRenderTable(int argc, const char **argv) {
+ _engine->getRenderManager()->getRenderTable()->generateRenderTable();
+
+ return true;
+}
+
+bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n");
+ return true;
+ }
+
+ _engine->getRenderManager()->getRenderTable()->setPanoramaFoV(atof(argv[1]));
+
+ return true;
+}
+
+bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n");
+ return true;
+ }
+
+ _engine->getRenderManager()->getRenderTable()->setPanoramaScale(atof(argv[1]));
+
+ return true;
+}
+
+bool Console::cmdChangeLocation(int argc, const char **argv) {
+ if (argc != 6) {
+ DebugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n");
+ return true;
+ }
+
+ _engine->getScriptManager()->changeLocation(*(argv[1]), *(argv[2]), *(argv[3]), *(argv[4]), atoi(argv[5]));
+
+ return true;
+}
+
+bool Console::cmdDumpFile(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use dumpfile <fileName> to dump a file\n");
+ return true;
+ }
+
+ writeFileContentsToFile(argv[1], argv[1]);
+
+ return true;
+}
+
+bool Console::cmdParseAllScrFiles(int argc, const char **argv) {
+ Common::ArchiveMemberList list;
+ SearchMan.listMatchingMembers(list, "*.scr");
+
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ _engine->getScriptManager()->parseScrFile((*iter)->getName());
+ }
+
+ return true;
+}
+
+bool Console::cmdRenderText(int argc, const char **argv) {
+ if (argc != 7) {
+ DebugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n");
+ return true;
+ }
+
+ StringManager::TextStyle style = _engine->getStringManager()->getTextStyle(atoi(argv[2]));
+ _engine->getRenderManager()->renderTextToWorkingWindow(333, Common::String(argv[1]), style.font, atoi(argv[3]), atoi(argv[4]), style.color, atoi(argv[5]), -1, Graphics::kTextAlignLeft, atoi(argv[6]) == 0 ? false : true);
+
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/core/console.h b/engines/zvision/core/console.h
new file mode 100644
index 0000000000..0ca1b8cc70
--- /dev/null
+++ b/engines/zvision/core/console.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef ZVISION_CONSOLE_H
+#define ZVISION_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class Console : public GUI::Debugger {
+public:
+ Console(ZVision *engine);
+ virtual ~Console() {}
+
+private:
+ ZVision *_engine;
+
+ bool cmdLoadImage(int argc, const char **argv);
+ bool cmdLoadVideo(int argc, const char **argv);
+ bool cmdLoadSound(int argc, const char **argv);
+ bool cmdRawToWav(int argc, const char **argv);
+ bool cmdSetRenderState(int argc, const char **argv);
+ bool cmdGenerateRenderTable(int argc, const char **argv);
+ bool cmdSetPanoramaFoV(int argc, const char **argv);
+ bool cmdSetPanoramaScale(int argc, const char **argv);
+ bool cmdChangeLocation(int argc, const char **argv);
+ bool cmdDumpFile(int argc, const char **argv);
+ bool cmdParseAllScrFiles(int argc, const char **argv);
+ bool cmdRenderText(int argc, const char **argv);
+};
+
+} // End of namespace ZVision
+#endif
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
new file mode 100644
index 0000000000..40bfb879b1
--- /dev/null
+++ b/engines/zvision/core/events.cpp
@@ -0,0 +1,186 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+
+#include "zvision/core/console.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/animation/rlf_animation.h"
+
+#include "common/events.h"
+#include "common/system.h"
+#include "common/rational.h"
+
+#include "engines/util.h"
+
+
+namespace ZVision {
+
+void ZVision::processEvents() {
+ while (_eventMan->pollEvent(_event)) {
+ switch (_event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ onMouseDown(_event.mouse);
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ onMouseUp(_event.mouse);
+ break;
+
+ case Common::EVENT_RBUTTONDOWN:
+ // TODO: Inventory logic
+ break;
+
+ case Common::EVENT_MOUSEMOVE:
+ onMouseMove(_event.mouse);
+ break;
+
+ case Common::EVENT_KEYDOWN:
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_d:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL)) {
+ // Start the debugger
+ _console->attach();
+ _console->onFrame();
+ }
+ break;
+ case Common::KEYCODE_q:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL))
+ quitGame();
+ break;
+ default:
+ break;
+ }
+
+ _scriptManager->onKeyDown(_event.kbd);
+ break;
+ case Common::EVENT_KEYUP:
+ _scriptManager->onKeyUp(_event.kbd);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void ZVision::onMouseDown(const Common::Point &pos) {
+ _cursorManager->cursorDown(true);
+
+ Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
+ _scriptManager->onMouseDown(pos, imageCoord);
+}
+
+void ZVision::onMouseUp(const Common::Point &pos) {
+ _cursorManager->cursorDown(false);
+
+ Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
+ _scriptManager->onMouseUp(pos, imageCoord);
+}
+
+void ZVision::onMouseMove(const Common::Point &pos) {
+ Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
+
+ bool cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);
+
+ // Graph of the function governing rotation velocity:
+ //
+ // |---------------- working window ------------------|
+ // ^ |---------|
+ // | |
+ // +Max velocity | rotation screen edge offset
+ // | /|
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // Zero velocity |______________________________ ______________________________/_________|__________________________>
+ // | Position -> | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // -Max velocity | |/
+ // |
+ // |
+ // ^
+
+ if (_workingWindow.contains(pos)) {
+ RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
+ if (renderState == RenderTable::PANORAMA) {
+ if (pos.x >= _workingWindow.left && pos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
+ // Linear function of distance to the left edge (y = -mx + b)
+ // We use fixed point math to get better accuracy
+ Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.left)) - MAX_ROTATION_SPEED;
+ _renderManager->setBackgroundVelocity(velocity.toInt());
+ _cursorManager->setLeftCursor();
+ cursorWasChanged = true;
+ } else if (pos.x <= _workingWindow.right && pos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
+ // Linear function of distance to the right edge (y = mx)
+ // We use fixed point math to get better accuracy
+ Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET);
+ _renderManager->setBackgroundVelocity(velocity.toInt());
+ _cursorManager->setRightCursor();
+ cursorWasChanged = true;
+ } else {
+ _renderManager->setBackgroundVelocity(0);
+ }
+ } else if (renderState == RenderTable::TILT) {
+ if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
+ // Linear function of distance to top edge
+ // We use fixed point math to get better accuracy
+ Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - MAX_ROTATION_SPEED;
+ _renderManager->setBackgroundVelocity(velocity.toInt());
+ _cursorManager->setUpCursor();
+ cursorWasChanged = true;
+ } else if (pos.y <= _workingWindow.bottom && pos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
+ // Linear function of distance to the bottom edge (y = mx)
+ // We use fixed point math to get better accuracy
+ Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET);
+ _renderManager->setBackgroundVelocity(velocity.toInt());
+ _cursorManager->setDownCursor();
+ cursorWasChanged = true;
+ } else {
+ _renderManager->setBackgroundVelocity(0);
+ }
+ }
+ } else {
+ _renderManager->setBackgroundVelocity(0);
+ }
+
+ if (!cursorWasChanged) {
+ _cursorManager->revertToIdle();
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/core/menu.h b/engines/zvision/core/menu.h
new file mode 100644
index 0000000000..affc69abd5
--- /dev/null
+++ b/engines/zvision/core/menu.h
@@ -0,0 +1,28 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_MENU_H
+#define ZVISION_MENU_H
+
+// TODO: Implement MenuHandler
+
+#endif
diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp
new file mode 100644
index 0000000000..b91f8eacad
--- /dev/null
+++ b/engines/zvision/core/save_manager.cpp
@@ -0,0 +1,206 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/core/save_manager.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/system.h"
+
+#include "graphics/surface.h"
+#include "graphics/thumbnail.h"
+
+#include "gui/message.h"
+
+
+namespace ZVision {
+
+const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
+
+void SaveManager::saveGame(uint slot, const Common::String &saveName) {
+ // The games only support 20 slots
+ assert(slot <= 1 && slot <= 20);
+
+ Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
+ Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));
+
+ // Write out the savegame header
+ file->writeUint32BE(SAVEGAME_ID);
+
+ // Write version
+ file->writeByte(SAVE_VERSION);
+
+ // Write savegame name
+ file->writeString(saveName);
+ file->writeByte(0);
+
+ // We can't call writeGameSaveData because the save menu is actually
+ // a room, so writeGameSaveData would save us in the save menu.
+ // However, an auto save is performed before each room change, so we
+ // can copy the data from there. We can guarantee that an auto save file will
+ // exist before this is called because the save menu can only be accessed
+ // after the first room (the main menu) has loaded.
+ Common::InSaveFile *autoSaveFile = saveFileManager->openForLoading(_engine->generateAutoSaveFileName());
+
+ // Skip over the header info
+ autoSaveFile->readSint32BE(); // SAVEGAME_ID
+ autoSaveFile->readByte(); // Version
+ autoSaveFile->seek(5, SEEK_CUR); // The string "auto" with terminating NULL
+
+ // Read the rest to a buffer
+ uint32 size = autoSaveFile->size() - autoSaveFile->pos();
+ byte *buffer = new byte[size];
+ autoSaveFile->read(buffer, size);
+
+ // Then write the buffer to the new file
+ file->write(buffer, size);
+
+ // Cleanup
+ delete[] buffer;
+ file->finalize();
+ delete file;
+}
+
+void SaveManager::autoSave() {
+ Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName());
+
+ // Write out the savegame header
+ file->writeUint32BE(SAVEGAME_ID);
+
+ // Version
+ file->writeByte(SAVE_VERSION);
+
+ file->writeString("auto");
+ file->writeByte(0);
+
+ writeSaveGameData(file);
+
+ // Cleanup
+ file->finalize();
+ delete file;
+}
+
+void SaveManager::writeSaveGameData(Common::OutSaveFile *file) {
+ // Create a thumbnail and save it
+ Graphics::saveThumbnail(*file);
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ file->writeSint16LE(td.tm_year + 1900);
+ file->writeSint16LE(td.tm_mon + 1);
+ file->writeSint16LE(td.tm_mday);
+ file->writeSint16LE(td.tm_hour);
+ file->writeSint16LE(td.tm_min);
+
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ // Write out the current location
+ Location currentLocation = scriptManager->getCurrentLocation();
+ file->writeByte(currentLocation.world);
+ file->writeByte(currentLocation.room);
+ file->writeByte(currentLocation.node);
+ file->writeByte(currentLocation.view);
+ file->writeUint32LE(currentLocation.offset);
+
+ // Write out the current state table values
+ scriptManager->serializeStateTable(file);
+
+ // Write out any controls needing to save state
+ scriptManager->serializeControls(file);
+}
+
+Common::Error SaveManager::loadGame(uint slot) {
+ // The games only support 20 slots
+ assert(slot <= 1 && slot <= 20);
+
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot));
+ if (saveFile == 0) {
+ return Common::kPathDoesNotExist;
+ }
+
+ // Read the header
+ SaveGameHeader header;
+ if (!readSaveGameHeader(saveFile, header)) {
+ return Common::kUnknownError;
+ }
+
+ char world = (char)saveFile->readByte();
+ char room = (char)saveFile->readByte();
+ char node = (char)saveFile->readByte();
+ char view = (char)saveFile->readByte();
+ uint32 offset = (char)saveFile->readUint32LE();
+
+ ScriptManager *scriptManager = _engine->getScriptManager();
+ // Update the state table values
+ scriptManager->deserializeStateTable(saveFile);
+
+ // Load the room
+ scriptManager->changeLocation(world, room, node, view, offset);
+
+ // Update the controls
+ scriptManager->deserializeControls(saveFile);
+
+ return Common::kNoError;
+}
+
+bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+ if (in->readUint32BE() != SAVEGAME_ID) {
+ warning("File is not a ZVision save file. Aborting load");
+ return false;
+ }
+
+ // Read in the version
+ header.version = in->readByte();
+
+ // Check that the save version isn't newer than this binary
+ if (header.version > SAVE_VERSION) {
+ uint tempVersion = header.version;
+ GUI::MessageDialog dialog(Common::String::format("This save file uses version %u, but this engine only supports up to version %d. You will need an updated version of the engine to use this save file.", tempVersion, SAVE_VERSION), "OK");
+ dialog.runModal();
+ }
+
+ // Read in the save name
+ header.saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0')
+ header.saveName += ch;
+
+ // Get the thumbnail
+ header.thumbnail = Graphics::loadThumbnail(*in);
+ if (!header.thumbnail)
+ return false;
+
+ // Read in save date/time
+ header.saveYear = in->readSint16LE();
+ header.saveMonth = in->readSint16LE();
+ header.saveDay = in->readSint16LE();
+ header.saveHour = in->readSint16LE();
+ header.saveMinutes = in->readSint16LE();
+
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/core/save_manager.h b/engines/zvision/core/save_manager.h
new file mode 100644
index 0000000000..b4770e68b2
--- /dev/null
+++ b/engines/zvision/core/save_manager.h
@@ -0,0 +1,91 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SAVE_MANAGER_H
+#define ZVISION_SAVE_MANAGER_H
+
+#include "common/savefile.h"
+
+namespace Common {
+class String;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct SaveGameHeader {
+ byte version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+ int saveYear, saveMonth, saveDay;
+ int saveHour, saveMinutes;
+};
+
+class SaveManager {
+public:
+ SaveManager(ZVision *engine) : _engine(engine) {}
+
+private:
+ ZVision *_engine;
+ static const uint32 SAVEGAME_ID;
+
+ enum {
+ SAVE_VERSION = 1
+ };
+
+public:
+ /**
+ * Called every room change. Saves the state of the room just before
+ * we switched rooms. Uses ZVision::generateAutoSaveFileName() to
+ * create the save file name.
+ */
+ void autoSave();
+ /**
+ * Copies the data from the last auto-save into a new save file. We
+ * can't use the current state data because the save menu *IS* a room.
+ * The file is named using ZVision::generateSaveFileName(slot)
+ *
+ * @param slot The save slot this save pertains to. Must be [1, 20]
+ * @param saveName The internal name for this save. This is NOT the name of the actual save file.
+ */
+ void saveGame(uint slot, const Common::String &saveName);
+ /**
+ * Loads the state data from the save file that slot references. Uses
+ * ZVision::generateSaveFileName(slot) to get the save file name.
+ *
+ * @param slot The save slot to load. Must be [1, 20]
+ */
+ Common::Error loadGame(uint slot);
+
+private:
+ void writeSaveGameData(Common::OutSaveFile *file);
+ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/cursors/cursor.cpp b/engines/zvision/cursors/cursor.cpp
new file mode 100644
index 0000000000..be80f6585b
--- /dev/null
+++ b/engines/zvision/cursors/cursor.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/cursors/cursor.h"
+
+#include "common/str.h"
+#include "common/file.h"
+
+
+namespace ZVision {
+
+ZorkCursor::ZorkCursor()
+ : _width(0),
+ _height(0),
+ _hotspotX(0),
+ _hotspotY(0) {
+}
+
+ZorkCursor::ZorkCursor(const Common::String &fileName)
+ : _width(0),
+ _height(0),
+ _hotspotX(0),
+ _hotspotY(0) {
+ Common::File file;
+ if (!file.open(fileName))
+ return;
+
+ uint32 magic = file.readUint32BE();
+ if (magic != MKTAG('Z', 'C', 'R', '1')) {
+ warning("%s is not a Zork Cursor file", fileName.c_str());
+ return;
+ }
+
+ _hotspotX = file.readUint16LE();
+ _hotspotY = file.readUint16LE();
+ _width = file.readUint16LE();
+ _height = file.readUint16LE();
+
+ uint dataSize = _width * _height * sizeof(uint16);
+ _surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+ uint32 bytesRead = file.read(_surface.getPixels(), dataSize);
+ assert(bytesRead == dataSize);
+
+ // Convert to RGB 565
+ _surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+}
+
+ZorkCursor::ZorkCursor(const ZorkCursor &other) {
+ _width = other._width;
+ _height = other._height;
+ _hotspotX = other._hotspotX;
+ _hotspotY = other._hotspotY;
+
+ _surface.copyFrom(other._surface);
+}
+
+ZorkCursor &ZorkCursor::operator=(const ZorkCursor &other) {
+ _width = other._width;
+ _height = other._height;
+ _hotspotX = other._hotspotX;
+ _hotspotY = other._hotspotY;
+
+ _surface.free();
+ _surface.copyFrom(other._surface);
+
+ return *this;
+}
+
+ZorkCursor::~ZorkCursor() {
+ _surface.free();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor.h b/engines/zvision/cursors/cursor.h
new file mode 100644
index 0000000000..18ac28ce8b
--- /dev/null
+++ b/engines/zvision/cursors/cursor.h
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_CURSOR_H
+#define ZVISION_CURSOR_H
+
+#include "graphics/surface.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+/**
+ * Utility class to parse and hold cursor data
+ * Modeled off Graphics::Cursor
+ */
+class ZorkCursor {
+public:
+ ZorkCursor();
+ ZorkCursor(const Common::String &fileName);
+ ZorkCursor(const ZorkCursor &other);
+ ~ZorkCursor();
+
+private:
+ uint16 _width;
+ uint16 _height;
+ uint16 _hotspotX;
+ uint16 _hotspotY;
+ Graphics::Surface _surface;
+
+public:
+ ZorkCursor &operator=(const ZorkCursor &other);
+
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ uint16 getHotspotX() const { return _hotspotX; }
+ uint16 getHotspotY() const { return _hotspotY; }
+ byte getKeyColor() const { return 0; }
+ const byte *getSurface() const { return (const byte *)_surface.getPixels(); }
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/cursors/cursor_manager.cpp b/engines/zvision/cursors/cursor_manager.cpp
new file mode 100644
index 0000000000..671f26ba2d
--- /dev/null
+++ b/engines/zvision/cursors/cursor_manager.cpp
@@ -0,0 +1,152 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/cursors/cursor_manager.h"
+
+#include "zvision/zvision.h"
+
+#include "common/system.h"
+
+#include "graphics/pixelformat.h"
+#include "graphics/cursorman.h"
+
+
+namespace ZVision {
+
+const char *CursorManager::_cursorNames[NUM_CURSORS] = { "active", "arrow", "backward", "downarrow", "forward", "handpt", "handpu", "hdown", "hleft",
+ "hright", "hup", "idle", "leftarrow", "rightarrow", "suggest_surround", "suggest_tilt", "turnaround", "zuparrow" };
+
+const char *CursorManager::_zgiCursorFileNames[NUM_CURSORS] = { "g0gbc011.zcr", "g0gac001.zcr", "g0gac021.zcr", "g0gac031.zcr", "g0gac041.zcr", "g0gac051.zcr", "g0gac061.zcr", "g0gac071.zcr", "g0gac081.zcr",
+ "g0gac091.zcr", "g0gac101.zcr", "g0gac011.zcr", "g0gac111.zcr", "g0gac121.zcr", "g0gac131.zcr", "g0gac141.zcr", "g0gac151.zcr", "g0gac161.zcr" };
+
+const char *CursorManager::_zNemCursorFileNames[NUM_CURSORS] = { "00act", "arrow", "back", "down", "forw", "handpt", "handpu", "hdown", "hleft",
+ "hright", "hup", "00idle", "left", "right", "ssurr", "stilt", "turn", "up" };
+
+
+CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat)
+ : _engine(engine),
+ _pixelFormat(pixelFormat),
+ _cursorIsPushed(false) {
+ // WARNING: The index IDLE_CURSOR_INDEX is hardcoded. If you change the order of _cursorNames/_zgiCursorFileNames/_zNemCursorFileNames, you HAVE to change the index accordingly
+ if (_engine->getGameId() == GID_NEMESIS) {
+ Common::String name(Common::String::format("%sa.zcr", _zNemCursorFileNames[IDLE_CURSOR_INDEX]));
+ _idleCursor = ZorkCursor(name);
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ _idleCursor = ZorkCursor(_zgiCursorFileNames[IDLE_CURSOR_INDEX]);
+ }
+}
+
+void CursorManager::initialize() {
+ revertToIdle();
+ CursorMan.showMouse(true);
+}
+
+void CursorManager::changeCursor(const Common::String &cursorName) {
+ changeCursor(cursorName, _cursorIsPushed);
+}
+
+void CursorManager::changeCursor(const Common::String &cursorName, bool pushed) {
+ if (_currentCursor.equals(cursorName) && _cursorIsPushed == pushed)
+ return;
+
+ if (_cursorIsPushed != pushed)
+ _cursorIsPushed = pushed;
+
+ if (cursorName == "idle" && !pushed) {
+ CursorMan.replaceCursor(_idleCursor.getSurface(), _idleCursor.getWidth(), _idleCursor.getHeight(), _idleCursor.getHotspotX(), _idleCursor.getHotspotY(), _idleCursor.getKeyColor(), false, _pixelFormat);
+ return;
+ }
+
+ for (int i = 0; i < NUM_CURSORS; ++i) {
+ if (_engine->getGameId() == GID_NEMESIS) {
+ if (cursorName.equals(_cursorNames[i])) {
+ _currentCursor = cursorName;
+
+ // ZNem uses a/b at the end of the file to signify not pushed/pushed respectively
+ Common::String pushedFlag = pushed ? "b" : "a";
+ Common::String name = Common::String::format("%s%s.zcr", _zNemCursorFileNames[i], pushedFlag.c_str());
+
+ changeCursor(ZorkCursor(name));
+ return;
+ }
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ if (cursorName.equals(_cursorNames[i])) {
+ _currentCursor = cursorName;
+
+ if (!pushed) {
+ changeCursor(ZorkCursor(_zgiCursorFileNames[i]));
+ } else {
+ // ZGI flips not pushed/pushed between a/c and b/d
+ // It flips the 4th character of the name
+ char buffer[25];
+ strcpy(buffer, _zgiCursorFileNames[i]);
+ buffer[3] += 2;
+ changeCursor(ZorkCursor(buffer));
+ }
+ return;
+ }
+ }
+ }
+
+ // If we get here, something went wrong
+ warning("No cursor found for identifier %s", cursorName.c_str());
+}
+
+void CursorManager::changeCursor(const ZorkCursor &cursor) {
+ CursorMan.replaceCursor(cursor.getSurface(), cursor.getWidth(), cursor.getHeight(), cursor.getHotspotX(), cursor.getHotspotY(), cursor.getKeyColor(), false, _pixelFormat);
+}
+
+void CursorManager::cursorDown(bool pushed) {
+ if (_cursorIsPushed == pushed)
+ return;
+
+ _cursorIsPushed = pushed;
+ changeCursor(_currentCursor, pushed);
+}
+
+void CursorManager::setLeftCursor() {
+ changeCursor("leftarrow");
+}
+
+void CursorManager::setRightCursor() {
+ changeCursor("rightarrow");
+}
+
+void CursorManager::setUpCursor() {
+ changeCursor("zuparrow");
+}
+
+void CursorManager::setDownCursor() {
+ changeCursor("downarrow");
+}
+
+void CursorManager::revertToIdle() {
+ _currentCursor = "idle";
+ if (!_cursorIsPushed)
+ CursorMan.replaceCursor(_idleCursor.getSurface(), _idleCursor.getWidth(), _idleCursor.getHeight(), _idleCursor.getHotspotX(), _idleCursor.getHotspotY(), _idleCursor.getKeyColor(), false, _pixelFormat);
+ else
+ changeCursor(_currentCursor, _cursorIsPushed);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/cursors/cursor_manager.h b/engines/zvision/cursors/cursor_manager.h
new file mode 100644
index 0000000000..e982a40188
--- /dev/null
+++ b/engines/zvision/cursors/cursor_manager.h
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_CURSOR_MANAGER_H
+#define ZVISION_CURSOR_MANAGER_H
+
+#include "zvision/cursors/cursor.h"
+
+#include "common/str.h"
+
+
+namespace Graphics {
+struct PixelFormat;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+/**
+ * Class to manage cursor changes. The actual changes have to be done
+ * through CursorMan. Otherwise the cursor will disappear after GMM
+ * or debug console.
+ * TODO: Figure out a way to get rid of the extraneous data copying due to having to use CursorMan
+ */
+class CursorManager {
+public:
+ CursorManager(ZVision *engine, const Graphics::PixelFormat *pixelFormat);
+
+private:
+ enum {
+ NUM_CURSORS = 18,
+ // WARNING: The index 11 is hardcoded. If you change the order of _cursorNames/_zgiCursorFileNames/_zNemCursorFileNames, you HAVE to change the index accordingly
+ IDLE_CURSOR_INDEX = 11
+ };
+
+ ZVision *_engine;
+ const Graphics::PixelFormat *_pixelFormat;
+ ZorkCursor _idleCursor;
+ Common::String _currentCursor;
+ bool _cursorIsPushed;
+
+ static const char *_cursorNames[];
+ static const char *_zgiCursorFileNames[];
+ static const char *_zNemCursorFileNames[];
+
+public:
+ /** Creates the idle cursor and shows it */
+ void initialize();
+
+ /**
+ * Parses a cursor name into a cursor file then creates and shows that cursor.
+ * It will use the current _isCursorPushed state to choose the correct cursor
+ *
+ * @param cursorName The name of a cursor. This *HAS* to correspond to one of the entries in _cursorNames[]
+ */
+ void changeCursor(const Common::String &cursorName);
+ /**
+ * Parses a cursor name into a cursor file then creates and shows that cursor.
+ *
+ * @param cursorName The name of a cursor. This *HAS* to correspond to one of the entries in _cursorNames[]
+ * @param pushed Should the cursor be pushed (true) or not pushed (false) (Another way to say it: down or up)
+ */
+ void changeCursor(const Common::String &cursorName, bool pushed);
+ /**
+ * Change the cursor to a certain push state. If the cursor is already in the specified push state, nothing will happen.
+ *
+ * @param pushed Should the cursor be pushed (true) or not pushed (false) (Another way to say it: down or up)
+ */
+ void cursorDown(bool pushed);
+
+ /** Set the cursor to 'Left Arrow'. It will retain the current _isCursorPushed state */
+ void setLeftCursor();
+ /** Set the cursor to 'Right Arrow'. It will retain the current _isCursorPushed state */
+ void setRightCursor();
+ /** Set the cursor to 'Up Arrow'. It will retain the current _isCursorPushed state */
+ void setUpCursor();
+ /** Set the cursor to 'Down Arrow'. It will retain the current _isCursorPushed state */
+ void setDownCursor();
+
+ /** Set the cursor to 'Idle'. It will retain the current _isCursorPushed state */
+ void revertToIdle();
+
+private:
+ /**
+ * Calls CursorMan.replaceCursor() using the data in cursor
+ *
+ * @param cursor The cursor to show
+ */
+ void changeCursor(const ZorkCursor &cursor);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
new file mode 100644
index 0000000000..49664935e1
--- /dev/null
+++ b/engines/zvision/detection.cpp
@@ -0,0 +1,272 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "base/plugins.h"
+
+#include "zvision/zvision.h"
+#include "zvision/detection.h"
+
+#include "common/translation.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/system.h"
+
+
+namespace ZVision {
+
+uint32 ZVision::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+Common::Language ZVision::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+} // End of namespace ZVision
+
+
+static const PlainGameDescriptor zVisionGames[] = {
+ {"zvision", "ZVision Game"},
+ {"znemesis", "Zork Nemesis: The Forbidden Lands"},
+ {"zgi", "Zork: Grand Inquisitor"},
+ {0, 0}
+};
+
+
+namespace ZVision {
+
+static const ZVisionGameDescription gameDescriptions[] = {
+
+ {
+ // Zork Nemesis English version
+ {
+ "znemesis",
+ 0,
+ AD_ENTRY1s("CSCR.ZFS", "88226e51a205d2e50c67a5237f3bd5f2", 2397741),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Grand Inquisitor English version
+ {
+ "zgi",
+ 0,
+ AD_ENTRY1s("SCRIPTS.ZFS", "81efd40ecc3d22531e211368b779f17f", 8336944),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ AD_TABLE_END_MARKER,
+ GID_NONE
+ }
+};
+
+} // End of namespace ZVision
+
+static const char *directoryGlobs[] = {
+ "znemscr",
+ 0
+};
+
+static const ExtraGuiOption ZVisionExtraGuiOption = {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+};
+
+class ZVisionMetaEngine : public AdvancedMetaEngine {
+public:
+ ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames) {
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ _singleid = "zvision";
+ }
+
+ virtual const char *getName() const {
+ return "ZVision";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "ZVision Activision (C) 1996";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
+ SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool ZVisionMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return false;
+ /*
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate) ||
+ (f == kSavesSupportPlayTime);
+ */
+}
+
+/*bool ZVision::ZVision::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}*/
+
+bool ZVisionMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const ZVision::ZVisionGameDescription *gd = (const ZVision::ZVisionGameDescription *)desc;
+ if (gd) {
+ *engine = new ZVision::ZVision(syst, gd);
+ }
+ return gd != 0;
+}
+
+const ExtraGuiOptions ZVisionMetaEngine::getExtraGuiOptions(const Common::String &target) const {
+ ExtraGuiOptions options;
+ options.push_back(ZVisionExtraGuiOption);
+ return options;
+}
+
+SaveStateList ZVisionMetaEngine::listSaves(const char *target) const {
+ //Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ /*ZVision::ZVision::SaveHeader header;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ Common::StringArray filenames;
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)*/
+
+ SaveStateList saveList;
+/* for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (ZVision::ZVision::readSaveHeader(in, false, header) == ZVision::ZVision::kRSHENoError) {
+ saveList.push_back(SaveStateDescriptor(slotNum, header.description));
+ }
+ delete in;
+ }
+ }
+ }*/
+
+ return saveList;
+}
+
+int ZVisionMetaEngine::getMaximumSaveSlot() const {
+ return 999;
+}
+
+void ZVisionMetaEngine::removeSaveState(const char *target, int slot) const {
+ /*
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+
+ saveFileMan->removeSavefile(filename.c_str());
+
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern += ".???";
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ // Rename every slot greater than the deleted slot,
+ if (slotNum > slot) {
+ saveFileMan->renameSavefile(file->c_str(), filename.c_str());
+ filename = ZVision::ZVision::getSavegameFilename(target, ++slot);
+ }
+ }
+ */
+}
+
+SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ /*
+ Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ ZVision::ZVision::SaveHeader header;
+ ZVision::ZVision::kReadSaveHeaderError error;
+
+ error = ZVision::ZVision::readSaveHeader(in, true, header);
+ delete in;
+
+ if (error == ZVision::ZVision::kRSHENoError) {
+ SaveStateDescriptor desc(slot, header.description);
+
+ desc.setThumbnail(header.thumbnail);
+
+ if (header.version > 0) {
+ int day = (header.saveDate >> 24) & 0xFF;
+ int month = (header.saveDate >> 16) & 0xFF;
+ int year = header.saveDate & 0xFFFF;
+
+ desc.setSaveDate(year, month, day);
+
+ int hour = (header.saveTime >> 16) & 0xFF;
+ int minutes = (header.saveTime >> 8) & 0xFF;
+
+ desc.setSaveTime(hour, minutes);
+
+ desc.setPlayTime(header.playTime * 1000);
+ }
+
+ return desc;
+ }
+ }
+ */
+
+ return SaveStateDescriptor();
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(ZVISION)
+ REGISTER_PLUGIN_DYNAMIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+#endif
diff --git a/engines/zvision/detection.h b/engines/zvision/detection.h
new file mode 100644
index 0000000000..34417601e8
--- /dev/null
+++ b/engines/zvision/detection.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef ZVISION_DETECTION_H
+#define ZVISION_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+
+namespace ZVision {
+
+enum ZVisionGameId {
+ GID_NONE = 0,
+ GID_NEMESIS = 1,
+ GID_GRANDINQUISITOR = 2
+};
+
+struct ZVisionGameDescription {
+ ADGameDescription desc;
+ ZVisionGameId gameId;
+};
+
+}
+
+#endif
diff --git a/engines/zvision/fonts/truetype_font.cpp b/engines/zvision/fonts/truetype_font.cpp
new file mode 100644
index 0000000000..f8910bfe06
--- /dev/null
+++ b/engines/zvision/fonts/truetype_font.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/fonts/truetype_font.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/system.h"
+
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/surface.h"
+
+
+namespace ZVision {
+
+TruetypeFont::TruetypeFont(ZVision *engine, int32 fontHeight)
+ : _engine(engine),
+ _fontHeight(fontHeight),
+ _font(0),
+ _lineHeight(0),
+ _maxCharWidth(0),
+ _maxCharHeight(0) {
+}
+
+TruetypeFont::~TruetypeFont(void) {
+ delete _font;
+}
+
+bool TruetypeFont::loadFile(const Common::String &filename) {
+ Common::File file;
+
+ bool fileOpened = false;
+ if (!Common::File::exists(filename)) {
+ debug("TTF font file %s was not found. Reverting to arial.ttf", filename.c_str());
+ fileOpened = file.open("arial.ttf");
+ } else {
+ fileOpened = file.open(filename);
+ }
+
+ if (!fileOpened) {
+ debug("TTF file could not be opened");
+ return false;
+ }
+
+ _font = Graphics::loadTTFFont(file, _fontHeight);
+ _lineHeight = _font->getFontHeight();
+
+ return true;
+}
+
+Graphics::Surface *TruetypeFont::drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) {
+ if (text.equals("")) {
+ return nullptr;
+ }
+
+ Graphics::Surface *surface = new Graphics::Surface();
+
+ if (!wrap) {
+ int width = MIN(_font->getStringWidth(text), maxWidth);
+ surface->create(width, _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ // TODO: Add better alpha support by getting the pixels from the backbuffer.
+ // However doing that requires some kind of caching system so future text doesn't try to use this text as it's alpha background.
+ surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);
+
+ _font->drawString(surface, text, 0, 0, maxWidth, textColor, align);
+ return surface;
+ }
+
+ Common::Array<Common::String> lines;
+ _font->wordWrapText(text, maxWidth, lines);
+
+ while (maxHeight > 0 && (int)lines.size() * _lineHeight > maxHeight) {
+ lines.pop_back();
+ }
+ if (lines.size() == 0) {
+ return nullptr;
+ }
+
+ surface->create(maxWidth, lines.size() * _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);
+
+ int heightOffset = 0;
+ for (Common::Array<Common::String>::iterator it = lines.begin(); it != lines.end(); it++) {
+ _font->drawString(surface, *it, 0, 0 + heightOffset, maxWidth, textColor, align);
+ heightOffset += _lineHeight;
+ }
+
+ return surface;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/fonts/truetype_font.h b/engines/zvision/fonts/truetype_font.h
new file mode 100644
index 0000000000..33f016cffd
--- /dev/null
+++ b/engines/zvision/fonts/truetype_font.h
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// This file is based on engines/wintermute/base/fonts/base_font_truetype.h/.cpp
+
+#ifndef ZVISION_TRUETYPE_FONT_H
+#define ZVISION_TRUETYPE_FONT_H
+
+#include "graphics/font.h"
+#include "graphics/pixelformat.h"
+
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class TruetypeFont {
+public:
+ TruetypeFont(ZVision *engine, int32 fontHeight);
+ ~TruetypeFont();
+
+private:
+ ZVision *_engine;
+ Graphics::Font *_font;
+ int _lineHeight;
+
+ size_t _maxCharWidth;
+ size_t _maxCharHeight;
+
+public:
+ int32 _fontHeight;
+
+public:
+ /**
+ * Loads a .ttf file into memory. This must be called
+ * before any calls to drawTextToSurface
+ *
+ * @param filename The file name of the .ttf file to load
+ */
+ bool loadFile(const Common::String &filename);
+ /**
+ * Renders the supplied text to a Surface using 0x0 as the
+ * background color.
+ *
+ * @param text The to render
+ * @param textColor The color to render the text with
+ * @param maxWidth The max width the text should take up.
+ * @param maxHeight The max height the text should take up.
+ * @param align The alignment of the text within the bounds of maxWidth
+ * @param wrap If true, any words extending past maxWidth will wrap to a new line. If false, ellipses will be rendered to show that the text didn't fit
+ * @return A Surface containing the rendered text
+ */
+ Graphics::Surface *drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
new file mode 100644
index 0000000000..f19df88935
--- /dev/null
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -0,0 +1,526 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/render_manager.h"
+
+#include "zvision/utility/lzss_read_stream.h"
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/stream.h"
+
+#include "engines/util.h"
+
+#include "graphics/decoders/tga.h"
+
+
+namespace ZVision {
+
+RenderManager::RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat)
+ : _system(system),
+ _workingWidth(workingWindow.width()),
+ _workingHeight(workingWindow.height()),
+ _screenCenterX(_workingWidth / 2),
+ _screenCenterY(_workingHeight / 2),
+ _workingWindow(workingWindow),
+ _pixelFormat(pixelFormat),
+ _backgroundWidth(0),
+ _backgroundHeight(0),
+ _backgroundInverseVelocity(0),
+ _backgroundOffset(0, 0),
+ _accumulatedVelocityMilliseconds(0),
+ _renderTable(_workingWidth, _workingHeight) {
+
+ _workingWindowBuffer.create(_workingWidth, _workingHeight, _pixelFormat);
+ _backBuffer.create(windowWidth, windowHeight, pixelFormat);
+}
+
+RenderManager::~RenderManager() {
+ _workingWindowBuffer.free();
+ _currentBackground.free();
+ _backBuffer.free();
+
+ for (AlphaEntryMap::iterator iter = _alphaDataEntries.begin(); iter != _alphaDataEntries.end(); ++iter) {
+ iter->_value.data->free();
+ delete iter->_value.data;
+ }
+}
+
+void RenderManager::update(uint deltaTimeInMillis) {
+ // An inverse velocity of 0 would be infinitely fast, so we'll let 0 mean no velocity.
+ if (_backgroundInverseVelocity != 0) {
+ _accumulatedVelocityMilliseconds += deltaTimeInMillis;
+
+ uint absVelocity = uint(abs(_backgroundInverseVelocity));
+
+ int numberOfSteps = 0;
+ while (_accumulatedVelocityMilliseconds >= absVelocity) {
+ _accumulatedVelocityMilliseconds -= absVelocity;
+ numberOfSteps++;
+ }
+
+ // Choose the direction of movement using the sign of the velocity
+ moveBackground(_backgroundInverseVelocity < 0 ? -numberOfSteps : numberOfSteps);
+ }
+}
+
+void RenderManager::renderBackbufferToScreen() {
+ if (!_workingWindowDirtyRect.isEmpty()) {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ _renderTable.mutateImage((uint16 *)_workingWindowBuffer.getPixels(), (uint16 *)_backBuffer.getBasePtr(_workingWindow.left + _workingWindowDirtyRect.left, _workingWindow.top + _workingWindowDirtyRect.top), _backBuffer.w, _workingWindowDirtyRect);
+ } else {
+ _backBuffer.copyRectToSurface(_workingWindowBuffer.getBasePtr(_workingWindowDirtyRect.left, _workingWindowDirtyRect.top), _workingWindowBuffer.pitch, _workingWindow.left + _workingWindowDirtyRect.left, _workingWindow.top + _workingWindowDirtyRect.top, _workingWindowDirtyRect.width(), _workingWindowDirtyRect.height());
+ }
+
+ // Translate the working window dirty rect to screen coords
+ _workingWindowDirtyRect.translate(_workingWindow.left, _workingWindow.top);
+ // Then extend the backbuffer dirty rect to contain it
+ if (_backBufferDirtyRect.isEmpty()) {
+ _backBufferDirtyRect = _workingWindowDirtyRect;
+ } else {
+ _backBufferDirtyRect.extend(_workingWindowDirtyRect);
+ }
+
+ // Clear the dirty rect
+ _workingWindowDirtyRect = Common::Rect();
+ }
+
+ // TODO: Add menu rendering
+
+ // Render alpha entries
+ processAlphaEntries();
+
+ if (!_backBufferDirtyRect.isEmpty()) {
+ _system->copyRectToScreen(_backBuffer.getBasePtr(_backBufferDirtyRect.left, _backBufferDirtyRect.top), _backBuffer.pitch, _backBufferDirtyRect.left, _backBufferDirtyRect.top, _backBufferDirtyRect.width(), _backBufferDirtyRect.height());
+ _backBufferDirtyRect = Common::Rect();
+ }
+}
+
+void RenderManager::processAlphaEntries() {
+ // TODO: Add dirty rectangling support. AKA only draw an entry if the _backbufferDirtyRect intersects/contains the entry Rect
+
+ for (AlphaEntryMap::iterator iter = _alphaDataEntries.begin(); iter != _alphaDataEntries.end(); ++iter) {
+ uint32 destOffset = 0;
+ uint32 sourceOffset = 0;
+ uint16 *backbufferPtr = (uint16 *)_backBuffer.getBasePtr(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top);
+ uint16 *entryPtr = (uint16 *)iter->_value.data->getPixels();
+
+ for (int32 y = 0; y < iter->_value.height; ++y) {
+ for (int32 x = 0; x < iter->_value.width; ++x) {
+ uint16 color = entryPtr[sourceOffset + x];
+ if (color != iter->_value.alphaColor) {
+ backbufferPtr[destOffset + x] = color;
+ }
+ }
+
+ destOffset += _backBuffer.w;
+ sourceOffset += iter->_value.width;
+ }
+
+ if (_backBufferDirtyRect.isEmpty()) {
+ _backBufferDirtyRect = Common::Rect(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top, iter->_value.destX + _workingWindow.left + iter->_value.width, iter->_value.destY + _workingWindow.top + iter->_value.height);
+ } else {
+ _backBufferDirtyRect.extend(Common::Rect(iter->_value.destX + _workingWindow.left, iter->_value.destY + _workingWindow.top, iter->_value.destX + _workingWindow.left + iter->_value.width, iter->_value.destY + _workingWindow.top + iter->_value.height));
+ }
+ }
+}
+
+void RenderManager::clearWorkingWindowTo555Color(uint16 color) {
+ uint32 workingWindowSize = _workingWidth * _workingHeight;
+ byte r, g, b;
+ Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(color, r, g, b);
+ uint16 colorIn565 = _pixelFormat.RGBToColor(r, g, b);
+ uint16 *bufferPtr = (uint16 *)_workingWindowBuffer.getPixels();
+
+ for (uint32 i = 0; i < workingWindowSize; ++i) {
+ bufferPtr[i] = colorIn565;
+ }
+}
+
+void RenderManager::renderSubRectToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap) {
+ int16 subRectX = 0;
+ int16 subRectY = 0;
+
+ // Take care of negative destinations
+ if (destinationX < 0) {
+ subRectX = -destinationX;
+ destinationX = 0;
+ } else if (destinationX >= surface.w) {
+ // Take care of extreme positive destinations
+ destinationX -= surface.w;
+ }
+
+ // Take care of negative destinations
+ if (destinationY < 0) {
+ subRectY = -destinationY;
+ destinationY = 0;
+ } else if (destinationY >= surface.h) {
+ // Take care of extreme positive destinations
+ destinationY -= surface.h;
+ }
+
+ if (wrap) {
+ _backgroundWidth = surface.w;
+ _backgroundHeight = surface.h;
+
+ if (destinationX > 0) {
+ // Move destinationX to 0
+ subRectX = surface.w - destinationX;
+ destinationX = 0;
+ }
+
+ if (destinationY > 0) {
+ // Move destinationY to 0
+ subRectY = surface.h - destinationY;
+ destinationY = 0;
+ }
+ }
+
+ // Clip subRect to working window bounds
+ Common::Rect subRect(subRectX, subRectY, subRectX + _workingWidth, subRectY + _workingHeight);
+
+ if (!wrap) {
+ // Clip to image bounds
+ subRect.clip(surface.w, surface.h);
+ }
+
+ // Check destRect for validity
+ if (!subRect.isValidRect() || subRect.isEmpty())
+ return;
+
+ copyRectToWorkingWindow((const uint16 *)surface.getBasePtr(subRect.left, subRect.top), destinationX, destinationY, surface.w, subRect.width(), subRect.height());
+}
+
+void RenderManager::renderImageToScreen(const Common::String &fileName, int16 destinationX, int16 destinationY, bool wrap) {
+ Graphics::Surface surface;
+ readImageToSurface(fileName, surface);
+
+ renderSubRectToScreen(surface, destinationX, destinationY, wrap);
+}
+
+void RenderManager::renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap) {
+ renderSubRectToScreen(surface, destinationX, destinationY, wrap);
+}
+
+void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {
+ Common::File file;
+
+ if (!file.open(fileName)) {
+ warning("Could not open file %s", fileName.c_str());
+ return;
+ }
+
+ // Read the magic number
+ // Some files are true TGA, while others are TGZ
+ uint32 fileType = file.readUint32BE();
+
+ uint32 imageWidth;
+ uint32 imageHeight;
+ Graphics::TGADecoder tga;
+ uint16 *buffer;
+ bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
+ // All ZVision images are in RGB 555
+ Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ destination.format = pixelFormat555;
+
+ bool isTGZ;
+
+ // Check for TGZ files
+ if (fileType == MKTAG('T', 'G', 'Z', '\0')) {
+ isTGZ = true;
+
+ // TGZ files have a header and then Bitmap data that is compressed with LZSS
+ uint32 decompressedSize = file.readSint32LE();
+ imageWidth = file.readSint32LE();
+ imageHeight = file.readSint32LE();
+
+ LzssReadStream lzssStream(&file);
+ buffer = (uint16 *)(new uint16[decompressedSize]);
+ lzssStream.read(buffer, decompressedSize);
+ } else {
+ isTGZ = false;
+
+ // Reset the cursor
+ file.seek(0);
+
+ // Decode
+ if (!tga.loadStream(file)) {
+ warning("Error while reading TGA image");
+ return;
+ }
+
+ Graphics::Surface tgaSurface = *(tga.getSurface());
+ imageWidth = tgaSurface.w;
+ imageHeight = tgaSurface.h;
+
+ buffer = (uint16 *)tgaSurface.getPixels();
+ }
+
+ // Flip the width and height if transposed
+ if (isTransposed) {
+ uint16 temp = imageHeight;
+ imageHeight = imageWidth;
+ imageWidth = temp;
+ }
+
+ // If the destination internal buffer is the same size as what we're copying into it,
+ // there is no need to free() and re-create
+ if (imageWidth != destination.w || imageHeight != destination.h) {
+ destination.create(imageWidth, imageHeight, pixelFormat555);
+ }
+
+ // If transposed, 'un-transpose' the data while copying it to the destination
+ // Otherwise, just do a simple copy
+ if (isTransposed) {
+ uint16 *dest = (uint16 *)destination.getPixels();
+
+ for (uint32 y = 0; y < imageHeight; ++y) {
+ uint32 columnIndex = y * imageWidth;
+
+ for (uint32 x = 0; x < imageWidth; ++x) {
+ dest[columnIndex + x] = buffer[x * imageHeight + y];
+ }
+ }
+ } else {
+ memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
+ }
+
+ // Cleanup
+ if (isTGZ) {
+ delete[] buffer;
+ } else {
+ tga.destroy();
+ }
+
+ // Convert in place to RGB 565 from RGB 555
+ destination.convertToInPlace(_pixelFormat);
+}
+
+void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height) {
+ uint32 destOffset = 0;
+ uint32 sourceOffset = 0;
+ uint16 *workingWindowBufferPtr = (uint16 *)_workingWindowBuffer.getBasePtr(destX, destY);
+
+ for (int32 y = 0; y < height; ++y) {
+ for (int32 x = 0; x < width; ++x) {
+ workingWindowBufferPtr[destOffset + x] = buffer[sourceOffset + x];
+ }
+
+ destOffset += _workingWidth;
+ sourceOffset += imageWidth;
+ }
+
+ if (_workingWindowDirtyRect.isEmpty()) {
+ _workingWindowDirtyRect = Common::Rect(destX, destY, destX + width, destY + height);
+ } else {
+ _workingWindowDirtyRect.extend(Common::Rect(destX, destY, destX + width, destY + height));
+ }
+
+ // TODO: Remove this from release. It's here to make sure code that uses this function clips their destinations correctly
+ assert(_workingWindowDirtyRect.width() <= _workingWidth && _workingWindowDirtyRect.height() <= _workingHeight);
+}
+
+void RenderManager::copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor, uint32 idNumber) {
+ AlphaDataEntry entry;
+ entry.alphaColor = alphaColor;
+ entry.data = new Graphics::Surface();
+ entry.data->create(width, height, _pixelFormat);
+ entry.destX = destX;
+ entry.destY = destY;
+ entry.width = width;
+ entry.height = height;
+
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+ uint16 *surfacePtr = (uint16 *)entry.data->getPixels();
+
+ for (int32 y = 0; y < height; ++y) {
+ for (int32 x = 0; x < width; ++x) {
+ surfacePtr[destOffset + x] = buffer[sourceOffset + x];
+ }
+
+ destOffset += width;
+ sourceOffset += imageWidth;
+ }
+
+ _alphaDataEntries[idNumber] = entry;
+}
+
+Common::Rect RenderManager::renderTextToWorkingWindow(uint32 idNumber, const Common::String &text, TruetypeFont *font, int destX, int destY, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) {
+ AlphaDataEntry entry;
+ entry.alphaColor = 0;
+ entry.destX = destX;
+ entry.destY = destY;
+
+ // Draw the text to the working window
+ entry.data = font->drawTextToSurface(text, textColor, maxWidth, maxHeight, align, wrap);
+ entry.width = entry.data->w;
+ entry.height = entry.data->h;
+
+ _alphaDataEntries[idNumber] = entry;
+
+ return Common::Rect(destX, destY, destX + entry.width, destY + entry.height);
+}
+
+const Common::Point RenderManager::screenSpaceToImageSpace(const Common::Point &point) {
+ // Convert from screen space to working window space
+ Common::Point newPoint(point - Common::Point(_workingWindow.left, _workingWindow.top));
+
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ newPoint = _renderTable.convertWarpedCoordToFlatCoord(newPoint);
+ }
+
+ if (state == RenderTable::PANORAMA) {
+ newPoint -= (Common::Point(_screenCenterX, 0) - _backgroundOffset);
+ } else if (state == RenderTable::TILT) {
+ newPoint -= (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ }
+
+ if (newPoint.x < 0)
+ newPoint.x += _backgroundWidth;
+ else if (newPoint.x >= _backgroundWidth)
+ newPoint.x -= _backgroundWidth;
+ if (newPoint.y < 0)
+ newPoint.y += _backgroundHeight;
+ else if (newPoint.y >= _backgroundHeight)
+ newPoint.y -= _backgroundHeight;
+
+ return newPoint;
+}
+
+const Common::Point RenderManager::imageSpaceToWorkingWindowSpace(const Common::Point &point) {
+ Common::Point newPoint(point);
+
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA) {
+ newPoint += (Common::Point(_screenCenterX, 0) - _backgroundOffset);
+ } else if (state == RenderTable::TILT) {
+ newPoint += (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ }
+
+ return newPoint;
+}
+
+bool RenderManager::clipRectToWorkingWindow(Common::Rect &rect) {
+ if (!_workingWindow.contains(rect)) {
+ return false;
+ }
+
+ // We can't clip against the actual working window rect because it's in screen space
+ // But rect is in working window space
+ rect.clip(_workingWidth, _workingHeight);
+ return true;
+}
+
+RenderTable *RenderManager::getRenderTable() {
+ return &_renderTable;
+}
+
+void RenderManager::setBackgroundImage(const Common::String &fileName) {
+ readImageToSurface(fileName, _currentBackground);
+
+ moveBackground(0);
+}
+
+void RenderManager::setBackgroundPosition(int offset) {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::TILT) {
+ _backgroundOffset.x = 0;
+ _backgroundOffset.y = offset;
+ } else if (state == RenderTable::PANORAMA) {
+ _backgroundOffset.x = offset;
+ _backgroundOffset.y = 0;
+ } else {
+ _backgroundOffset.x = 0;
+ _backgroundOffset.y = 0;
+ }
+}
+
+void RenderManager::setBackgroundVelocity(int velocity) {
+ // setBackgroundVelocity(0) will be called quite often, so make sure
+ // _backgroundInverseVelocity isn't already 0 to prevent an extraneous assignment
+ if (velocity == 0) {
+ if (_backgroundInverseVelocity != 0) {
+ _backgroundInverseVelocity = 0;
+ }
+ } else {
+ _backgroundInverseVelocity = 1000 / velocity;
+ }
+}
+
+void RenderManager::moveBackground(int offset) {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::TILT) {
+ _backgroundOffset += Common::Point(0, offset);
+
+ _backgroundOffset.y = CLIP<int16>(_backgroundOffset.y, _screenCenterY, (int16)_backgroundHeight - _screenCenterY);
+
+ renderImageToScreen(_currentBackground, 0, _screenCenterY - _backgroundOffset.y, true);
+ } else if (state == RenderTable::PANORAMA) {
+ _backgroundOffset += Common::Point(offset, 0);
+
+ if (_backgroundOffset.x <= -_backgroundWidth)
+ _backgroundOffset.x += _backgroundWidth;
+ else if (_backgroundOffset.x >= _backgroundWidth)
+ _backgroundOffset.x -= _backgroundWidth;
+
+ renderImageToScreen(_currentBackground, _screenCenterX - _backgroundOffset.x, 0, true);
+ } else {
+ renderImageToScreen(_currentBackground, 0, 0);
+ }
+}
+
+uint32 RenderManager::getCurrentBackgroundOffset() {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+
+ if (state == RenderTable::PANORAMA) {
+ return _backgroundOffset.x;
+ } else if (state == RenderTable::TILT) {
+ return _backgroundOffset.y;
+ } else {
+ return 0;
+ }
+}
+
+Graphics::Surface *RenderManager::tranposeSurface(const Graphics::Surface *surface) {
+ Graphics::Surface *tranposedSurface = new Graphics::Surface();
+ tranposedSurface->create(surface->h, surface->w, surface->format);
+
+ const uint16 *source = (const uint16 *)surface->getPixels();
+ uint16 *dest = (uint16 *)tranposedSurface->getPixels();
+
+ for (uint32 y = 0; y < tranposedSurface->h; ++y) {
+ uint32 columnIndex = y * tranposedSurface->w;
+
+ for (uint32 x = 0; x < tranposedSurface->w; ++x) {
+ dest[columnIndex + x] = source[x * surface->w + y];
+ }
+ }
+
+ return tranposedSurface;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
new file mode 100644
index 0000000000..cb71308bc3
--- /dev/null
+++ b/engines/zvision/graphics/render_manager.h
@@ -0,0 +1,328 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_RENDER_MANAGER_H
+#define ZVISION_RENDER_MANAGER_H
+
+#include "zvision/graphics/render_table.h"
+#include "zvision/fonts/truetype_font.h"
+
+#include "common/rect.h"
+#include "common/hashmap.h"
+
+#include "graphics/surface.h"
+
+
+class OSystem;
+
+namespace Common {
+class String;
+class SeekableReadStream;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace ZVision {
+
+class RenderManager {
+public:
+ RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat);
+ ~RenderManager();
+
+private:
+ struct AlphaDataEntry {
+ Graphics::Surface *data;
+ uint16 alphaColor;
+ uint16 destX;
+ uint16 destY;
+ uint16 width;
+ uint16 height;
+ };
+
+ typedef Common::HashMap<uint32, AlphaDataEntry> AlphaEntryMap;
+
+private:
+ OSystem *_system;
+ const Graphics::PixelFormat _pixelFormat;
+
+ // A buffer the exact same size as the workingWindow
+ // This buffer stores everything un-warped, then does a warp at the end of the frame
+ Graphics::Surface _workingWindowBuffer;
+ // A buffer representing the entire screen. Any graphical updates are first done with this buffer
+ // before actually being blitted to the screen
+ Graphics::Surface _backBuffer;
+ // A list of Alpha Entries that need to be blitted to the backbuffer
+ AlphaEntryMap _alphaDataEntries;
+
+ // A rectangle representing the portion of the working window where the pixels have been changed since last frame
+ Common::Rect _workingWindowDirtyRect;
+ // A rectangle representing the portion of the backbuffer where the pixels have been changed since last frame
+ Common::Rect _backBufferDirtyRect;
+
+ /** Width of the working window. Saved to prevent extraneous calls to _workingWindow.width() */
+ const int _workingWidth;
+ /** Height of the working window. Saved to prevent extraneous calls to _workingWindow.height() */
+ const int _workingHeight;
+ /** Center of the screen in the x direction */
+ const int _screenCenterX;
+ /** Center of the screen in the y direction */
+ const int _screenCenterY;
+
+ /**
+ * A Rectangle centered inside the actual window. All in-game coordinates
+ * are given in this coordinate space. Also, all images are clipped to the
+ * edges of this Rectangle
+ */
+ const Common::Rect _workingWindow;
+ /** Used to warp the background image */
+ RenderTable _renderTable;
+
+ Graphics::Surface _currentBackground;
+ /** The (x1,y1) coordinates of the subRectangle of the background that is currently displayed on the screen */
+ Common::Point _backgroundOffset;
+ /** The width of the current background image */
+ uint16 _backgroundWidth;
+ /** The height of the current background image */
+ uint16 _backgroundHeight;
+
+ /**
+ * The "velocity" at which the background image is panning. We actually store the inverse of velocity (ms/pixel instead of pixels/ms)
+ * because it allows you to accumulate whole pixels 'steps' instead of rounding pixels every frame
+ */
+ int _backgroundInverseVelocity;
+ /** Holds any 'leftover' milliseconds between frames */
+ uint _accumulatedVelocityMilliseconds;
+
+public:
+ void initialize();
+ /**
+ * Rotates the background image in accordance to the current _backgroundInverseVelocity
+ *
+ * @param deltaTimeInMillis The amount of time that has passed since the last frame
+ */
+ void update(uint deltaTimeInMillis);
+
+ /**
+ * Renders the current state of the backbuffer to the screen
+ */
+ void renderBackbufferToScreen();
+
+ /**
+ * Renders all AlphaEntries to the backbuffer
+ */
+ void processAlphaEntries();
+ /**
+ * Clears the AlphaEntry list
+ */
+ void clearAlphaEntries() { _alphaDataEntries.clear(); }
+ /**
+ * Removes a specific AlphaEntry from the list
+ *
+ * @param idNumber The id number identifing the AlphaEntry
+ */
+ void removeAlphaEntry(uint32 idNumber) { _alphaDataEntries.erase(idNumber); }
+
+ /**
+ * Copies a sub-rectangle of a buffer to the working window
+ *
+ * @param buffer The pixel data to copy to the working window
+ * @param destX The X destination in the working window where the subRect of data should be put
+ * @param destY The Y destination in the working window where the subRect of data should be put
+ * @param imageWidth The width of the source image
+ * @param width The width of the sub rectangle
+ * @param height The height of the sub rectangle
+ */
+ void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height);
+ /**
+ * Copies a sub-rectangle of a buffer to the working window with binary alpha support.
+ *
+ * @param buffer The pixel data to copy to the working window
+ * @param destX The X destination in the working window where the subRect of data should be put
+ * @param destY The Y destination in the working window where the subRect of data should be put
+ * @param imageWidth The width of the source image
+ * @param width The width of the sub rectangle
+ * @param height The height of the sub rectangle
+ * @param alphaColor The color to interpret as meaning 'transparent'
+ * @param idNumber A unique identifier for the data being copied over.
+ */
+ void copyRectToWorkingWindow(const uint16 *buffer, int32 destX, int32 destY, int32 imageWidth, int32 width, int32 height, int16 alphaColor, uint32 idNumber);
+
+ /**
+ * Renders the supplied text to the working window
+ *
+ * @param idNumber A unique identifier for the text
+ * @param text The text to be rendered
+ * @param font The font to use to render the text
+ * @param destX The X destination in the working window where the text should be rendered
+ * @param destY The Y destination in the working window where the text should be rendered
+ * @param textColor The color to render the text with (in RBG 565)
+ * @param maxWidth The max width the text should take up.
+ * @param maxHeight The max height the text should take up.
+ * @param align The alignment of the text within the bounds of maxWidth
+ * @param wrap If true, any words extending past maxWidth will wrap to a new line. If false, ellipses will be rendered to show that the text didn't fit
+ * @return A rectangle representing where the text was drawn in the working window
+ */
+ Common::Rect renderTextToWorkingWindow(uint32 idNumber, const Common::String &text, TruetypeFont *font, int destX, int destY, uint16 textColor, int maxWidth, int maxHeight = -1, Graphics::TextAlign align = Graphics::kTextAlignLeft, bool wrap = true);
+
+ /**
+ * Fills the entire workingWindow with the specified color. Internally, the color
+ * will be converted to RGB 565 and then blitted.
+ *
+ * @param color The color to fill the working window with. (In RGB 555)
+ */
+ void clearWorkingWindowTo555Color(uint16 color);
+
+ /**
+ * Blits the image or a portion of the image to the backbuffer. Actual screen updates won't happen until the end of the frame.
+ * The image will be clipped to fit inside the working window. Coords are in working window space, not screen space!
+ *
+ * @param fileName Name of the image file
+ * @param destinationX X position where the image should be put. Coords are in working window space, not screen space!
+ * @param destinationY Y position where the image should be put. Coords are in working window space, not screen space!
+ */
+ void renderImageToScreen(const Common::String &fileName, int16 destinationX, int16 destinationY, bool wrap = false);
+
+ /**
+ * Blits the image or a portion of the image to the backbuffer. Actual screen updates won't happen until the end of the frame.
+ * The image will be clipped to fit inside the working window. Coords are in working window space, not screen space!
+ *
+ * @param stream Surface to read the image data from
+ * @param destinationX X position where the image should be put. Coords are in working window space, not screen space!
+ * @param destinationY Y position where the image should be put. Coords are in working window space, not screen space!
+ */
+ void renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap = false);
+
+ /**
+ * Sets the current background image to be used by the RenderManager and immediately
+ * blits it to the screen. (It won't show up until the end of the frame)
+ *
+ * @param fileName The name of the image file
+ */
+ void setBackgroundImage(const Common::String &fileName);
+
+ /**
+ * Set the background position (_backgroundOffset). If the current RenderState is PANORAMA, the offset
+ * will be in the horizontal direction. If the current RenderState is TILT, the offset will be in the
+ * vertical direction.
+ *
+ * This method will not render anything on the screen. So if nothing else is called that renders the
+ * background, the change won't be seen until next frame.
+ *
+ * @param offset The amount to offset the background
+ */
+ void setBackgroundPosition(int offset);
+
+ /**
+ * Set the background scroll velocity. Negative velocities correspond to left / up scrolling and
+ * positive velocities correspond to right / down scrolling
+ *
+ * @param velocity Velocity
+ */
+ void setBackgroundVelocity(int velocity);
+
+ /**
+ * Converts a point in screen coordinate space to image coordinate space
+ *
+ * @param point Point in screen coordinate space
+ * @return Point in image coordinate space
+ */
+ const Common::Point screenSpaceToImageSpace(const Common::Point &point);
+ /**
+ * Converts a point in image coordinate space to ***PRE-WARP***
+ * working window coordinate space
+ *
+ * @param point Point in image coordinate space
+ * @return Point in PRE-WARP working window coordinate space
+ */
+ const Common::Point imageSpaceToWorkingWindowSpace(const Common::Point &point);
+
+ /**
+ * Clip a rectangle to the working window. If it returns false, the original rect
+ * is not inside the working window.
+ *
+ * @param rect The rectangle to clip against the working window
+ * @return Is rect at least partially inside the working window (true) or completely outside (false)
+ */
+ bool clipRectToWorkingWindow(Common::Rect &rect);
+
+ RenderTable *getRenderTable();
+ uint32 getCurrentBackgroundOffset();
+ const Graphics::Surface *getBackBuffer() { return &_backBuffer; }
+
+ /**
+ * Creates a copy of surface and transposes the data.
+ *
+ * Note: The user is responsible for calling free() on the returned surface
+ * and then deleting it
+ *
+ * @param surface The data to be transposed
+ * @return A copy of the surface with the data transposed
+ */
+ static Graphics::Surface *tranposeSurface(const Graphics::Surface *surface);
+
+private:
+ /**
+ * Renders a subRectangle of an image to the backbuffer. The destinationRect and SubRect
+ * will be clipped to image bound and to working window bounds
+ *
+ * @param buffer Pointer to (0, 0) of the image data
+ * @param imageWidth The width of the original image (not of the subRectangle)
+ * @param imageHeight The width of the original image (not of the subRectangle)
+ * @param horizontalPitch The horizontal pitch of the original image
+ * @param destinationX The x coordinate (in working window space) of where to put the final image
+ * @param destinationY The y coordinate (in working window space) of where to put the final image
+ * @param subRectangle A rectangle representing the part of the image that should be rendered
+ * @param wrap Should the image wrap (tile) if it doesn't completely fill the screen?
+ */
+ void renderSubRectToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap);
+
+ /**
+ * Reads an image file pixel data into a Surface buffer. In the process
+ * it converts the pixel data from RGB 555 to RGB 565. Also, if the image
+ * is transposed, it will un-transpose the pixel data. The function will
+ * call destination::create() if the dimensions of destination do not match
+ * up with the dimensions of the image.
+ *
+ * @param fileName The name of a .tga file
+ * @param destination A reference to the Surface to store the pixel data in
+ */
+ void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination);
+
+ /**
+ * Move the background image by an offset. If we are currently in Panorama mode,
+ * the offset will correspond to a horizontal motion. If we are currently in Tilt mode,
+ * the offset will correspond to a vertical motion. This function should not be called
+ * if we are in Flat mode.
+ *
+ * The RenderManager will take care of wrapping the image.
+ * Ex: If the image has width 1400px, it is legal to offset 1500px.
+ *
+ * @param offset The amount to move the background
+ */
+ void moveBackground(int offset);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/graphics/render_table.cpp b/engines/zvision/graphics/render_table.cpp
new file mode 100644
index 0000000000..ffd42e6a60
--- /dev/null
+++ b/engines/zvision/graphics/render_table.cpp
@@ -0,0 +1,240 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/render_table.h"
+
+#include "common/rect.h"
+
+#include "graphics/colormasks.h"
+
+
+namespace ZVision {
+
+RenderTable::RenderTable(uint numColumns, uint numRows)
+ : _numRows(numRows),
+ _numColumns(numColumns),
+ _renderState(FLAT) {
+ assert(numRows != 0 && numColumns != 0);
+
+ _internalBuffer = new Common::Point[numRows * numColumns];
+}
+
+RenderTable::~RenderTable() {
+ delete[] _internalBuffer;
+}
+
+void RenderTable::setRenderState(RenderState newState) {
+ _renderState = newState;
+
+ switch (newState) {
+ case PANORAMA:
+ _panoramaOptions.fieldOfView = 27.0f;
+ _panoramaOptions.linearScale = 0.55f;
+ _panoramaOptions.reverse = false;
+ break;
+ case TILT:
+ _tiltOptions.fieldOfView = 27.0f;
+ _tiltOptions.linearScale = 0.55f;
+ _tiltOptions.reverse = false;
+ break;
+ case FLAT:
+ // Intentionally left empty
+ break;
+ }
+}
+
+const Common::Point RenderTable::convertWarpedCoordToFlatCoord(const Common::Point &point) {
+ // If we're outside the range of the RenderTable, no warping is happening. Return the maximum image coords
+ if (point.x >= (int16)_numColumns || point.y >= (int16)_numRows || point.x < 0 || point.y < 0) {
+ int16 x = CLIP<int16>(point.x, 0, (int16)_numColumns);
+ int16 y = CLIP<int16>(point.y, 0, (int16)_numRows);
+ return Common::Point(x, y);
+ }
+
+ uint32 index = point.y * _numColumns + point.x;
+
+ Common::Point newPoint(point);
+ newPoint.x += _internalBuffer[index].x;
+ newPoint.y += _internalBuffer[index].y;
+
+ return newPoint;
+}
+
+uint16 mixTwoRGB(uint16 colorOne, uint16 colorTwo, float percentColorOne) {
+ assert(percentColorOne < 1.0f);
+
+ float rOne = float((colorOne & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
+ float rTwo = float((colorTwo & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
+ float gOne = float((colorOne & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
+ float gTwo = float((colorTwo & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
+ float bOne = float((colorOne & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
+ float bTwo = float((colorTwo & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
+
+ float rFinal = rOne * percentColorOne + rTwo * (1.0f - percentColorOne);
+ float gFinal = gOne * percentColorOne + gTwo * (1.0f - percentColorOne);
+ float bFinal = bOne * percentColorOne + bTwo * (1.0f - percentColorOne);
+
+ uint16 returnColor = (byte(rFinal + 0.5f) << Graphics::ColorMasks<555>::kRedShift) |
+ (byte(gFinal + 0.5f) << Graphics::ColorMasks<555>::kGreenShift) |
+ (byte(bFinal + 0.5f) << Graphics::ColorMasks<555>::kBlueShift);
+
+ return returnColor;
+}
+
+void RenderTable::mutateImage(uint16 *sourceBuffer, uint16* destBuffer, uint32 destWidth, const Common::Rect &subRect) {
+ uint32 destOffset = 0;
+
+ for (int16 y = subRect.top; y < subRect.bottom; ++y) {
+ uint32 sourceOffset = y * _numColumns;
+
+ for (int16 x = subRect.left; x < subRect.right; ++x) {
+ uint32 normalizedX = x - subRect.left;
+ uint32 index = sourceOffset + x;
+
+ // RenderTable only stores offsets from the original coordinates
+ uint32 sourceYIndex = y + _internalBuffer[index].y;
+ uint32 sourceXIndex = x + _internalBuffer[index].x;
+
+ destBuffer[destOffset + normalizedX] = sourceBuffer[sourceYIndex * _numColumns + sourceXIndex];
+ }
+
+ destOffset += destWidth;
+ }
+}
+
+void RenderTable::generateRenderTable() {
+ switch (_renderState) {
+ case ZVision::RenderTable::PANORAMA:
+ generatePanoramaLookupTable();
+ break;
+ case ZVision::RenderTable::TILT:
+ generateTiltLookupTable();
+ break;
+ case ZVision::RenderTable::FLAT:
+ // Intentionally left empty
+ break;
+ }
+}
+
+void RenderTable::generatePanoramaLookupTable() {
+ memset(_internalBuffer, 0, _numRows * _numColumns * sizeof(uint16));
+
+ float halfWidth = (float)_numColumns / 2.0f;
+ float halfHeight = (float)_numRows / 2.0f;
+
+ float fovInRadians = (_panoramaOptions.fieldOfView * M_PI / 180.0f);
+ float cylinderRadius = halfHeight / tan(fovInRadians);
+
+ for (uint x = 0; x < _numColumns; ++x) {
+ // Add an offset of 0.01 to overcome zero tan/atan issue (vertical line on half of screen)
+ // Alpha represents the horizontal angle between the viewer at the center of a cylinder and x
+ float alpha = atan(((float)x - halfWidth + 0.01f) / cylinderRadius);
+
+ // To get x in cylinder coordinates, we just need to calculate the arc length
+ // We also scale it by _panoramaOptions.linearScale
+ int32 xInCylinderCoords = int32(floor((cylinderRadius * _panoramaOptions.linearScale * alpha) + halfWidth));
+
+ float cosAlpha = cos(alpha);
+
+ for (uint y = 0; y < _numRows; ++y) {
+ // To calculate y in cylinder coordinates, we can do similar triangles comparison,
+ // comparing the triangle from the center to the screen and from the center to the edge of the cylinder
+ int32 yInCylinderCoords = int32(floor(halfHeight + ((float)y - halfHeight) * cosAlpha));
+
+ uint32 index = y * _numColumns + x;
+
+ // Only store the (x,y) offsets instead of the absolute positions
+ _internalBuffer[index].x = xInCylinderCoords - x;
+ _internalBuffer[index].y = yInCylinderCoords - y;
+ }
+ }
+}
+
+void RenderTable::generateTiltLookupTable() {
+ float halfWidth = (float)_numColumns / 2.0f;
+ float halfHeight = (float)_numRows / 2.0f;
+
+ float fovInRadians = (_tiltOptions.fieldOfView * M_PI / 180.0f);
+ float cylinderRadius = halfWidth / tan(fovInRadians);
+
+ for (uint y = 0; y < _numRows; ++y) {
+
+ // Add an offset of 0.01 to overcome zero tan/atan issue (horizontal line on half of screen)
+ // Alpha represents the vertical angle between the viewer at the center of a cylinder and y
+ float alpha = atan(((float)y - halfHeight + 0.01f) / cylinderRadius);
+
+ // To get y in cylinder coordinates, we just need to calculate the arc length
+ // We also scale it by _tiltOptions.linearScale
+ int32 yInCylinderCoords = int32(floor((cylinderRadius * _tiltOptions.linearScale * alpha) + halfHeight));
+
+ float cosAlpha = cos(alpha);
+ uint32 columnIndex = y * _numColumns;
+
+ for (uint x = 0; x < _numColumns; ++x) {
+ // To calculate x in cylinder coordinates, we can do similar triangles comparison,
+ // comparing the triangle from the center to the screen and from the center to the edge of the cylinder
+ int32 xInCylinderCoords = int32(floor(halfWidth + ((float)x - halfWidth) * cosAlpha));
+
+ uint32 index = columnIndex + x;
+
+ // Only store the (x,y) offsets instead of the absolute positions
+ _internalBuffer[index].x = xInCylinderCoords - x;
+ _internalBuffer[index].y = yInCylinderCoords - y;
+ }
+ }
+}
+
+void RenderTable::setPanoramaFoV(float fov) {
+ assert(fov > 0.0f);
+
+ _panoramaOptions.fieldOfView = fov;
+}
+
+void RenderTable::setPanoramaScale(float scale) {
+ assert(scale > 0.0f);
+
+ _panoramaOptions.linearScale = scale;
+}
+
+void RenderTable::setPanoramaReverse(bool reverse) {
+ _panoramaOptions.reverse = reverse;
+}
+
+void RenderTable::setTiltFoV(float fov) {
+ assert(fov > 0.0f);
+
+ _tiltOptions.fieldOfView = fov;
+}
+
+void RenderTable::setTiltScale(float scale) {
+ assert(scale > 0.0f);
+
+ _tiltOptions.linearScale = scale;
+}
+
+void RenderTable::setTiltReverse(bool reverse) {
+ _tiltOptions.reverse = reverse;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_table.h b/engines/zvision/graphics/render_table.h
new file mode 100644
index 0000000000..898091193a
--- /dev/null
+++ b/engines/zvision/graphics/render_table.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_RENDER_TABLE_H
+#define ZVISION_RENDER_TABLE_H
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class RenderTable {
+public:
+ RenderTable(uint numRows, uint numColumns);
+ ~RenderTable();
+
+public:
+ enum RenderState {
+ PANORAMA,
+ TILT,
+ FLAT
+ };
+
+private:
+ uint _numColumns, _numRows;
+ Common::Point *_internalBuffer;
+ RenderState _renderState;
+
+ struct {
+ float fieldOfView;
+ float linearScale;
+ bool reverse;
+ } _panoramaOptions;
+
+ // TODO: See if tilt and panorama need to have separate options
+ struct {
+ float fieldOfView;
+ float linearScale;
+ bool reverse;
+ } _tiltOptions;
+
+public:
+ RenderState getRenderState() { return _renderState; }
+ void setRenderState(RenderState newState);
+
+ const Common::Point convertWarpedCoordToFlatCoord(const Common::Point &point);
+
+ void mutateImage(uint16 *sourceBuffer, uint16* destBuffer, uint32 destWidth, const Common::Rect &subRect);
+ void generateRenderTable();
+
+ void setPanoramaFoV(float fov);
+ void setPanoramaScale(float scale);
+ void setPanoramaReverse(bool reverse);
+
+ void setTiltFoV(float fov);
+ void setTiltScale(float scale);
+ void setTiltReverse(bool reverse);
+
+private:
+ void generatePanoramaLookupTable();
+ void generateTiltLookupTable();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/inventory/inventory_manager.h b/engines/zvision/inventory/inventory_manager.h
new file mode 100644
index 0000000000..ae6d116b18
--- /dev/null
+++ b/engines/zvision/inventory/inventory_manager.h
@@ -0,0 +1,28 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_INVENTORY_MANAGER_H
+#define ZVISION_INVENTORY_MANAGER_H
+
+// TODO: Implement InventoryManager
+
+#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
new file mode 100644
index 0000000000..4cf9c989cd
--- /dev/null
+++ b/engines/zvision/module.mk
@@ -0,0 +1,43 @@
+MODULE := engines/zvision
+
+MODULE_OBJS := \
+ animation/rlf_animation.o \
+ archives/zfs_archive.o \
+ core/console.o \
+ core/events.o \
+ core/save_manager.o \
+ cursors/cursor.o \
+ cursors/cursor_manager.o \
+ detection.o \
+ fonts/truetype_font.o \
+ graphics/render_manager.o \
+ graphics/render_table.o \
+ scripting/actions.o \
+ scripting/control.o \
+ scripting/controls/animation_control.o \
+ scripting/controls/input_control.o \
+ scripting/controls/lever_control.o \
+ scripting/controls/push_toggle_control.o \
+ scripting/controls/timer_node.o \
+ scripting/scr_file_handling.o \
+ scripting/script_manager.o \
+ sound/zork_raw.o \
+ strings/string_manager.o \
+ utility/clock.o \
+ utility/lzss_read_stream.o \
+ utility/single_value_container.o \
+ utility/utility.o \
+ video/video.o \
+ video/zork_avi_decoder.o \
+ zvision.o
+
+MODULE_DIRS += \
+ engines/zvision
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_ZVISION), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
new file mode 100644
index 0000000000..878fa752d5
--- /dev/null
+++ b/engines/zvision/scripting/actions.cpp
@@ -0,0 +1,401 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/actions.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/sound/zork_raw.h"
+#include "zvision/video/zork_avi_decoder.h"
+#include "zvision/scripting/controls/timer_node.h"
+#include "zvision/scripting/controls/animation_control.h"
+
+#include "common/file.h"
+
+#include "audio/decoders/wave.h"
+
+
+namespace ZVision {
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAdd
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAdd::ActionAdd(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u,%u)", &_key, &_value);
+}
+
+bool ActionAdd::execute(ZVision *engine) {
+ engine->getScriptManager()->addToStateValue(_key, _value);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAssign
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAssign::ActionAssign(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u, %u)", &_key, &_value);
+}
+
+bool ActionAssign::execute(ZVision *engine) {
+ engine->getScriptManager()->setStateValue(_key, _value);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAttenuate
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAttenuate::ActionAttenuate(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u, %d)", &_key, &_attenuation);
+}
+
+bool ActionAttenuate::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionChangeLocation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionChangeLocation::ActionChangeLocation(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%c,%c,%c%c,%u)", &_world, &_room, &_node, &_view, &_offset);
+}
+
+bool ActionChangeLocation::execute(ZVision *engine) {
+ // We can't directly call ScriptManager::ChangeLocationIntern() because doing so clears all the Puzzles, and thus would corrupt the current puzzle checking
+ engine->getScriptManager()->changeLocation(_world, _room, _node, _view, _offset);
+ // Tell the puzzle system to stop checking any more puzzles
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionCrossfade
+//////////////////////////////////////////////////////////////////////////////
+
+ActionCrossfade::ActionCrossfade(const Common::String &line) {
+ sscanf(line.c_str(),
+ "%*[^(](%u %u %u %u %u %u %u)",
+ &_keyOne, &_keyTwo, &_oneStartVolume, &_twoStartVolume, &_oneEndVolume, &_twoEndVolume, &_timeInMillis);
+}
+
+bool ActionCrossfade::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionDisableControl
+//////////////////////////////////////////////////////////////////////////////
+
+ActionDisableControl::ActionDisableControl(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u)", &_key);
+}
+
+bool ActionDisableControl::execute(ZVision *engine) {
+ debug("Disabling control %u", _key);
+
+ ScriptManager *scriptManager = engine->getScriptManager();
+ scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) | ScriptManager::DISABLED);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionEnableControl
+//////////////////////////////////////////////////////////////////////////////
+
+ActionEnableControl::ActionEnableControl(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u)", &_key);
+}
+
+bool ActionEnableControl::execute(ZVision *engine) {
+ debug("Enabling control %u", _key);
+
+ ScriptManager *scriptManager = engine->getScriptManager();
+ scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) & ~ScriptManager::DISABLED);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionMusic
+//////////////////////////////////////////////////////////////////////////////
+
+ActionMusic::ActionMusic(const Common::String &line) : _volume(255) {
+ uint type;
+ char fileNameBuffer[25];
+ uint loop;
+ uint volume = 255;
+
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u %25s %u %u)", &_key, &type, fileNameBuffer, &loop, &volume);
+
+ // type 4 are midi sound effect files
+ if (type == 4) {
+ _soundType = Audio::Mixer::kSFXSoundType;
+ _fileName = Common::String::format("midi/%s/%u.wav", fileNameBuffer, loop);
+ _loop = false;
+ } else {
+ // TODO: See what the other types are so we can specify the correct Mixer::SoundType. In the meantime use kPlainSoundType
+ _soundType = Audio::Mixer::kPlainSoundType;
+ _fileName = Common::String(fileNameBuffer);
+ _loop = loop == 1 ? true : false;
+ }
+
+ // Volume is optional. If it doesn't appear, assume full volume
+ if (volume != 255) {
+ // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255]
+ _volume = volume * 255 / 100;
+ }
+}
+
+bool ActionMusic::execute(ZVision *engine) {
+ Audio::RewindableAudioStream *audioStream;
+
+ if (_fileName.contains(".wav")) {
+ Common::File *file = new Common::File();
+ if (file->open(_fileName)) {
+ audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ } else {
+ warning("Unable to open %s", _fileName.c_str());
+ return false;
+ }
+ } else {
+ audioStream = makeRawZorkStream(_fileName, engine);
+ }
+
+ if (_loop) {
+ Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
+ engine->_mixer->playStream(_soundType, 0, loopingAudioStream, -1, _volume);
+ } else {
+ engine->_mixer->playStream(_soundType, 0, audioStream, -1, _volume);
+ }
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPreloadAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPreloadAnimation::ActionPreloadAnimation(const Common::String &line) {
+ char fileName[25];
+
+ // The two %*u are always 0 and dont seem to have a use
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%25s %*u %*u %u %u)", &_key, fileName, &_mask, &_framerate);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionPreloadAnimation::execute(ZVision *engine) {
+ // TODO: We ignore the mask and framerate atm. Mask refers to a key color used for binary alpha. We assume the framerate is the default framerate embedded in the videos
+
+ // TODO: Check if the Control already exists
+
+ // Create the control, but disable it until PlayPreload is called
+ ScriptManager *scriptManager = engine->getScriptManager();
+ scriptManager->addControl(new AnimationControl(engine, _key, _fileName));
+ scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) | ScriptManager::DISABLED);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPlayAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPlayAnimation::ActionPlayAnimation(const Common::String &line) {
+ char fileName[25];
+
+ // The two %*u are always 0 and dont seem to have a use
+ sscanf(line.c_str(),
+ "%*[^:]:%*[^:]:%u(%25s %u %u %u %u %u %u %u %*u %*u %u %u)",
+ &_key, fileName, &_x, &_y, &_width, &_height, &_start, &_end, &_loopCount, &_mask, &_framerate);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionPlayAnimation::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPlayPreloadAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(const Common::String &line) {
+ sscanf(line.c_str(),
+ "%*[^:]:%*[^:]:%u(%u %u %u %u %u %u %u %u)",
+ &_animationKey, &_controlKey, &_x1, &_y1, &_x2, &_y2, &_startFrame, &_endFrame, &_loopCount);
+}
+
+bool ActionPlayPreloadAnimation::execute(ZVision *engine) {
+ // Find the control
+ AnimationControl *control = (AnimationControl *)engine->getScriptManager()->getControl(_controlKey);
+
+ // Set the needed values within the control
+ control->setAnimationKey(_animationKey);
+ control->setLoopCount(_loopCount);
+ control->setXPos(_x1);
+ control->setYPost(_y1);
+
+ // Enable the control. ScriptManager will take care of the rest
+ control->enable();
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionQuit
+//////////////////////////////////////////////////////////////////////////////
+
+bool ActionQuit::execute(ZVision *engine) {
+ engine->quitGame();
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionRandom
+//////////////////////////////////////////////////////////////////////////////
+
+ActionRandom::ActionRandom(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u, %u)", &_key, &_max);
+}
+
+bool ActionRandom::execute(ZVision *engine) {
+ uint randNumber = engine->getRandomSource()->getRandomNumber(_max);
+ engine->getScriptManager()->setStateValue(_key, randNumber);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionSetPartialScreen
+//////////////////////////////////////////////////////////////////////////////
+
+ActionSetPartialScreen::ActionSetPartialScreen(const Common::String &line) {
+ char fileName[25];
+ uint color;
+
+ sscanf(line.c_str(), "%*[^(](%u %u %25s %*u %u)", &_x, &_y, fileName, &color);
+
+ _fileName = Common::String(fileName);
+
+ if (color > 0xFFFF) {
+ warning("Background color for ActionSetPartialScreen is bigger than a uint16");
+ }
+ _backgroundColor = color;
+}
+
+bool ActionSetPartialScreen::execute(ZVision *engine) {
+ RenderManager *renderManager = engine->getRenderManager();
+
+ if (_backgroundColor > 0) {
+ renderManager->clearWorkingWindowTo555Color(_backgroundColor);
+ }
+ renderManager->renderImageToScreen(_fileName, _x, _y);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionSetScreen
+//////////////////////////////////////////////////////////////////////////////
+
+ActionSetScreen::ActionSetScreen(const Common::String &line) {
+ char fileName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", fileName);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionSetScreen::execute(ZVision *engine) {
+ engine->getRenderManager()->setBackgroundImage(_fileName);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionStreamVideo
+//////////////////////////////////////////////////////////////////////////////
+
+ActionStreamVideo::ActionStreamVideo(const Common::String &line) {
+ char fileName[25];
+ uint skippable;
+
+ sscanf(line.c_str(), "%*[^(](%25s %u %u %u %u %u %u)", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skippable);
+
+ _fileName = Common::String(fileName);
+ _skippable = (skippable == 0) ? false : true;
+}
+
+bool ActionStreamVideo::execute(ZVision *engine) {
+ ZorkAVIDecoder decoder;
+ if (!decoder.loadFile(_fileName)) {
+ return true;
+ }
+
+ Common::Rect destRect;
+ if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) {
+ destRect = Common::Rect(_x1, _y1, _x2, _y2);
+ }
+
+ engine->playVideo(decoder, destRect, _skippable);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionTimer
+//////////////////////////////////////////////////////////////////////////////
+
+ActionTimer::ActionTimer(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u)", &_key, &_time);
+}
+
+bool ActionTimer::execute(ZVision *engine) {
+ engine->getScriptManager()->addControl(new TimerNode(engine, _key, _time));
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
new file mode 100644
index 0000000000..afa3e3a2ac
--- /dev/null
+++ b/engines/zvision/scripting/actions.h
@@ -0,0 +1,346 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ACTIONS_H
+#define ZVISION_ACTIONS_H
+
+#include "common/str.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+// Forward declaration of ZVision. This file is included before ZVision is declared
+class ZVision;
+
+/**
+ * The base class that represents any action that a Puzzle can take.
+ * This class is purely virtual.
+ */
+class ResultAction {
+public:
+ virtual ~ResultAction() {}
+ /**
+ * This is called by the script system whenever a Puzzle's criteria are found to be true.
+ * It should execute any necessary actions and return a value indicating whether the script
+ * system should continue to test puzzles. In 99% of cases this will be 'true'.
+ *
+ * @param engine A pointer to the base engine so the ResultAction can access all the necessary methods
+ * @return Should the script system continue to test any remaining puzzles (true) or immediately break and go on to the next frame (false)
+ */
+ virtual bool execute(ZVision *engine) = 0;
+};
+
+
+// The different types of actions
+// DEBUG,
+// DISABLE_CONTROL,
+// DISABLE_VENUS,
+// DISPLAY_MESSAGE,
+// DISSOLVE,
+// DISTORT,
+// ENABLE_CONTROL,
+// FLUSH_MOUSE_EVENTS,
+// INVENTORY,
+// KILL,
+// MENU_BAR_ENABLE,
+// MUSIC,
+// PAN_TRACK,
+// PLAY_PRELOAD,
+// PREFERENCES,
+// QUIT,
+// RANDOM,
+// REGION,
+// RESTORE_GAME,
+// ROTATE_TO,
+// SAVE_GAME,
+// SET_PARTIAL_SCREEN,
+// SET_SCREEN,
+// SET_VENUS,
+// STOP,
+// STREAM_VIDEO,
+// SYNC_SOUND,
+// TTY_TEXT,
+// UNIVERSE_MUSIC,
+
+class ActionAdd : public ResultAction {
+public:
+ ActionAdd(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _value;
+};
+
+class ActionAssign : public ResultAction {
+public:
+ ActionAssign(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _value;
+};
+
+class ActionAttenuate : public ResultAction {
+public:
+ ActionAttenuate(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ int _attenuation;
+};
+
+class ActionChangeLocation : public ResultAction {
+public:
+ ActionChangeLocation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ char _world;
+ char _room;
+ char _node;
+ char _view;
+ uint32 _offset;
+};
+
+class ActionCrossfade : public ResultAction {
+public:
+ ActionCrossfade(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _keyOne;
+ uint32 _keyTwo;
+ uint _oneStartVolume;
+ uint _twoStartVolume;
+ uint _oneEndVolume;
+ uint _twoEndVolume;
+ uint _timeInMillis;
+};
+
+class ActionDebug : public ResultAction {
+public:
+ ActionDebug(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDelayRender : public ResultAction {
+public:
+ ActionDelayRender(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ // TODO: Check if this should actually be frames or if it should be milliseconds/seconds
+ uint32 framesToDelay;
+};
+
+class ActionDisableControl : public ResultAction {
+public:
+ ActionDisableControl(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+};
+
+class ActionDisableVenus : public ResultAction {
+public:
+ ActionDisableVenus(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDisplayMessage : public ResultAction {
+public:
+ ActionDisplayMessage(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDissolve : public ResultAction {
+public:
+ ActionDissolve();
+ bool execute(ZVision *engine);
+};
+
+class ActionDistort : public ResultAction {
+public:
+ ActionDistort(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionEnableControl : public ResultAction {
+public:
+ ActionEnableControl(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+};
+
+class ActionMusic : public ResultAction {
+public:
+ ActionMusic(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Audio::Mixer::SoundType _soundType;
+ Common::String _fileName;
+ bool _loop;
+ byte _volume;
+};
+
+class ActionPlayAnimation : public ResultAction {
+public:
+ ActionPlayAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Common::String _fileName;
+ uint32 _x;
+ uint32 _y;
+ uint32 _width;
+ uint32 _height;
+ uint32 _start;
+ uint32 _end;
+ uint _mask;
+ uint _framerate;
+ uint _loopCount;
+};
+
+class ActionPlayPreloadAnimation : public ResultAction {
+public:
+ ActionPlayPreloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _animationKey;
+ uint32 _controlKey;
+ uint32 _x1;
+ uint32 _y1;
+ uint32 _x2;
+ uint32 _y2;
+ uint _startFrame;
+ uint _endFrame;
+ uint _loopCount;
+};
+
+class ActionPreloadAnimation : public ResultAction {
+public:
+ ActionPreloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Common::String _fileName;
+ uint _mask;
+ uint _framerate;
+};
+
+class ActionQuit : public ResultAction {
+public:
+ ActionQuit() {}
+ bool execute(ZVision *engine);
+};
+
+// TODO: See if this exists in ZGI. It doesn't in ZNem
+class ActionUnloadAnimation : public ResultAction {
+public:
+ ActionUnloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+};
+
+class ActionRandom : public ResultAction {
+public:
+ ActionRandom(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _max;
+};
+
+class ActionSetPartialScreen : public ResultAction {
+public:
+ ActionSetPartialScreen(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint _x;
+ uint _y;
+ Common::String _fileName;
+ uint16 _backgroundColor;
+};
+
+class ActionSetScreen : public ResultAction {
+public:
+ ActionSetScreen(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ Common::String _fileName;
+};
+
+class ActionStreamVideo : public ResultAction {
+public:
+ ActionStreamVideo(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ enum {
+ DIFFERENT_DIMENSIONS = 0x1 // 0x1 flags that the destRect dimensions are different from the original video dimensions
+ };
+
+ Common::String _fileName;
+ uint _x1;
+ uint _y1;
+ uint _x2;
+ uint _y2;
+ uint _flags;
+ bool _skippable;
+};
+
+class ActionTimer : public ResultAction {
+public:
+ ActionTimer(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _time;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/control.cpp b/engines/zvision/scripting/control.cpp
new file mode 100644
index 0000000000..35c4ea1441
--- /dev/null
+++ b/engines/zvision/scripting/control.cpp
@@ -0,0 +1,124 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+void Control::enable() {
+ if (!_enabled) {
+ _enabled = true;
+ return;
+ }
+
+ debug("Control %u is already enabled", _key);
+}
+
+void Control::disable() {
+ if (_enabled) {
+ _enabled = false;
+ return;
+ }
+
+ debug("Control %u is already disabled", _key);
+}
+
+void Control::parseFlatControl(ZVision *engine) {
+ engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT);
+}
+
+void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &stream) {
+ RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
+ renderTable->setRenderState(RenderTable::PANORAMA);
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("angle*", true)) {
+ float fov;
+ sscanf(line.c_str(), "angle(%f)", &fov);
+ renderTable->setPanoramaFoV(fov);
+ } else if (line.matchString("linscale*", true)) {
+ float scale;
+ sscanf(line.c_str(), "linscale(%f)", &scale);
+ renderTable->setPanoramaScale(scale);
+ } else if (line.matchString("reversepana*", true)) {
+ uint reverse;
+ sscanf(line.c_str(), "reversepana(%u)", &reverse);
+ if (reverse == 1) {
+ renderTable->setPanoramaReverse(true);
+ }
+ } else if (line.matchString("zeropoint*", true)) {
+ // TODO: Implement
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderTable->generateRenderTable();
+}
+
+void Control::parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream) {
+ RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
+ renderTable->setRenderState(RenderTable::TILT);
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("angle*", true)) {
+ float fov;
+ sscanf(line.c_str(), "angle(%f)", &fov);
+ renderTable->setTiltFoV(fov);
+ } else if (line.matchString("linscale*", true)) {
+ float scale;
+ sscanf(line.c_str(), "linscale(%f)", &scale);
+ renderTable->setTiltScale(scale);
+ } else if (line.matchString("reversepana*", true)) {
+ uint reverse;
+ sscanf(line.c_str(), "reversepana(%u)", &reverse);
+ if (reverse == 1) {
+ renderTable->setTiltReverse(true);
+ }
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderTable->generateRenderTable();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/control.h b/engines/zvision/scripting/control.h
new file mode 100644
index 0000000000..770c540a12
--- /dev/null
+++ b/engines/zvision/scripting/control.h
@@ -0,0 +1,146 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_CONTROL_H
+#define ZVISION_CONTROL_H
+
+#include "common/keyboard.h"
+
+
+namespace Common {
+class SeekableReadStream;
+struct Point;
+class WriteStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class Control {
+public:
+ Control() : _engine(0), _key(0), _enabled(false) {}
+ Control(ZVision *engine, uint32 key) : _engine(engine), _key(key), _enabled(false) {}
+ virtual ~Control() {}
+
+ uint32 getKey() { return _key; }
+
+ virtual void enable();
+ virtual void disable();
+ virtual void focus() {}
+ virtual void unfocus() {}
+ /**
+ * Called when LeftMouse is pushed. Default is NOP.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ virtual void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {}
+ /**
+ * Called when LeftMouse is lifted. Default is NOP.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ virtual void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {}
+ /**
+ * Called on every MouseMove. Default is NOP.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ virtual bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { return false; }
+ /**
+ * Called when a key is pressed. Default is NOP.
+ *
+ * @param keycode The key that was pressed
+ */
+ virtual void onKeyDown(Common::KeyState keyState) {}
+ /**
+ * Called when a key is released. Default is NOP.
+ *
+ * @param keycode The key that was pressed
+ */
+ virtual void onKeyUp(Common::KeyState keyState) {}
+ /**
+ * Processes the node given the deltaTime since last frame. Default is NOP.
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ virtual bool process(uint32 deltaTimeInMillis) { return false; }
+ /**
+ * Serialize a Control for save game use. This should only be used if a Control needs
+ * to save values that would be different from initialization. AKA a TimerNode needs to
+ * store the amount of time left on the timer. Any Controls overriding this *MUST* write
+ * their key as the first data outputted. The default implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override deserialize()
+ * and needsSerialization()
+ *
+ * @param stream Stream to write any needed data to
+ */
+ virtual void serialize(Common::WriteStream *stream) {}
+ /**
+ * De-serialize data from a save game stream. This should only be implemented if the
+ * Control also implements serialize(). The calling method assumes the size of the
+ * data read from the stream exactly equals that written in serialize(). The default
+ * implementation is NOP.
+ *
+ * NOTE: If this method is overridden, you MUST also override serialize()
+ * and needsSerialization()
+ *
+ * @param stream Save game file stream
+ */
+ virtual void deserialize(Common::SeekableReadStream *stream) {}
+ /**
+ * If a Control overrides serialize() and deserialize(), this should return true
+ *
+ * @return Does the Control need save game serialization?
+ */
+ virtual inline bool needsSerialization() { return false; }
+
+protected:
+ ZVision * _engine;
+ uint32 _key;
+ bool _enabled;
+
+// Static member functions
+public:
+ static void parseFlatControl(ZVision *engine);
+ static void parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &stream);
+ static void parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream);
+};
+
+// TODO: Implement InputControl
+// TODO: Implement SaveControl
+// TODO: Implement SlotControl
+// TODO: Implement SafeControl
+// TODO: Implement FistControl
+// TODO: Implement HotMovieControl
+// TODO: Implement PaintControl
+// TODO: Implement TilterControl
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/animation_control.cpp b/engines/zvision/scripting/controls/animation_control.cpp
new file mode 100644
index 0000000000..ec8f7a9647
--- /dev/null
+++ b/engines/zvision/scripting/controls/animation_control.cpp
@@ -0,0 +1,263 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/animation_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/animation/rlf_animation.h"
+#include "zvision/video/zork_avi_decoder.h"
+
+#include "video/video_decoder.h"
+
+#include "graphics/surface.h"
+
+
+namespace ZVision {
+
+AnimationControl::AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName)
+ : Control(engine, controlKey),
+ _fileType(RLF),
+ _loopCount(1),
+ _currentLoop(0),
+ _accumulatedTime(0),
+ _cachedFrame(0),
+ _cachedFrameNeedsDeletion(false) {
+ if (fileName.hasSuffix(".rlf")) {
+ _fileType = RLF;
+ _animation.rlf = new RlfAnimation(fileName, false);
+ } else if (fileName.hasSuffix(".avi")) {
+ _fileType = AVI;
+ _animation.avi = new ZorkAVIDecoder();
+ _animation.avi->loadFile(fileName);
+ } else {
+ warning("Unrecognized animation file type: %s", fileName.c_str());
+ }
+
+ _cachedFrame = new Graphics::Surface();
+}
+
+AnimationControl::~AnimationControl() {
+ if (_fileType == RLF) {
+ delete _animation.rlf;
+ } else if (_fileType == AVI) {
+ delete _animation.avi;
+ }
+
+ _cachedFrame->free();
+ delete _cachedFrame;
+}
+
+bool AnimationControl::process(uint32 deltaTimeInMillis) {
+ if (!_enabled) {
+ return false;
+ }
+
+ bool finished = false;
+
+ if (_fileType == RLF) {
+ _accumulatedTime += deltaTimeInMillis;
+
+ uint32 frameTime = _animation.rlf->frameTime();
+ if (_accumulatedTime >= frameTime) {
+ while (_accumulatedTime >= frameTime) {
+ _accumulatedTime -= frameTime;
+
+ // Make sure the frame is inside the working window
+ // If it's not, then just return
+
+ RenderManager *renderManager = _engine->getRenderManager();
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _animation.rlf->width(), workingWindowPoint.y + _animation.rlf->height());
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ const Graphics::Surface *frame = _animation.rlf->getNextFrame();
+
+ // Animation frames for PANORAMAs are transposed, so un-transpose them
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+ if (state == RenderTable::PANORAMA) {
+ Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
+
+ renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ if (_cachedFrameNeedsDeletion) {
+ _cachedFrame->free();
+ delete _cachedFrame;
+ _cachedFrameNeedsDeletion = false;
+ }
+ _cachedFrame = tranposedFrame;
+ _cachedFrameNeedsDeletion = true;
+ } else {
+ // Cleanup
+ tranposedFrame->free();
+ delete tranposedFrame;
+ }
+ } else {
+ renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ if (_cachedFrameNeedsDeletion) {
+ _cachedFrame->free();
+ delete _cachedFrame;
+ _cachedFrameNeedsDeletion = false;
+ }
+ _cachedFrame->copyFrom(*frame);
+ }
+ }
+
+ // Check if we should continue looping
+ if (_animation.rlf->endOfAnimation()) {
+ _animation.rlf->seekToFrame(-1);
+ if (_loopCount > 0) {
+ _currentLoop++;
+ if (_currentLoop >= _loopCount) {
+ finished = true;
+ }
+ }
+ }
+ }
+ } else {
+ // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
+ }
+ }
+ } else if (_fileType == AVI) {
+ if (!_animation.avi->isPlaying()) {
+ _animation.avi->start();
+ }
+
+ if (_animation.avi->needsUpdate()) {
+ const Graphics::Surface *frame = _animation.avi->decodeNextFrame();
+
+ if (frame) {
+ // Make sure the frame is inside the working window
+ // If it's not, then just return
+
+ RenderManager *renderManager = _engine->getRenderManager();
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + frame->w, workingWindowPoint.y + frame->h);
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ // Animation frames for PANORAMAs are transposed, so un-transpose them
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+ if (state == RenderTable::PANORAMA) {
+ Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame);
+
+ renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ if (_cachedFrameNeedsDeletion) {
+ _cachedFrame->free();
+ delete _cachedFrame;
+ _cachedFrameNeedsDeletion = false;
+ }
+ _cachedFrame = tranposedFrame;
+ _cachedFrameNeedsDeletion = true;
+ } else {
+ // Cleanup
+ tranposedFrame->free();
+ delete tranposedFrame;
+ }
+ } else {
+ renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height());
+
+ // If the background can move, we need to cache the last frame so it can be rendered during background movement
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ if (_cachedFrameNeedsDeletion) {
+ _cachedFrame->free();
+ delete _cachedFrame;
+ _cachedFrameNeedsDeletion = false;
+ }
+ _cachedFrame->copyFrom(*frame);
+ }
+ }
+ } else {
+ // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement
+ RenderManager *renderManager = _engine->getRenderManager();
+ RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState();
+
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y));
+ Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h);
+
+ // If the clip returns false, it means the animation is outside the working window
+ if (!renderManager->clipRectToWorkingWindow(subRect)) {
+ return false;
+ }
+
+ renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height());
+ }
+ }
+ }
+
+ // Check if we should continue looping
+ if (_animation.avi->endOfVideo()) {
+ _animation.avi->rewind();
+ if (_loopCount > 0) {
+ _currentLoop++;
+ if (_currentLoop >= _loopCount) {
+ _animation.avi->stop();
+ finished = true;
+ }
+ }
+ }
+ }
+
+ // If we're done, set _animation key = 2 (Why 2? I don't know. It's just the value that they used)
+ // Then disable the control. DON'T delete it. It can be re-used
+ if (finished) {
+ _engine->getScriptManager()->setStateValue(_animationKey, 2);
+ disable();
+ _currentLoop = 0;
+ }
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/animation_control.h b/engines/zvision/scripting/controls/animation_control.h
new file mode 100644
index 0000000000..77663aaf1e
--- /dev/null
+++ b/engines/zvision/scripting/controls/animation_control.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ANIMATION_CONTROL_H
+#define ZVISION_ANIMATION_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+class RlfAnimation;
+
+class AnimationControl : public Control {
+public:
+ AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName);
+ ~AnimationControl();
+
+private:
+ enum FileType {
+ RLF = 1,
+ AVI = 2
+ };
+
+private:
+ uint32 _animationKey;
+
+ union {
+ RlfAnimation *rlf;
+ Video::VideoDecoder *avi;
+ } _animation;
+
+ FileType _fileType;
+ uint _loopCount;
+ int32 _x;
+ int32 _y;
+
+ uint _accumulatedTime;
+ uint _currentLoop;
+
+ Graphics::Surface *_cachedFrame;
+ bool _cachedFrameNeedsDeletion;
+
+public:
+ bool process(uint32 deltaTimeInMillis);
+
+ void setAnimationKey(uint32 animationKey) { _animationKey = animationKey; }
+ void setLoopCount(uint loopCount) { _loopCount = loopCount; }
+ void setXPos(int32 x) { _x = x; }
+ void setYPost(int32 y) { _y = y; }
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
new file mode 100644
index 0000000000..2685b01312
--- /dev/null
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -0,0 +1,142 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/input_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/strings/string_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key),
+ _nextTabstop(0),
+ _focused(false),
+ _textChanged(false),
+ _cursorOffset(0) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("*rectangle*", true)) {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+
+ _textRectangle = Common::Rect(x1, y1, x2, y2);
+ } else if (line.matchString("*aux_hotspot*", true)) {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+
+ _headerRectangle = Common::Rect(x1, y1, x2, y2);
+ } else if (line.matchString("*string_init*", true)) {
+ uint fontFormatNumber;
+
+ sscanf(line.c_str(), "%*[^(](%u)", &fontFormatNumber);
+
+ _textStyle = _engine->getStringManager()->getTextStyle(fontFormatNumber);
+ } else if (line.matchString("*next_tabstop*", true)) {
+ sscanf(line.c_str(), "%*[^(](%u)", &_nextTabstop);
+ } else if (line.matchString("*cursor_animation*", true)) {
+ char fileName[25];
+
+ sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName);
+
+ _cursorAnimationFileName = Common::String(fileName);
+ } else if (line.matchString("*cursor_dimensions*", true)) {
+ // Ignore, use the dimensions in the animation file
+ } else if (line.matchString("*cursor_animation_frames*", true)) {
+ // Ignore, use the frame count in the animation file
+ } else if (line.matchString("*focus*", true)) {
+ _focused = true;
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+}
+
+void InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ _engine->getScriptManager()->focusControl(_key);
+}
+
+void InputControl::onKeyDown(Common::KeyState keyState) {
+ if (!_focused) {
+ return;
+ }
+
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE) {
+ _currentInputText.deleteLastChar();
+ } else if (keyState.keycode == Common::KEYCODE_TAB) {
+ _focused = false;
+ // Focus the next input control
+ _engine->getScriptManager()->focusControl(_nextTabstop);
+ } else {
+ // Otherwise, append the new character to the end of the current text
+
+ uint16 asciiValue = keyState.ascii;
+ // We only care about text values
+ if (asciiValue >= 32 && asciiValue <= 126) {
+ _currentInputText += (char)asciiValue;
+ _textChanged = true;
+ }
+ }
+}
+
+bool InputControl::process(uint32 deltaTimeInMillis) {
+ if (!_focused) {
+ return false;
+ }
+
+ // First see if we need to render the text
+ if (_textChanged) {
+ // Blit the text using the RenderManager
+ Common::Rect destRect = _engine->getRenderManager()->renderTextToWorkingWindow(_key, _currentInputText, _textStyle.font, _textRectangle.left, _textRectangle.top, _textStyle.color, _textRectangle.width());
+
+ _cursorOffset = destRect.left - _textRectangle.left;
+ }
+
+ // Render the next frame of the animation
+ // TODO: Implement animation handling
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
new file mode 100644
index 0000000000..f0fd8b502d
--- /dev/null
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_INPUT_CONTROL_H
+#define ZVISION_INPUT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+#include "zvision/strings/string_manager.h"
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class InputControl : public Control {
+public:
+ InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+
+private:
+ Common::Rect _textRectangle;
+ Common::Rect _headerRectangle;
+ StringManager::TextStyle _textStyle;
+ uint32 _nextTabstop;
+ Common::String _cursorAnimationFileName;
+ bool _focused;
+
+ Common::String _currentInputText;
+ bool _textChanged;
+ uint _cursorOffset;
+
+public:
+ void focus() { _focused = true; }
+ void unfocus() { _focused = false; }
+ void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void onKeyDown(Common::KeyState keyState);
+ bool process(uint32 deltaTimeInMillis);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
new file mode 100644
index 0000000000..e08fdd10f3
--- /dev/null
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -0,0 +1,402 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/lever_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/animation/rlf_animation.h"
+#include "zvision/video/zork_avi_decoder.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
+
+namespace ZVision {
+
+LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key),
+ _frameInfo(0),
+ _frameCount(0),
+ _startFrame(0),
+ _currentFrame(0),
+ _lastRenderedFrame(0),
+ _mouseIsCaptured(false),
+ _isReturning(false),
+ _accumulatedTime(0),
+ _returnRoutesCurrentFrame(0) {
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("*descfile*", true)) {
+ char levFileName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", levFileName);
+
+ parseLevFile(levFileName);
+ } else if (line.matchString("*cursor*", true)) {
+ char cursorName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", cursorName);
+
+ _cursorName = Common::String(cursorName);
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderFrame(_currentFrame);
+}
+
+LeverControl::~LeverControl() {
+ if (_fileType == AVI) {
+ delete _animation.avi;
+ } else if (_fileType == RLF) {
+ delete _animation.rlf;
+ }
+
+ delete[] _frameInfo;
+}
+
+void LeverControl::parseLevFile(const Common::String &fileName) {
+ Common::File file;
+ if (!file.open(fileName)) {
+ warning("LEV file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line = file.readLine();
+
+ while (!file.eos()) {
+ if (line.matchString("*animation_id*", true)) {
+ // Not used
+ } else if (line.matchString("*filename*", true)) {
+ char fileNameBuffer[25];
+ sscanf(line.c_str(), "%*[^:]:%25[^~]~", fileNameBuffer);
+
+ Common::String animationFileName(fileNameBuffer);
+
+ if (animationFileName.hasSuffix(".avi")) {
+ _animation.avi = new ZorkAVIDecoder();
+ _animation.avi->loadFile(animationFileName);
+ _fileType = AVI;
+ } else if (animationFileName.hasSuffix(".rlf")) {
+ _animation.rlf = new RlfAnimation(animationFileName, false);
+ _fileType = RLF;
+ }
+ } else if (line.matchString("*skipcolor*", true)) {
+ // Not used
+ } else if (line.matchString("*anim_coords*", true)) {
+ int left, top, right, bottom;
+ sscanf(line.c_str(), "%*[^:]:%d %d %d %d~", &left, &top, &right, &bottom);
+
+ _animationCoords.left = left;
+ _animationCoords.top = top;
+ _animationCoords.right = right;
+ _animationCoords.bottom = bottom;
+ } else if (line.matchString("*mirrored*", true)) {
+ uint mirrored;
+ sscanf(line.c_str(), "%*[^:]:%u~", &mirrored);
+
+ _mirrored = mirrored == 0 ? false : true;
+ } else if (line.matchString("*frames*", true)) {
+ sscanf(line.c_str(), "%*[^:]:%u~", &_frameCount);
+
+ _frameInfo = new FrameInfo[_frameCount];
+ } else if (line.matchString("*elsewhere*", true)) {
+ // Not used
+ } else if (line.matchString("*out_of_control*", true)) {
+ // Not used
+ } else if (line.matchString("*start_pos*", true)) {
+ sscanf(line.c_str(), "%*[^:]:%u~", &_startFrame);
+ _currentFrame = _startFrame;
+ } else if (line.matchString("*hotspot_deltas*", true)) {
+ uint x;
+ uint y;
+ sscanf(line.c_str(), "%*[^:]:%u %u~", &x, &y);
+
+ _hotspotDelta.x = x;
+ _hotspotDelta.y = y;
+ } else {
+ uint frameNumber;
+ uint x, y;
+
+ if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) {
+ _frameInfo[frameNumber].hotspot.left = x;
+ _frameInfo[frameNumber].hotspot.top = y;
+ _frameInfo[frameNumber].hotspot.right = x + _hotspotDelta.x;
+ _frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
+ }
+
+ Common::StringTokenizer tokenizer(line, " ^=()");
+ tokenizer.nextToken();
+ tokenizer.nextToken();
+
+ Common::String token = tokenizer.nextToken();
+ while (!tokenizer.empty()) {
+ if (token == "D") {
+ token = tokenizer.nextToken();
+
+ uint angle;
+ uint toFrame;
+ sscanf(token.c_str(), "%u,%u", &toFrame, &angle);
+
+ _frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame));
+ } else if (token.hasPrefix("P")) {
+ // Format: P(<from> to <to>)
+ tokenizer.nextToken();
+ tokenizer.nextToken();
+ token = tokenizer.nextToken();
+ uint to = atoi(token.c_str());
+
+ _frameInfo[frameNumber].returnRoute.push_back(to);
+ }
+
+ token = tokenizer.nextToken();
+ }
+ }
+
+ line = file.readLine();
+ }
+}
+
+void LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
+ _mouseIsCaptured = true;
+ _lastMousePos = backgroundImageSpacePos;
+ }
+}
+
+void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_mouseIsCaptured) {
+ _mouseIsCaptured = false;
+ _engine->getScriptManager()->setStateValue(_key, _currentFrame);
+
+ _isReturning = true;
+ _returnRoutesCurrentProgress = _frameInfo[_currentFrame].returnRoute.begin();
+ _returnRoutesCurrentFrame = _currentFrame;
+ }
+}
+
+bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return false;
+ }
+
+ bool cursorWasChanged = false;
+
+ if (_mouseIsCaptured) {
+ // Make sure the square distance between the last point and the current point is greater than 64
+ // This is a heuristic. This determines how responsive the lever is to mouse movement.
+ // TODO: Fiddle with the heuristic to get a good lever responsiveness 'feel'
+ if (_lastMousePos.sqrDist(backgroundImageSpacePos) >= 64) {
+ int angle = calculateVectorAngle(_lastMousePos, backgroundImageSpacePos);
+ _lastMousePos = backgroundImageSpacePos;
+
+ for (Common::List<Direction>::iterator iter = _frameInfo[_currentFrame].directions.begin(); iter != _frameInfo[_currentFrame].directions.end(); ++iter) {
+ if (angle >= (int)iter->angle - ANGLE_DELTA && angle <= (int)iter->angle + ANGLE_DELTA) {
+ _currentFrame = iter->toFrame;
+ renderFrame(_currentFrame);
+ break;
+ }
+ }
+ }
+ } else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursorName);
+ cursorWasChanged = true;
+ }
+
+ return cursorWasChanged;
+}
+
+bool LeverControl::process(uint32 deltaTimeInMillis) {
+ if (!_enabled) {
+ return false;
+ }
+
+ if (_isReturning) {
+ _accumulatedTime += deltaTimeInMillis;
+ while (_accumulatedTime >= ANIMATION_FRAME_TIME) {
+ _accumulatedTime -= ANIMATION_FRAME_TIME;
+ if (_returnRoutesCurrentFrame == *_returnRoutesCurrentProgress) {
+ _returnRoutesCurrentProgress++;
+ }
+ if (_returnRoutesCurrentProgress == _frameInfo[_currentFrame].returnRoute.end()) {
+ _isReturning = false;
+ _currentFrame = _returnRoutesCurrentFrame;
+ return false;
+ }
+
+ uint toFrame = *_returnRoutesCurrentProgress;
+ if (_returnRoutesCurrentFrame < toFrame) {
+ _returnRoutesCurrentFrame++;
+ } else if (_returnRoutesCurrentFrame > toFrame) {
+ _returnRoutesCurrentFrame--;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, _returnRoutesCurrentFrame);
+ renderFrame(_returnRoutesCurrentFrame);
+ }
+ }
+
+ return false;
+}
+
+int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo) {
+ // Check for the easy angles first
+ if (pointOne.x == pointTwo.x && pointOne.y == pointTwo.y)
+ return -1; // This should never happen
+ else if (pointOne.x == pointTwo.x) {
+ if (pointTwo.y < pointOne.y)
+ return 90;
+ else
+ return 270;
+ } else if (pointOne.y == pointTwo.y) {
+ if (pointTwo.x > pointOne.x)
+ return 0;
+ else
+ return 180;
+ } else {
+ // Calculate the angle with trig
+ int16 xDist = pointTwo.x - pointOne.x;
+ int16 yDist = pointTwo.y - pointOne.y;
+
+ // Calculate the angle using arctan
+ // Then convert to degrees. (180 / 3.14159 = 57.2958)
+ int angle = int(atan((float)yDist / (float)xDist) * 57);
+
+ // Calculate what quadrant pointTwo is in
+ uint quadrant = ((yDist > 0 ? 1 : 0) << 1) | (xDist < 0 ? 1 : 0);
+
+ // Explanation of quadrants:
+ //
+ // yDist > 0 | xDist < 0 | Quadrant number
+ // 0 | 0 | 0
+ // 0 | 1 | 1
+ // 1 | 0 | 2
+ // 1 | 1 | 3
+ //
+ // Note: I know this doesn't line up with traditional mathematical quadrants
+ // but doing it this way allows you can use a switch and is a bit cleaner IMO.
+ //
+ // The graph below shows the 4 quadrants pointTwo can end up in as well
+ // as what the angle as calculated above refers to.
+ // Note: The calculated angle in quadrants 0 and 3 is negative
+ // due to arctan(-x) = -theta
+ //
+ // Origin => (pointOne.x, pointOne.y)
+ // * => (pointTwo.x, pointTwo.y)
+ //
+ // 90 |
+ // ^ |
+ // * | * |
+ // \ | / |
+ // \ | / |
+ // \ | / |
+ // Quadrant 1 \ | / Quadrant 0 |
+ // \ | / |
+ // \ | / |
+ // angle ( \|/ ) -angle |
+ // 180 <----------------------------------------> 0 |
+ // -angle ( /|\ ) angle |
+ // / | \ |
+ // / | \ |
+ // Quadrant 3 / | \ Quadrant 2 |
+ // / | \ |
+ // / | \ |
+ // / | \ |
+ // * | * |
+ // ^ |
+ // 270 |
+
+ // Convert the local angles to unit circle angles
+ switch (quadrant) {
+ case 0:
+ angle = 180 + angle;
+ break;
+ case 1:
+ // Do nothing
+ break;
+ case 2:
+ angle = 180 + angle;
+ break;
+ case 3:
+ angle = 360 + angle;
+ break;
+ }
+
+ return angle;
+ }
+}
+
+void LeverControl::renderFrame(uint frameNumber) {
+ if (frameNumber == 0) {
+ _lastRenderedFrame = frameNumber;
+ } else if (frameNumber < _lastRenderedFrame && _mirrored) {
+ _lastRenderedFrame = frameNumber;
+ frameNumber = (_frameCount * 2) - frameNumber - 1;
+ } else {
+ _lastRenderedFrame = frameNumber;
+ }
+
+ const uint16 *frameData = 0;
+ int x = _animationCoords.left;
+ int y = _animationCoords.top;
+ int width = 0;
+ int height = 0;
+
+ if (_fileType == RLF) {
+ // getFrameData() will automatically optimize to getNextFrame() / getPreviousFrame() if it can
+ frameData = (const uint16 *)_animation.rlf->getFrameData(frameNumber)->getPixels();
+ width = _animation.rlf->width(); // Use the animation width instead of _animationCoords.width()
+ height = _animation.rlf->height(); // Use the animation height instead of _animationCoords.height()
+ } else if (_fileType == AVI) {
+ _animation.avi->seekToFrame(frameNumber);
+ const Graphics::Surface *surface = _animation.avi->decodeNextFrame();
+ frameData = (const uint16 *)surface->getPixels();
+ width = surface->w;
+ height = surface->h;
+ }
+
+ _engine->getRenderManager()->copyRectToWorkingWindow(frameData, x, y, width, width, height);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
new file mode 100644
index 0000000000..69473cf119
--- /dev/null
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_LEVER_CONTROL_H
+#define ZVISION_LEVER_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/list.h"
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class ZorkAVIDecoder;
+class RlfAnimation;
+
+class LeverControl : public Control {
+public:
+ LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~LeverControl();
+
+private:
+ enum FileType {
+ RLF = 1,
+ AVI = 2
+ };
+
+ struct Direction {
+ Direction(uint a, uint t) : angle(a), toFrame(t) {}
+
+ uint angle;
+ uint toFrame;
+ };
+
+ struct FrameInfo {
+ Common::Rect hotspot;
+ Common::List<Direction> directions;
+ Common::List<uint> returnRoute;
+ };
+
+ enum {
+ ANGLE_DELTA = 30, // How far off a mouse angle can be and still be considered valid. This is in both directions, so the total buffer zone is (2 * ANGLE_DELTA)
+ ANIMATION_FRAME_TIME = 30 // In millis
+ };
+
+private:
+ union {
+ RlfAnimation *rlf;
+ ZorkAVIDecoder *avi;
+ } _animation;
+ FileType _fileType;
+
+ Common::String _cursorName;
+ Common::Rect _animationCoords;
+ bool _mirrored;
+ uint _frameCount;
+ uint _startFrame;
+ Common::Point _hotspotDelta;
+ FrameInfo *_frameInfo;
+
+ uint _currentFrame;
+ uint _lastRenderedFrame;
+ bool _mouseIsCaptured;
+ bool _isReturning;
+ Common::Point _lastMousePos;
+ Common::List<uint>::iterator _returnRoutesCurrentProgress;
+ uint _returnRoutesCurrentFrame;
+ uint32 _accumulatedTime;
+
+public:
+ void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ void parseLevFile(const Common::String &fileName);
+ /**
+ * Calculates the angle a vector makes with the negative y-axis
+ *
+ * 90
+ * pointTwo * ^
+ * \ |
+ * \ |
+ * \ |
+ * \ |
+ * angle ( \|pointOne
+ * 180 <-----------*-----------> 0
+ * |
+ * |
+ * |
+ * |
+ * |
+ * ^
+ * 270
+ *
+ * @param pointOne The origin of the vector
+ * @param pointTwo The end of the vector
+ * @return The angle the vector makes with the negative y-axis
+ */
+ static int calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo);
+ void renderFrame(uint frameNumber);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/push_toggle_control.cpp b/engines/zvision/scripting/controls/push_toggle_control.cpp
new file mode 100644
index 0000000000..11ec4bb73f
--- /dev/null
+++ b/engines/zvision/scripting/controls/push_toggle_control.cpp
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/push_toggle_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("*_hotspot*", true)) {
+ uint x;
+ uint y;
+ uint width;
+ uint height;
+
+ sscanf(line.c_str(), "%*[^(](%u,%u,%u,%u)", &x, &y, &width, &height);
+
+ _hotspot = Common::Rect(x, y, x + width, y + height);
+ } else if (line.matchString("cursor*", true)) {
+ char nameBuffer[25];
+
+ sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer);
+
+ _hoverCursor = Common::String(nameBuffer);
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ if (_hotspot.isEmpty() || _hoverCursor.empty()) {
+ warning("Push_toggle cursor %u was parsed incorrectly", key);
+ }
+}
+
+PushToggleControl::~PushToggleControl() {
+ // Clear the state value back to 0
+ _engine->getScriptManager()->setStateValue(_key, 0);
+}
+
+void PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getScriptManager()->setStateValue(_key, 1);
+ }
+}
+
+bool PushToggleControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return false;
+ }
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_hoverCursor);
+ return true;
+ }
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/push_toggle_control.h b/engines/zvision/scripting/controls/push_toggle_control.h
new file mode 100644
index 0000000000..13dc54a65f
--- /dev/null
+++ b/engines/zvision/scripting/controls/push_toggle_control.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_PUSH_TOGGLE_CONTROL_H
+#define ZVISION_PUSH_TOGGLE_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class PushToggleControl : public Control {
+public:
+ PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~PushToggleControl();
+
+ /**
+ * Called when LeftMouse is lifted. Calls ScriptManager::setStateValue(_key, 1);
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor.
+ *
+ * @param engine The base engine
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+ Common::Rect _hotspot;
+ /** The cursor to use when hovering over _hotspot */
+ Common::String _hoverCursor;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/controls/timer_node.cpp
new file mode 100644
index 0000000000..3b691be275
--- /dev/null
+++ b/engines/zvision/scripting/controls/timer_node.cpp
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/timer_node.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
+ : Control(engine, key) {
+ if (_engine->getGameId() == GID_NEMESIS) {
+ _timeLeft = timeInSeconds * 1000;
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ _timeLeft = timeInSeconds * 100;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+TimerNode::~TimerNode() {
+ if (_timeLeft <= 0)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ else
+ _engine->getScriptManager()->setStateValue(_key, _timeLeft); // If timer was stopped by stop or kill
+}
+
+bool TimerNode::process(uint32 deltaTimeInMillis) {
+ _timeLeft -= deltaTimeInMillis;
+
+ if (_timeLeft <= 0) {
+ // Let the destructor reset the state value
+ return true;
+ }
+
+ return false;
+}
+
+void TimerNode::serialize(Common::WriteStream *stream) {
+ stream->writeUint32LE(_key);
+ stream->writeUint32LE(_timeLeft);
+}
+
+void TimerNode::deserialize(Common::SeekableReadStream *stream) {
+ _timeLeft = stream->readUint32LE();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/controls/timer_node.h
new file mode 100644
index 0000000000..a8e579cbe4
--- /dev/null
+++ b/engines/zvision/scripting/controls/timer_node.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_TIMER_NODE_H
+#define ZVISION_TIMER_NODE_H
+
+#include "zvision/scripting/control.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class TimerNode : public Control {
+public:
+ TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
+ ~TimerNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+ void serialize(Common::WriteStream *stream);
+ void deserialize(Common::SeekableReadStream *stream);
+ inline bool needsSerialization() { return true; }
+
+private:
+ int32 _timeLeft;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/puzzle.h b/engines/zvision/scripting/puzzle.h
new file mode 100644
index 0000000000..0d717f1fa9
--- /dev/null
+++ b/engines/zvision/scripting/puzzle.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_PUZZLE_H
+#define ZVISION_PUZZLE_H
+
+#include "zvision/scripting/actions.h"
+
+#include "common/list.h"
+#include "common/ptr.h"
+
+
+namespace ZVision {
+
+struct Puzzle {
+ Puzzle() : key(0) {}
+
+ ~Puzzle() {
+ for (Common::List<ResultAction *>::iterator iter = resultActions.begin(); iter != resultActions.end(); ++iter) {
+ delete *iter;
+ }
+ }
+
+ /** How criteria should be decided */
+ enum CriteriaOperator {
+ EQUAL_TO,
+ NOT_EQUAL_TO,
+ GREATER_THAN,
+ LESS_THAN
+ };
+
+ /** Criteria for a Puzzle result to be fired */
+ struct CriteriaEntry {
+ /** The key of a global state */
+ uint32 key;
+ /**
+ * What we're comparing the value of the global state against
+ * This can either be a pure value or it can be the key of another global state
+ */
+ uint32 argument;
+ /** How to do the comparison */
+ CriteriaOperator criteriaOperator;
+ /** Whether 'argument' is the key of a global state (true) or a pure value (false) */
+ bool argumentIsAKey;
+ };
+
+ uint32 key;
+ Common::List<Common::List <CriteriaEntry> > criteriaList;
+ // This has to be list of pointers because ResultAction is abstract
+ Common::List<ResultAction *> resultActions;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
new file mode 100644
index 0000000000..d93094a3b2
--- /dev/null
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -0,0 +1,302 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/script_manager.h"
+
+#include "zvision/utility/utility.h"
+#include "zvision/scripting/puzzle.h"
+#include "zvision/scripting/actions.h"
+#include "zvision/scripting/controls/push_toggle_control.h"
+#include "zvision/scripting/controls/lever_control.h"
+
+#include "common/textconsole.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+
+
+namespace ZVision {
+
+void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal) {
+ Common::File file;
+ if (!file.open(fileName)) {
+ warning("Script file not found: %s", fileName.c_str());
+ return;
+ }
+
+ while(!file.eos()) {
+ Common::String line = file.readLine();
+ if (file.err()) {
+ warning("Error parsing scr file: %s", fileName.c_str());
+ return;
+ }
+
+ trimCommentsAndWhiteSpace(&line);
+ if (line.empty())
+ continue;
+
+ if (line.matchString("puzzle:*", true)) {
+ Puzzle *puzzle = new Puzzle();
+ sscanf(line.c_str(),"puzzle:%u",&(puzzle->key));
+
+ parsePuzzle(puzzle, file);
+ if (isGlobal) {
+ _globalPuzzles.push_back(puzzle);
+ } else {
+ _activePuzzles.push_back(puzzle);
+ }
+ } else if (line.matchString("control:*", true)) {
+ parseControl(line, file);
+ }
+ }
+}
+
+void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream) {
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("criteria {", true)) {
+ parseCriteria(stream, puzzle->criteriaList);
+ } else if (line.matchString("results {", true)) {
+ parseResults(stream, puzzle->resultActions);
+ } else if (line.matchString("flags {", true)) {
+ setStateFlags(puzzle->key, parseFlags(stream));
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+}
+
+bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ // Criteria can be empty
+ if (line.contains('}')) {
+ return false;
+ }
+
+ // Create a new List to hold the CriteriaEntries
+ criteriaList.push_back(Common::List<Puzzle::CriteriaEntry>());
+
+ while (!stream.eos() && !line.contains('}')) {
+ Puzzle::CriteriaEntry entry;
+
+ // Split the string into tokens using ' ' as a delimiter
+ Common::StringTokenizer tokenizer(line);
+ Common::String token;
+
+ // Parse the id out of the first token
+ token = tokenizer.nextToken();
+ sscanf(token.c_str(), "[%u]", &(entry.key));
+
+ // Parse the operator out of the second token
+ token = tokenizer.nextToken();
+ if (token.c_str()[0] == '=')
+ entry.criteriaOperator = Puzzle::EQUAL_TO;
+ else if (token.c_str()[0] == '!')
+ entry.criteriaOperator = Puzzle::NOT_EQUAL_TO;
+ else if (token.c_str()[0] == '>')
+ entry.criteriaOperator = Puzzle::GREATER_THAN;
+ else if (token.c_str()[0] == '<')
+ entry.criteriaOperator = Puzzle::LESS_THAN;
+
+ // First determine if the last token is an id or a value
+ // Then parse it into 'argument'
+ token = tokenizer.nextToken();
+ if (token.contains('[')) {
+ sscanf(token.c_str(), "[%u]", &(entry.argument));
+ entry.argumentIsAKey = true;
+ } else {
+ sscanf(token.c_str(), "%u", &(entry.argument));
+ entry.argumentIsAKey = false;
+ }
+
+ criteriaList.back().push_back(entry);
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return true;
+}
+
+void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::List<ResultAction *> &actionList) const {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ // TODO: Re-order the if-then statements in order of highest occurrence
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.empty()) {
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ continue;
+ }
+
+ // Parse for the action type
+ if (line.matchString("*:add*", true)) {
+ actionList.push_back(new ActionAdd(line));
+ } else if (line.matchString("*:animplay*", true)) {
+ actionList.push_back(new ActionPlayAnimation(line));
+ } else if (line.matchString("*:animpreload*", true)) {
+ actionList.push_back(new ActionPreloadAnimation(line));
+ } else if (line.matchString("*:animunload*", true)) {
+ //actionList.push_back(new ActionUnloadAnimation(line));
+ } else if (line.matchString("*:attenuate*", true)) {
+ // TODO: Implement ActionAttenuate
+ } else if (line.matchString("*:assign*", true)) {
+ actionList.push_back(new ActionAssign(line));
+ } else if (line.matchString("*:change_location*", true)) {
+ actionList.push_back(new ActionChangeLocation(line));
+ } else if (line.matchString("*:crossfade*", true)) {
+ // TODO: Implement ActionCrossfade
+ } else if (line.matchString("*:debug*", true)) {
+ // TODO: Implement ActionDebug
+ } else if (line.matchString("*:delay_render*", true)) {
+ // TODO: Implement ActionDelayRender
+ } else if (line.matchString("*:disable_control*", true)) {
+ actionList.push_back(new ActionDisableControl(line));
+ } else if (line.matchString("*:disable_venus*", true)) {
+ // TODO: Implement ActionDisableVenus
+ } else if (line.matchString("*:display_message*", true)) {
+ // TODO: Implement ActionDisplayMessage
+ } else if (line.matchString("*:dissolve*", true)) {
+ // TODO: Implement ActionDissolve
+ } else if (line.matchString("*:distort*", true)) {
+ // TODO: Implement ActionDistort
+ } else if (line.matchString("*:enable_control*", true)) {
+ actionList.push_back(new ActionEnableControl(line));
+ } else if (line.matchString("*:flush_mouse_events*", true)) {
+ // TODO: Implement ActionFlushMouseEvents
+ } else if (line.matchString("*:inventory*", true)) {
+ // TODO: Implement ActionInventory
+ } else if (line.matchString("*:kill*", true)) {
+ // TODO: Implement ActionKill
+ } else if (line.matchString("*:menu_bar_enable*", true)) {
+ // TODO: Implement ActionMenuBarEnable
+ } else if (line.matchString("*:music*", true)) {
+ actionList.push_back(new ActionMusic(line));
+ } else if (line.matchString("*:pan_track*", true)) {
+ // TODO: Implement ActionPanTrack
+ } else if (line.matchString("*:playpreload*", true)) {
+ actionList.push_back(new ActionPlayPreloadAnimation(line));
+ } else if (line.matchString("*:preferences*", true)) {
+ // TODO: Implement ActionPreferences
+ } else if (line.matchString("*:quit*", true)) {
+ actionList.push_back(new ActionQuit());
+ } else if (line.matchString("*:random*", true)) {
+ actionList.push_back(new ActionRandom(line));
+ } else if (line.matchString("*:region*", true)) {
+ // TODO: Implement ActionRegion
+ } else if (line.matchString("*:restore_game*", true)) {
+ // TODO: Implement ActionRestoreGame
+ } else if (line.matchString("*:rotate_to*", true)) {
+ // TODO: Implement ActionRotateTo
+ } else if (line.matchString("*:save_game*", true)) {
+ // TODO: Implement ActionSaveGame
+ } else if (line.matchString("*:set_partial_screen*", true)) {
+ actionList.push_back(new ActionSetPartialScreen(line));
+ } else if (line.matchString("*:set_screen*", true)) {
+ actionList.push_back(new ActionSetScreen(line));
+ } else if (line.matchString("*:set_venus*", true)) {
+ // TODO: Implement ActionSetVenus
+ } else if (line.matchString("*:stop*", true)) {
+ // TODO: Implement ActionStop
+ } else if (line.matchString("*:streamvideo*", true)) {
+ actionList.push_back(new ActionStreamVideo(line));
+ } else if (line.matchString("*:syncsound*", true)) {
+ // TODO: Implement ActionSyncSound
+ } else if (line.matchString("*:timer*", true)) {
+ actionList.push_back(new ActionTimer(line));
+ } else if (line.matchString("*:ttytext*", true)) {
+ // TODO: Implement ActionTTYText
+ } else if (line.matchString("*:universe_music*", true)) {
+ // TODO: Implement ActionUniverseMusic
+ } else if (line.matchString("*:copy_file*", true)) {
+ // Not used. Purposely left empty
+ } else {
+ warning("Unhandled result action type: %s", line.c_str());
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return;
+}
+
+uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
+ uint flags = 0;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("ONCE_PER_INST", true)) {
+ flags |= ONCE_PER_INST;
+ } else if (line.matchString("DO_ME_NOW", true)) {
+ flags |= DO_ME_NOW;
+ } else if (line.matchString("DISABLED", true)) {
+ flags |= DISABLED;
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return flags;
+}
+
+void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
+ uint32 key;
+ char controlTypeBuffer[20];
+
+ sscanf(line.c_str(), "control:%u %s {", &key, controlTypeBuffer);
+
+ Common::String controlType(controlTypeBuffer);
+
+ if (controlType.equalsIgnoreCase("push_toggle")) {
+ _activeControls.push_back(new PushToggleControl(_engine, key, stream));
+ return;
+ } else if (controlType.equalsIgnoreCase("flat")) {
+ Control::parseFlatControl(_engine);
+ return;
+ } else if (controlType.equalsIgnoreCase("pana")) {
+ Control::parsePanoramaControl(_engine, stream);
+ return;
+ } else if (controlType.equalsIgnoreCase("tilt")) {
+ Control::parseTiltControl(_engine, stream);
+ return;
+ } else if (controlType.equalsIgnoreCase("lever")) {
+ _activeControls.push_back(new LeverControl(_engine, key, stream));
+ return;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
new file mode 100644
index 0000000000..adcc5c7545
--- /dev/null
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -0,0 +1,444 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/script_manager.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/core/save_manager.h"
+#include "zvision/scripting/actions.h"
+#include "zvision/utility/utility.h"
+
+#include "common/algorithm.h"
+#include "common/hashmap.h"
+#include "common/debug.h"
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+ScriptManager::ScriptManager(ZVision *engine)
+ : _engine(engine),
+ _currentlyFocusedControl(0) {
+}
+
+ScriptManager::~ScriptManager() {
+ for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
+ delete (*iter);
+ }
+ for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
+ delete (*iter);
+ }
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ delete (*iter);
+ }
+}
+
+void ScriptManager::initialize() {
+ parseScrFile("universe.scr", true);
+ changeLocation('g', 'a', 'r', 'y', 0);
+}
+
+void ScriptManager::update(uint deltaTimeMillis) {
+ updateNodes(deltaTimeMillis);
+ checkPuzzleCriteria();
+}
+
+void ScriptManager::createReferenceTable() {
+ // Iterate through each local Puzzle
+ for (PuzzleList::iterator activePuzzleIter = _activePuzzles.begin(); activePuzzleIter != _activePuzzles.end(); ++activePuzzleIter) {
+ Puzzle *puzzlePtr = (*activePuzzleIter);
+
+ // Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*activePuzzleIter)->criteriaList.begin(); criteriaIter != (*activePuzzleIter)->criteriaList.end(); ++criteriaIter) {
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
+ _referenceTable[entryIter->key].push_back(puzzlePtr);
+
+ // If the argument is a key, add a reference to it as well
+ if (entryIter->argumentIsAKey) {
+ _referenceTable[entryIter->argument].push_back(puzzlePtr);
+ }
+ }
+ }
+ }
+
+ // Iterate through each global Puzzle
+ for (PuzzleList::iterator globalPuzzleIter = _globalPuzzles.begin(); globalPuzzleIter != _globalPuzzles.end(); ++globalPuzzleIter) {
+ Puzzle *puzzlePtr = (*globalPuzzleIter);
+
+ // Iterate through each CriteriaEntry and add a reference from the criteria key to the Puzzle
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = (*globalPuzzleIter)->criteriaList.begin(); criteriaIter != (*globalPuzzleIter)->criteriaList.end(); ++criteriaIter) {
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
+ _referenceTable[entryIter->key].push_back(puzzlePtr);
+
+ // If the argument is a key, add a reference to it as well
+ if (entryIter->argumentIsAKey) {
+ _referenceTable[entryIter->argument].push_back(puzzlePtr);
+ }
+ }
+ }
+ }
+
+ // Remove duplicate entries
+ for (PuzzleMap::iterator referenceTableIter = _referenceTable.begin(); referenceTableIter != _referenceTable.end(); ++referenceTableIter) {
+ removeDuplicateEntries(referenceTableIter->_value);
+ }
+}
+
+void ScriptManager::updateNodes(uint deltaTimeMillis) {
+ // If process() returns true, it means the node can be deleted
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end();) {
+ if ((*iter)->process(deltaTimeMillis)) {
+ delete (*iter);
+ // Remove the node
+ iter = _activeControls.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
+void ScriptManager::checkPuzzleCriteria() {
+ while (!_puzzlesToCheck.empty()) {
+ Puzzle *puzzle = _puzzlesToCheck.pop();
+
+ // Check if the puzzle is already finished
+ // Also check that the puzzle isn't disabled
+ if (getStateValue(puzzle->key) == 1 && (getStateFlags(puzzle->key) & DISABLED) == 0) {
+ continue;
+ }
+
+ // Check each Criteria
+
+ bool criteriaMet = false;
+ for (Common::List<Common::List<Puzzle::CriteriaEntry> >::iterator criteriaIter = puzzle->criteriaList.begin(); criteriaIter != puzzle->criteriaList.end(); ++criteriaIter) {
+ criteriaMet = false;
+
+ for (Common::List<Puzzle::CriteriaEntry>::iterator entryIter = criteriaIter->begin(); entryIter != criteriaIter->end(); ++entryIter) {
+ // Get the value to compare against
+ uint argumentValue;
+ if (entryIter->argumentIsAKey)
+ argumentValue = getStateValue(entryIter->argument);
+ else
+ argumentValue = entryIter->argument;
+
+ // Do the comparison
+ switch (entryIter->criteriaOperator) {
+ case Puzzle::EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) == argumentValue;
+ break;
+ case Puzzle::NOT_EQUAL_TO:
+ criteriaMet = getStateValue(entryIter->key) != argumentValue;
+ break;
+ case Puzzle::GREATER_THAN:
+ criteriaMet = getStateValue(entryIter->key) > argumentValue;
+ break;
+ case Puzzle::LESS_THAN:
+ criteriaMet = getStateValue(entryIter->key) < argumentValue;
+ break;
+ }
+
+ // If one check returns false, don't keep checking
+ if (!criteriaMet) {
+ break;
+ }
+ }
+
+ // If any of the Criteria are *fully* met, then execute the results
+ if (criteriaMet) {
+ break;
+ }
+ }
+
+ // criteriaList can be empty. Aka, the puzzle should be executed immediately
+ if (puzzle->criteriaList.empty() || criteriaMet) {
+ debug(1, "Puzzle %u criteria passed. Executing its ResultActions", puzzle->key);
+
+ // Set the puzzle as completed
+ setStateValue(puzzle->key, 1);
+
+ bool shouldContinue = true;
+ for (Common::List<ResultAction *>::iterator resultIter = puzzle->resultActions.begin(); resultIter != puzzle->resultActions.end(); ++resultIter) {
+ shouldContinue = shouldContinue && (*resultIter)->execute(_engine);
+ if (!shouldContinue) {
+ break;
+ }
+ }
+
+ if (!shouldContinue) {
+ break;
+ }
+ }
+ }
+}
+
+void ScriptManager::cleanStateTable() {
+ for (StateMap::iterator iter = _globalState.begin(); iter != _globalState.end(); ++iter) {
+ // If the value is equal to zero, we can purge it since getStateValue()
+ // will return zero if _globalState doesn't contain a key
+ if (iter->_value == 0) {
+ // Remove the node
+ _globalState.erase(iter);
+ }
+ }
+}
+
+uint ScriptManager::getStateValue(uint32 key) {
+ if (_globalState.contains(key))
+ return _globalState[key];
+ else
+ return 0;
+}
+
+void ScriptManager::setStateValue(uint32 key, uint value) {
+ _globalState[key] = value;
+
+ if (_referenceTable.contains(key)) {
+ for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
+ _puzzlesToCheck.push((*iter));
+ }
+ }
+}
+
+uint ScriptManager::getStateFlags(uint32 key) {
+ if (_globalStateFlags.contains(key))
+ return _globalStateFlags[key];
+ else
+ return 0;
+}
+
+void ScriptManager::setStateFlags(uint32 key, uint flags) {
+ _globalStateFlags[key] = flags;
+
+ if (_referenceTable.contains(key)) {
+ for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
+ _puzzlesToCheck.push((*iter));
+ }
+ }
+}
+
+void ScriptManager::addToStateValue(uint32 key, uint valueToAdd) {
+ _globalState[key] += valueToAdd;
+}
+
+void ScriptManager::addControl(Control *control) {
+ _activeControls.push_back(control);
+}
+
+Control *ScriptManager::getControl(uint32 key) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ return (*iter);
+ }
+ }
+
+ return nullptr;
+}
+
+void ScriptManager::focusControl(uint32 key) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ uint32 controlKey = (*iter)->getKey();
+
+ if (controlKey == key) {
+ (*iter)->focus();
+ } else if (controlKey == _currentlyFocusedControl) {
+ (*iter)->unfocus();
+ }
+ }
+
+ _currentlyFocusedControl = key;
+}
+
+void ScriptManager::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onMouseDown(screenSpacePos, backgroundImageSpacePos);
+ }
+}
+
+void ScriptManager::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onMouseUp(screenSpacePos, backgroundImageSpacePos);
+ }
+}
+
+bool ScriptManager::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ bool cursorWasChanged = false;
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ cursorWasChanged = cursorWasChanged || (*iter)->onMouseMove(screenSpacePos, backgroundImageSpacePos);
+ }
+
+ return cursorWasChanged;
+}
+
+void ScriptManager::onKeyDown(Common::KeyState keyState) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onKeyDown(keyState);
+ }
+}
+
+void ScriptManager::onKeyUp(Common::KeyState keyState) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onKeyUp(keyState);
+ }
+}
+
+void ScriptManager::changeLocation(char world, char room, char node, char view, uint32 offset) {
+ assert(world != 0);
+ debug(1, "Changing location to: %c %c %c %c %u", world, room, node, view, offset);
+
+ // Auto save
+ _engine->getSaveManager()->autoSave();
+
+ // Clear all the containers
+ _referenceTable.clear();
+ _puzzlesToCheck.clear();
+ for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
+ delete (*iter);
+ }
+ _activePuzzles.clear();
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ delete (*iter);
+ }
+ _activeControls.clear();
+
+ // Revert to the idle cursor
+ _engine->getCursorManager()->revertToIdle();
+
+ // Reset the background velocity
+ _engine->getRenderManager()->setBackgroundVelocity(0);
+
+ // Remove any alphaEntries
+ _engine->getRenderManager()->clearAlphaEntries();
+
+ // Clean the global state table
+ cleanStateTable();
+
+ // Parse into puzzles and controls
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", world, room, node, view);
+ parseScrFile(fileName);
+
+ // Change the background position
+ _engine->getRenderManager()->setBackgroundPosition(offset);
+
+ // Enable all the controls
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->enable();
+ }
+
+ // Add all the local puzzles to the queue to be checked
+ for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
+ // Reset any Puzzles that have the flag ONCE_PER_INST
+ if ((getStateFlags((*iter)->key) & ONCE_PER_INST) == ONCE_PER_INST) {
+ setStateValue((*iter)->key, 0);
+ }
+
+ _puzzlesToCheck.push((*iter));
+ }
+
+ // Add all the global puzzles to the queue to be checked
+ for (PuzzleList::iterator iter = _globalPuzzles.begin(); iter != _globalPuzzles.end(); ++iter) {
+ // Reset any Puzzles that have the flag ONCE_PER_INST
+ if ((getStateFlags((*iter)->key) & ONCE_PER_INST) == ONCE_PER_INST) {
+ setStateValue((*iter)->key, 0);
+ }
+
+ _puzzlesToCheck.push((*iter));
+ }
+
+ // Create the puzzle reference table
+ createReferenceTable();
+
+ // Update _currentLocation
+ _currentLocation.world = world;
+ _currentLocation.room = room;
+ _currentLocation.node = node;
+ _currentLocation.view = view;
+ _currentLocation.offset = offset;
+}
+
+void ScriptManager::serializeStateTable(Common::WriteStream *stream) {
+ // Write the number of state value entries
+ stream->writeUint32LE(_globalState.size());
+
+ for (StateMap::iterator iter = _globalState.begin(); iter != _globalState.end(); ++iter) {
+ // Write out the key/value pair
+ stream->writeUint32LE(iter->_key);
+ stream->writeUint32LE(iter->_value);
+ }
+}
+
+void ScriptManager::deserializeStateTable(Common::SeekableReadStream *stream) {
+ // Clear out the current table values
+ _globalState.clear();
+
+ // Read the number of key/value pairs
+ uint32 numberOfPairs = stream->readUint32LE();
+
+ for (uint32 i = 0; i < numberOfPairs; ++i) {
+ uint32 key = stream->readUint32LE();
+ uint32 value = stream->readUint32LE();
+ // Directly access the state table so we don't trigger Puzzle checks
+ _globalState[key] = value;
+ }
+}
+
+void ScriptManager::serializeControls(Common::WriteStream *stream) {
+ // Count how many controls need to save their data
+ // Because WriteStream isn't seekable
+ uint32 numberOfControlsNeedingSerialization = 0;
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if ((*iter)->needsSerialization()) {
+ numberOfControlsNeedingSerialization++;
+ }
+ }
+ stream->writeUint32LE(numberOfControlsNeedingSerialization);
+
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->serialize(stream);
+ }
+}
+
+void ScriptManager::deserializeControls(Common::SeekableReadStream *stream) {
+ uint32 numberOfControls = stream->readUint32LE();
+
+ for (uint32 i = 0; i < numberOfControls; ++i) {
+ uint32 key = stream->readUint32LE();
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ (*iter)->deserialize(stream);
+ break;
+ }
+ }
+ }
+}
+
+Location ScriptManager::getCurrentLocation() const {
+ Location location = _currentLocation;
+ location.offset = _engine->getRenderManager()->getCurrentBackgroundOffset();
+
+ return location;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
new file mode 100644
index 0000000000..ab9b03ed30
--- /dev/null
+++ b/engines/zvision/scripting/script_manager.h
@@ -0,0 +1,225 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SCRIPT_MANAGER_H
+#define ZVISION_SCRIPT_MANAGER_H
+
+#include "zvision/scripting/puzzle.h"
+#include "zvision/scripting/control.h"
+
+#include "common/hashmap.h"
+#include "common/queue.h"
+
+
+namespace Common {
+class String;
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct Location {
+ Location() : world('g'), room('a'), node('r'), view('y'), offset(0) {}
+
+ char world;
+ char room;
+ char node;
+ char view;
+ uint32 offset;
+};
+
+typedef Common::HashMap<uint32, Common::Array<Puzzle *> > PuzzleMap;
+typedef Common::List<Puzzle *> PuzzleList;
+typedef Common::Queue<Puzzle *> PuzzleQueue;
+typedef Common::List<Control *> ControlList;
+typedef Common::HashMap<uint32, uint32> StateMap;
+typedef Common::HashMap<uint32, uint> StateFlagMap;
+
+class ScriptManager {
+public:
+ ScriptManager(ZVision *engine);
+ ~ScriptManager();
+
+public:
+ enum StateFlags {
+ ONCE_PER_INST = 0x01,
+ DO_ME_NOW = 0x02, // Somewhat useless flag since anything that needs to be done immediately has no criteria
+ DISABLED = 0x04
+ };
+
+private:
+ ZVision *_engine;
+ /**
+ * Holds the global state variable. Do NOT directly modify this. Use the accessors and
+ * mutators getStateValue() and setStateValue(). This ensures that Puzzles that reference a
+ * particular state key are checked after the key is modified.
+ */
+ StateMap _globalState;
+ /**
+ * Holds the flags for the global states. This is used to enable/disable puzzles and/or
+ * controls as well as which puzzles should are allowed to be re-executed
+ */
+ StateFlagMap _globalStateFlags;
+ /** References _globalState keys to Puzzles */
+ PuzzleMap _referenceTable;
+ /** Holds the Puzzles that should be checked this frame */
+ PuzzleQueue _puzzlesToCheck;
+ /** Holds the currently active puzzles */
+ PuzzleList _activePuzzles;
+ /** Holds the global puzzles */
+ PuzzleList _globalPuzzles;
+ /** Holds the currently active controls */
+ ControlList _activeControls;
+
+ Location _currentLocation;
+
+ uint32 _currentlyFocusedControl;
+
+public:
+ void initialize();
+ void update(uint deltaTimeMillis);
+
+ uint getStateValue(uint32 key);
+ void setStateValue(uint32 key, uint value);
+ void addToStateValue(uint32 key, uint valueToAdd);
+
+ uint getStateFlags(uint32 key);
+ void setStateFlags(uint32 key, uint flags);
+
+ void addControl(Control *control);
+ Control *getControl(uint32 key);
+
+ void focusControl(uint32 key);
+
+ /**
+ * Called when LeftMouse is pushed.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called when LeftMouse is lifted.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called on every MouseMove.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called when a key is pressed.
+ *
+ * @param keycode The key that was pressed
+ */
+ void onKeyDown(Common::KeyState keyState);
+ /**
+ * Called when a key is released.
+ *
+ * @param keycode The key that was pressed
+ */
+ void onKeyUp(Common::KeyState keyState);
+
+ void changeLocation(char world, char room, char node, char view, uint32 offset);
+
+ void serializeStateTable(Common::WriteStream *stream);
+ void deserializeStateTable(Common::SeekableReadStream *stream);
+ void serializeControls(Common::WriteStream *stream);
+ void deserializeControls(Common::SeekableReadStream *stream);
+
+ Location getCurrentLocation() const;
+
+private:
+ void createReferenceTable();
+ void updateNodes(uint deltaTimeMillis);
+ void checkPuzzleCriteria();
+ void cleanStateTable();
+
+// TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
+public:
+ /**
+ * Parses a script file into triggers and events
+ *
+ * @param fileName Name of the .scr file
+ * @param isGlobal Are the puzzles included in the file global (true). AKA, the won't be purged during location changes
+ */
+ void parseScrFile(const Common::String &fileName, bool isGlobal = false);
+
+private:
+ /**
+ * Parses the stream into a Puzzle object
+ * Helper method for parseScrFile.
+ *
+ * @param puzzle The object to store what is parsed
+ * @param stream Scr file stream
+ */
+ void parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream);
+
+ /**
+ * Parses the stream into a Criteria object
+ * Helper method for parsePuzzle.
+ *
+ * @param criteria Pointer to the Criteria object to fill
+ * @param stream Scr file stream
+ * @return Whether any criteria were read
+ */
+ bool parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const;
+
+ /**
+ * Parses the stream into a ResultAction objects
+ * Helper method for parsePuzzle.
+ *
+ * @param stream Scr file stream
+ * @param actionList The list where the results will be added
+ * @return Created Results object
+ */
+ void parseResults(Common::SeekableReadStream &stream, Common::List<ResultAction *> &actionList) const;
+
+ /**
+ * Helper method for parsePuzzle. Parses the stream into a bitwise or of the StateFlags enum
+ *
+ * @param stream Scr file stream
+ * @return Bitwise OR of all the flags set within the puzzle
+ */
+ uint parseFlags(Common::SeekableReadStream &stream) const;
+
+ /**
+ * Helper method for parseScrFile. Parses the stream into a Control object
+ *
+ * @param line The line initially read
+ * @param stream Scr file stream
+ */
+ void parseControl(Common::String &line, Common::SeekableReadStream &stream);
+};
+
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
new file mode 100644
index 0000000000..321ac93de2
--- /dev/null
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -0,0 +1,217 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/sound/zork_raw.h"
+
+#include "zvision/zvision.h"
+#include "zvision/detection.h"
+#include "zvision/utility/utility.h"
+
+#include "common/file.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/memstream.h"
+#include "common/bufferedstream.h"
+#include "common/util.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+
+namespace ZVision {
+
+const int16 RawZorkStream::_stepAdjustmentTable[8] = {-1, -1, -1, 1, 4, 7, 10, 12};
+
+const int32 RawZorkStream::_amplitudeLookupTable[89] = {0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E,
+ 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F,
+ 0x0022, 0x0025, 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042,
+ 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076, 0x0082, 0x008F,
+ 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
+ 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292,
+ 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583,
+ 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD, 0x0BD0,
+ 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
+ 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
+ 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF};
+
+const SoundParams RawZorkStream::_zNemSoundParamLookupTable[6] = {{'6', 0x2B11, false, false},
+ {'a', 0x5622, false, true},
+ {'b', 0x5622, true, true},
+ {'n', 0x2B11, false, true},
+ {'s', 0x5622, false, true},
+ {'t', 0x5622, true, true}
+};
+
+const SoundParams RawZorkStream::_zgiSoundParamLookupTable[5] = {{'a',0x5622, false, false},
+ {'k',0x2B11, true, true},
+ {'p',0x5622, false, true},
+ {'q',0x5622, true, true},
+ {'u',0xAC44, true, true}
+};
+
+RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
+ : _rate(rate),
+ _stereo(0),
+ _stream(stream, disposeStream),
+ _endOfData(false) {
+ if (stereo)
+ _stereo = 1;
+
+ _lastSample[0].index = 0;
+ _lastSample[0].sample = 0;
+ _lastSample[1].index = 0;
+ _lastSample[1].sample = 0;
+
+ // Calculate the total playtime of the stream
+ if (stereo)
+ _playtime = Audio::Timestamp(0, _stream->size() / 2, rate);
+ else
+ _playtime = Audio::Timestamp(0, _stream->size(), rate);
+}
+
+int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
+ int bytesRead = 0;
+
+ // 0: Left, 1: Right
+ uint channel = 0;
+
+ while (bytesRead < numSamples) {
+ byte encodedSample = _stream->readByte();
+ if (_stream->eos()) {
+ _endOfData = true;
+ return bytesRead;
+ }
+ bytesRead++;
+
+ int16 index = _lastSample[channel].index;
+ uint32 lookUpSample = _amplitudeLookupTable[index];
+
+ int32 sample = 0;
+
+ if (encodedSample & 0x40)
+ sample += lookUpSample;
+ if (encodedSample & 0x20)
+ sample += lookUpSample >> 1;
+ if (encodedSample & 0x10)
+ sample += lookUpSample >> 2;
+ if (encodedSample & 8)
+ sample += lookUpSample >> 3;
+ if (encodedSample & 4)
+ sample += lookUpSample >> 4;
+ if (encodedSample & 2)
+ sample += lookUpSample >> 5;
+ if (encodedSample & 1)
+ sample += lookUpSample >> 6;
+ if (encodedSample & 0x80)
+ sample = -sample;
+
+ sample += _lastSample[channel].sample;
+ sample = CLIP<int32>(sample, -32768, 32767);
+
+ buffer[bytesRead - 1] = (int16)sample;
+
+ index += _stepAdjustmentTable[(encodedSample >> 4) & 7];
+ index = CLIP<int16>(index, 0, 88);
+
+ _lastSample[channel].sample = sample;
+ _lastSample[channel].index = index;
+
+ // Increment and wrap the channel
+ channel = (channel + 1) & _stereo;
+ }
+
+ return bytesRead;
+}
+
+bool RawZorkStream::rewind() {
+ _stream->seek(0, 0);
+ _stream->clearErr();
+ _endOfData = false;
+ _lastSample[0].index = 0;
+ _lastSample[0].sample = 0;
+ _lastSample[1].index = 0;
+ _lastSample[1].sample = 0;
+
+ return true;
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse) {
+ if (stereo)
+ assert(stream->size() % 2 == 0);
+
+ return new RawZorkStream(rate, stereo, disposeAfterUse, stream);
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse) {
+ return makeRawZorkStream(new Common::MemoryReadStream(buffer, size, disposeAfterUse), rate, stereo, DisposeAfterUse::YES);
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine) {
+ Common::File *file = new Common::File();
+ assert(file->open(filePath));
+
+ Common::String fileName = getFileName(filePath);
+ fileName.toLowercase();
+
+ SoundParams soundParams = { ' ', 0, false, false };
+ bool foundParams = false;
+ char fileIdentifier = (engine->getGameId() == GID_NEMESIS) ? fileName[6] : fileName[7];
+
+ if (engine->getGameId() == GID_NEMESIS) {
+ for (int i = 0; i < 6; ++i) {
+ if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == fileIdentifier) {
+ soundParams = RawZorkStream::_zNemSoundParamLookupTable[i];
+ foundParams = true;
+ }
+ }
+ } else if (engine->getGameId() == GID_GRANDINQUISITOR) {
+ for (int i = 0; i < 6; ++i) {
+ if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == fileIdentifier) {
+ soundParams = RawZorkStream::_zgiSoundParamLookupTable[i];
+ foundParams = true;
+ }
+ }
+ }
+
+ if (!foundParams)
+ error("Unable to find sound params for file '%s'. File identifier is '%c'", filePath.c_str(), fileIdentifier);
+
+ if (soundParams.packed) {
+ return makeRawZorkStream(wrapBufferedSeekableReadStream(file, 2048, DisposeAfterUse::YES), soundParams.rate, soundParams.stereo, DisposeAfterUse::YES);
+ } else {
+ byte flags = 0;
+ if (soundParams.stereo)
+ flags |= Audio::FLAG_STEREO;
+
+ return Audio::makeRawStream(file, soundParams.rate, flags, DisposeAfterUse::YES);
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/sound/zork_raw.h b/engines/zvision/sound/zork_raw.h
new file mode 100644
index 0000000000..481ea79f2d
--- /dev/null
+++ b/engines/zvision/sound/zork_raw.h
@@ -0,0 +1,120 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ZORK_RAW_H
+#define ZVISION_ZORK_RAW_H
+
+#include "audio/audiostream.h"
+
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct SoundParams {
+ char identifier;
+ uint32 rate;
+ bool stereo;
+ bool packed;
+};
+
+/**
+ * This is a stream, which allows for playing raw ADPCM data from a stream.
+ */
+class RawZorkStream : public Audio::RewindableAudioStream {
+public:
+ RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream);
+
+ ~RawZorkStream() {
+ }
+
+public:
+ static const SoundParams _zNemSoundParamLookupTable[6];
+ static const SoundParams _zgiSoundParamLookupTable[5];
+
+private:
+ const int _rate; // Sample rate of stream
+ Audio::Timestamp _playtime; // Calculated total play time
+ Common::DisposablePtr<Common::SeekableReadStream> _stream; // Stream to read data from
+ bool _endOfData; // Whether the stream end has been reached
+ uint _stereo;
+
+ /**
+ * Holds the frequency and index from the last sample
+ * 0 holds the left channel, 1 holds the right channel
+ */
+ struct {
+ int32 sample;
+ int16 index;
+ } _lastSample[2];
+
+ static const int16 _stepAdjustmentTable[8];
+ static const int32 _amplitudeLookupTable[89];
+
+public:
+ int readBuffer(int16 *buffer, const int numSamples);
+
+ bool isStereo() const { return true; }
+ bool endOfData() const { return _endOfData; }
+
+ int getRate() const { return _rate; }
+ Audio::Timestamp getLength() const { return _playtime; }
+
+ bool rewind();
+};
+
+/**
+ * Creates an audio stream, which plays from the given buffer.
+ *
+ * @param buffer Buffer to play from.
+ * @param size Size of the buffer in bytes.
+ * @param rate Rate of the sound data.
+ * @param dispose AfterUse Whether to free the buffer after use (with free!).
+ * @return The new SeekableAudioStream (or 0 on failure).
+ */
+Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+
+/**
+ * Creates an audio stream, which plays from the given stream.
+ *
+ * @param stream Stream object to play from.
+ * @param rate Rate of the sound data.
+ * @param dispose AfterUse Whether to delete the stream after use.
+ * @return The new SeekableAudioStream (or 0 on failure).
+ */
+Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+
+Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine);
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/strings/string_manager.cpp b/engines/zvision/strings/string_manager.cpp
new file mode 100644
index 0000000000..77ed501672
--- /dev/null
+++ b/engines/zvision/strings/string_manager.cpp
@@ -0,0 +1,255 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/strings/string_manager.h"
+
+#include "zvision/fonts/truetype_font.h"
+
+#include "common/file.h"
+#include "common/tokenizer.h"
+#include "common/debug.h"
+
+#include "graphics/fontman.h"
+#include "graphics/colormasks.h"
+
+
+namespace ZVision {
+
+StringManager::StringManager(ZVision *engine)
+ : _engine(engine) {
+}
+
+StringManager::~StringManager() {
+ for (Common::HashMap<Common::String, TruetypeFont *>::iterator iter = _fonts.begin(); iter != _fonts.end(); ++iter) {
+ delete iter->_value;
+ }
+}
+
+void StringManager::initialize(ZVisionGameId gameId) {
+ if (gameId == GID_NEMESIS) {
+ // TODO: Check this hardcoded filename against all versions of Nemesis
+ parseStrFile("nemesis.str");
+ } else if (gameId == GID_GRANDINQUISITOR) {
+ // TODO: Check this hardcoded filename against all versions of Grand Inquisitor
+ parseStrFile("inquis.str");
+ }
+}
+
+void StringManager::parseStrFile(const Common::String &fileName) {
+ Common::File file;
+ if (!file.open(fileName)) {
+ warning("%s does not exist. String parsing failed", fileName.c_str());
+ return;
+ }
+
+ uint lineNumber = 0;
+ while (!file.eos()) {
+ _lastStyle.align = Graphics::kTextAlignLeft;
+ _lastStyle.color = 0;
+ _lastStyle.font = nullptr;
+
+ Common::String asciiLine = readWideLine(file);
+ if (asciiLine.empty()) {
+ continue;
+ }
+
+ char tagString[150];
+ uint tagStringCursor = 0;
+ char textString[150];
+ uint textStringCursor = 0;
+ bool inTag = false;
+
+ for (uint i = 0; i < asciiLine.size(); ++i) {
+ switch (asciiLine[i]) {
+ case '<':
+ inTag = true;
+ if (!_inGameText[lineNumber].fragments.empty()) {
+ _inGameText[lineNumber].fragments.back().text = Common::String(textString, textStringCursor);
+ textStringCursor = 0;
+ }
+ break;
+ case '>':
+ inTag = false;
+ parseTag(Common::String(tagString, tagStringCursor), lineNumber);
+ tagStringCursor = 0;
+ break;
+ default:
+ if (inTag) {
+ tagString[tagStringCursor] = asciiLine[i];
+ tagStringCursor++;
+ } else {
+ textString[textStringCursor] = asciiLine[i];
+ textStringCursor++;
+ }
+ break;
+ }
+ }
+
+ if (textStringCursor > 0) {
+ _inGameText[lineNumber].fragments.back().text = Common::String(textString, textStringCursor);
+ }
+
+ lineNumber++;
+ assert(lineNumber <= NUM_TEXT_LINES);
+ }
+}
+
+void StringManager::parseTag(const Common::String &tagString, uint lineNumber) {
+ Common::StringTokenizer tokenizer(tagString);
+
+ Common::String token = tokenizer.nextToken();
+
+ Common::String fontName;
+ bool bold = false;
+ Graphics::TextAlign align = _lastStyle.align;
+ int point = _lastStyle.font != nullptr ? _lastStyle.font->_fontHeight : 12;
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+
+ while (!token.empty()) {
+ if (token.matchString("font", true)) {
+ fontName = tokenizer.nextToken();
+ } else if (token.matchString("bold", true)) {
+ token = tokenizer.nextToken();
+ if (token.matchString("on", false)) {
+ bold = true;
+ }
+ } else if (token.matchString("justify", true)) {
+ token = tokenizer.nextToken();
+ if (token.matchString("center", false)) {
+ align = Graphics::kTextAlignCenter;
+ } else if (token.matchString("right", false)) {
+ align = Graphics::kTextAlignRight;
+ }
+ } else if (token.matchString("point", true)) {
+ point = atoi(tokenizer.nextToken().c_str());
+ } else if (token.matchString("red", true)) {
+ red = atoi(tokenizer.nextToken().c_str());
+ } else if (token.matchString("green", true)) {
+ green = atoi(tokenizer.nextToken().c_str());
+ } else if (token.matchString("blue", true)) {
+ blue = atoi(tokenizer.nextToken().c_str());
+ }
+
+ token = tokenizer.nextToken();
+ }
+
+ TextFragment fragment;
+
+ if (fontName.empty()) {
+ fragment.style.font = _lastStyle.font;
+ } else {
+ Common::String newFontName;
+ if (fontName.matchString("*times new roman*", true)) {
+ if (bold) {
+ newFontName = "timesbd.ttf";
+ } else {
+ newFontName = "times.ttf";
+ }
+ } else if (fontName.matchString("*courier new*", true)) {
+ if (bold) {
+ newFontName = "courbd.ttf";
+ } else {
+ newFontName = "cour.ttf";
+ }
+ } else if (fontName.matchString("*century schoolbook*", true)) {
+ if (bold) {
+ newFontName = "censcbkbd.ttf";
+ } else {
+ newFontName = "censcbk.ttf";
+ }
+ } else if (fontName.matchString("*garamond*", true)) {
+ if (bold) {
+ newFontName = "garabd.ttf";
+ } else {
+ newFontName = "gara.ttf";
+ }
+ } else {
+ debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
+ if (bold) {
+ newFontName = "zorknorm.ttf";
+ } else {
+ newFontName = "arial.ttf";
+ }
+ }
+
+ Common::String fontKey = Common::String::format("%s-%d", newFontName.c_str(), point);
+ if (_fonts.contains(fontKey)) {
+ fragment.style.font = _fonts[fontKey];
+ } else {
+ fragment.style.font = new TruetypeFont(_engine, point);
+ fragment.style.font->loadFile(newFontName);
+ _fonts[fontKey] = fragment.style.font;
+ }
+ }
+
+ fragment.style.align = align;
+ fragment.style.color = Graphics::ARGBToColor<Graphics::ColorMasks<565> >(0, red, green, blue);
+ _inGameText[lineNumber].fragments.push_back(fragment);
+
+ _lastStyle = fragment.style;
+}
+
+Common::String StringManager::readWideLine(Common::SeekableReadStream &stream) {
+ Common::String asciiString;
+
+ // Don't spam the user with warnings about UTF-16 support.
+ // Just do one warning per String
+ bool charOverflowWarning = false;
+
+ uint16 value = stream.readUint16LE();
+ while (!stream.eos()) {
+ // Check for CRLF
+ if (value == 0x0A0D) {
+ // Read in the extra NULL char
+ stream.readByte(); // \0
+ // End of the line. Break
+ break;
+ }
+
+ // Crush each octet pair to a single octet with a simple cast
+ if (value > 255) {
+ charOverflowWarning = true;
+ value = '?';
+ }
+ char charValue = (char)value;
+
+ asciiString += charValue;
+
+ value = stream.readUint16LE();
+ }
+
+ if (charOverflowWarning) {
+ warning("UTF-16 is not supported. Characters greater than 255 are replaced with '?'");
+ }
+
+ return asciiString;
+}
+
+StringManager::TextStyle StringManager::getTextStyle(uint stringNumber) {
+ return _inGameText[stringNumber].fragments.front().style;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/strings/string_manager.h b/engines/zvision/strings/string_manager.h
new file mode 100644
index 0000000000..86bb9638d7
--- /dev/null
+++ b/engines/zvision/strings/string_manager.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZVISION_STRING_MANAGER_H
+#define ZVISION_STRING_MANAGER_H
+
+#include "zvision/detection.h"
+#include "zvision/fonts/truetype_font.h"
+
+
+namespace Graphics {
+class FontManager;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class StringManager {
+public:
+ StringManager(ZVision *engine);
+ ~StringManager();
+
+public:
+ struct TextStyle {
+ TruetypeFont *font;
+ uint16 color; // In RBG 565
+ Graphics::TextAlign align;
+ };
+
+ struct TextFragment {
+ TextStyle style;
+ Common::String text;
+ };
+
+private:
+ struct InGameText {
+ Common::List<TextFragment> fragments;
+ };
+
+ enum {
+ NUM_TEXT_LINES = 56 // Max number of lines in a .str file. We hardcode this number because we know ZNem uses 42 strings and ZGI uses 56
+ };
+
+private:
+ ZVision *_engine;
+ InGameText _inGameText[NUM_TEXT_LINES];
+ Common::HashMap<Common::String, TruetypeFont *> _fonts;
+
+ TextStyle _lastStyle;
+
+public:
+ void initialize(ZVisionGameId gameId);
+ StringManager::TextStyle getTextStyle(uint stringNumber);
+
+private:
+ void parseStrFile(const Common::String &fileName);
+ void parseTag(const Common::String &tagString, uint lineNumber);
+
+ static Common::String readWideLine(Common::SeekableReadStream &stream);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/subtitles/subtitles.h b/engines/zvision/subtitles/subtitles.h
new file mode 100644
index 0000000000..13426e03e4
--- /dev/null
+++ b/engines/zvision/subtitles/subtitles.h
@@ -0,0 +1,29 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZVISION_SUBTITLES_H
+#define ZVISION_SUBTITLES_H
+
+// TODO: Implement Subtitles
+
+#endif
diff --git a/engines/zvision/utility/clock.cpp b/engines/zvision/utility/clock.cpp
new file mode 100644
index 0000000000..49e4b32054
--- /dev/null
+++ b/engines/zvision/utility/clock.cpp
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/utility/clock.h"
+
+#include "common/system.h"
+
+
+namespace ZVision {
+
+Clock::Clock(OSystem *system)
+ : _system(system),
+ _lastTime(0),
+ _deltaTime(0),
+ _pausedTime(0),
+ _paused(false) {
+}
+
+void Clock::update() {
+ uint32 currentTime = _system->getMillis();
+
+ _deltaTime = (currentTime - _lastTime);
+ if (_paused) {
+ _deltaTime -= (currentTime - _pausedTime);
+ }
+
+ if (_deltaTime < 0) {
+ _deltaTime = 0;
+ }
+
+ _lastTime = currentTime;
+}
+
+void Clock::start() {
+ if (_paused) {
+ _lastTime = _system->getMillis();
+ _paused = false;
+ }
+}
+
+void Clock::stop() {
+ if (!_paused) {
+ _pausedTime = _system->getMillis();
+ _paused = true;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/clock.h b/engines/zvision/utility/clock.h
new file mode 100644
index 0000000000..3939ba1612
--- /dev/null
+++ b/engines/zvision/utility/clock.h
@@ -0,0 +1,78 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZVISION_CLOCK_H
+#define ZVISION_CLOCK_H
+
+#include "common/types.h"
+
+class OSystem;
+
+namespace ZVision {
+
+/* Class for handling frame to frame deltaTime while keeping track of time pauses/un-pauses */
+class Clock {
+public:
+ Clock(OSystem *system);
+
+private:
+ OSystem *_system;
+ uint32 _lastTime;
+ int32 _deltaTime;
+ uint32 _pausedTime;
+ bool _paused;
+
+public:
+ /**
+ * Updates _deltaTime with the difference between the current time and
+ * when the last update() was called.
+ */
+ void update();
+ /**
+ * Get the delta time since the last frame. (The time between update() calls)
+ *
+ * @return Delta time since the last frame (in milliseconds)
+ */
+ uint32 getDeltaTime() const { return _deltaTime; }
+ /**
+ * Get the time from the program starting to the last update() call
+ *
+ * @return Time from program start to last update() call (in milliseconds)
+ */
+ uint32 getLastMeasuredTime() { return _lastTime; }
+
+ /**
+ * Pause the clock. Any future delta times will take this pause into account.
+ * Has no effect if the clock is already paused.
+ */
+ void start();
+ /**
+ * Un-pause the clock.
+ * Has no effect if the clock is already un-paused.
+ */
+ void stop();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/utility/lzss_read_stream.cpp b/engines/zvision/utility/lzss_read_stream.cpp
new file mode 100644
index 0000000000..dc537cd8ab
--- /dev/null
+++ b/engines/zvision/utility/lzss_read_stream.cpp
@@ -0,0 +1,103 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/utility/lzss_read_stream.h"
+
+
+namespace ZVision {
+
+LzssReadStream::LzssReadStream(Common::SeekableReadStream *source)
+ : _source(source),
+ // It's convention to set the starting cursor position to blockSize - 16
+ _windowCursor(0x0FEE),
+ _eosFlag(false) {
+ // Clear the window to null
+ memset(_window, 0, BLOCK_SIZE);
+}
+
+uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) {
+ uint32 destinationCursor = 0;
+
+ while (destinationCursor < numberOfBytes) {
+ byte flagbyte = _source->readByte();
+ if (_source->eos())
+ break;
+ uint mask = 1;
+
+ for (int i = 0; i < 8; ++i) {
+ if ((flagbyte & mask) == mask) {
+ byte data = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ _window[_windowCursor] = data;
+ destination[destinationCursor++] = data;
+
+ // Increment and wrap the window cursor
+ _windowCursor = (_windowCursor + 1) & 0xFFF;
+ } else {
+ byte low = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ byte high = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ uint16 length = (high & 0xF) + 2;
+ uint16 offset = low | ((high & 0xF0)<<4);
+
+ for(int j = 0; j <= length; ++j) {
+ byte temp = _window[(offset + j) & 0xFFF];
+ _window[_windowCursor] = temp;
+ destination[destinationCursor++] = temp;
+ _windowCursor = (_windowCursor + 1) & 0xFFF;
+ }
+ }
+
+ mask = mask << 1;
+ }
+ }
+
+ return destinationCursor;
+}
+
+bool LzssReadStream::eos() const {
+ return _eosFlag;
+}
+
+uint32 LzssReadStream::read(void *dataPtr, uint32 dataSize) {
+ uint32 bytesRead = decompressBytes(static_cast<byte *>(dataPtr), dataSize);
+ if (bytesRead < dataSize) {
+ // Flag that we're at EOS
+ _eosFlag = true;
+ }
+
+ return dataSize;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/lzss_read_stream.h b/engines/zvision/utility/lzss_read_stream.h
new file mode 100644
index 0000000000..f6b1eb1a65
--- /dev/null
+++ b/engines/zvision/utility/lzss_read_stream.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef ZVISION_LZSS_STREAM_H
+#define ZVISION_LZSS_STREAM_H
+
+#include "common/stream.h"
+#include "common/array.h"
+
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class LzssReadStream : public Common::ReadStream {
+public:
+ /**
+ * A class that decompresses LZSS data and implements ReadStream for easy access
+ * to the decompiled data.
+ *
+ * @param source The source data
+ */
+ LzssReadStream(Common::SeekableReadStream *source);
+
+private:
+ enum {
+ BLOCK_SIZE = 0x1000
+ };
+
+private:
+ Common::SeekableReadStream *_source;
+ byte _window[BLOCK_SIZE];
+ uint _windowCursor;
+ bool _eosFlag;
+
+public:
+ bool eos() const;
+ uint32 read(void *dataPtr, uint32 dataSize);
+
+private:
+ /**
+ * Decompress the next <numberOfBytes> from the source stream. Or until EOS
+ *
+ * @param numberOfBytes How many bytes to decompress. This is a count of source bytes, not destination bytes
+ */
+ uint32 decompressBytes(byte* destination, uint32 numberOfBytes);
+};
+
+}
+
+#endif
diff --git a/engines/zvision/utility/single_value_container.cpp b/engines/zvision/utility/single_value_container.cpp
new file mode 100644
index 0000000000..2667b27b75
--- /dev/null
+++ b/engines/zvision/utility/single_value_container.cpp
@@ -0,0 +1,348 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/utility/single_value_container.h"
+
+#include "common/textconsole.h"
+#include "common/str.h"
+
+
+namespace ZVision {
+
+SingleValueContainer::SingleValueContainer(ValueType type) : _objectType(type) { }
+
+SingleValueContainer::SingleValueContainer(bool value) : _objectType(BOOL) {
+ _value.boolVal = value;
+}
+
+SingleValueContainer::SingleValueContainer(byte value) : _objectType(BYTE) {
+ _value.byteVal = value;
+}
+
+SingleValueContainer::SingleValueContainer(int16 value) : _objectType(INT16) {
+ _value.int16Val = value;
+}
+
+SingleValueContainer::SingleValueContainer(uint16 value) : _objectType(UINT16) {
+ _value.uint16Val = value;
+}
+
+SingleValueContainer::SingleValueContainer(int32 value) : _objectType(INT32) {
+ _value.int32Val = value;
+}
+
+SingleValueContainer::SingleValueContainer(uint32 value) : _objectType(UINT32) {
+ _value.uint32Val = value;
+}
+
+SingleValueContainer::SingleValueContainer(float value) : _objectType(FLOAT) {
+ _value.floatVal = value;
+}
+
+SingleValueContainer::SingleValueContainer(double value) : _objectType(DOUBLE) {
+ _value.doubleVal = value;
+}
+
+SingleValueContainer::SingleValueContainer(Common::String value) : _objectType(BYTE) {
+ _value.stringVal = new char[value.size() + 1];
+ memcpy(_value.stringVal, value.c_str(), value.size() + 1);
+}
+
+SingleValueContainer::SingleValueContainer(const SingleValueContainer &other) {
+ _objectType = other._objectType;
+
+ switch (_objectType) {
+ case BOOL:
+ _value.boolVal = other._value.boolVal;
+ break;
+ case BYTE:
+ _value.byteVal = other._value.byteVal;
+ break;
+ case INT16:
+ _value.int16Val = other._value.int16Val;
+ break;
+ case UINT16:
+ _value.uint16Val = other._value.uint16Val;
+ break;
+ case INT32:
+ _value.int32Val = other._value.int32Val;
+ break;
+ case UINT32:
+ _value.uint32Val = other._value.uint32Val;
+ break;
+ case FLOAT:
+ _value.floatVal = other._value.floatVal;
+ break;
+ case DOUBLE:
+ _value.doubleVal = other._value.doubleVal;
+ break;
+ case STRING:
+ uint32 length = strlen(other._value.stringVal);
+ _value.stringVal = new char[length + 1];
+ memcpy(_value.stringVal, other._value.stringVal, length + 1);
+ break;
+ }
+}
+
+SingleValueContainer::~SingleValueContainer() {
+ deleteCharPointer();
+}
+
+void SingleValueContainer::deleteCharPointer() {
+ if (_objectType == STRING)
+ delete[] _value.stringVal;
+}
+
+
+SingleValueContainer &SingleValueContainer::operator=(const bool &rhs) {
+ if (_objectType == BOOL) {
+ _value.boolVal = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = BOOL;
+ _value.boolVal = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const byte &rhs) {
+ if (_objectType == BYTE) {
+ _value.byteVal = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = BYTE;
+ _value.byteVal = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const int16 &rhs) {
+ if (_objectType == INT16) {
+ _value.int16Val = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = INT16;
+ _value.int16Val = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const uint16 &rhs) {
+ if (_objectType == UINT16) {
+ _value.uint16Val = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = UINT16;
+ _value.uint16Val = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const int32 &rhs) {
+ if (_objectType == INT32) {
+ _value.int32Val = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = INT32;
+ _value.int32Val = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const uint32 &rhs) {
+ if (_objectType == UINT32) {
+ _value.uint32Val = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = UINT32;
+ _value.uint32Val = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const float &rhs) {
+ if (_objectType == FLOAT) {
+ _value.floatVal = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = FLOAT;
+ _value.floatVal = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const double &rhs) {
+ if (_objectType == DOUBLE) {
+ _value.doubleVal = rhs;
+ return *this;
+ }
+
+ deleteCharPointer();
+ _objectType = DOUBLE;
+ _value.doubleVal = rhs;
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const Common::String &rhs) {
+ if (_objectType != STRING) {
+ _objectType = STRING;
+ _value.stringVal = new char[rhs.size() + 1];
+ memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
+
+ return *this;
+ }
+
+ uint32 length = strlen(_value.stringVal);
+ if (length <= rhs.size() + 1) {
+ memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
+ } else {
+ delete[] _value.stringVal;
+ _value.stringVal = new char[rhs.size() + 1];
+ memcpy(_value.stringVal, rhs.c_str(), rhs.size() + 1);
+ }
+
+ return *this;
+}
+
+SingleValueContainer &SingleValueContainer::operator=(const SingleValueContainer &rhs) {
+ switch (_objectType) {
+ case BOOL:
+ return operator=(rhs._value.boolVal);
+ case BYTE:
+ return operator=(rhs._value.byteVal);
+ case INT16:
+ return operator=(rhs._value.int16Val);
+ case UINT16:
+ return operator=(rhs._value.uint16Val);
+ case INT32:
+ return operator=(rhs._value.int32Val);
+ case UINT32:
+ return operator=(rhs._value.uint32Val);
+ case FLOAT:
+ return operator=(rhs._value.floatVal);
+ case DOUBLE:
+ return operator=(rhs._value.doubleVal);
+ case STRING:
+ uint32 length = strlen(rhs._value.stringVal);
+
+ _value.stringVal = new char[length + 1];
+ memcpy(_value.stringVal, rhs._value.stringVal, length + 1);
+
+ return *this;
+ }
+
+ return *this;
+}
+
+
+bool SingleValueContainer::getBoolValue(bool *returnValue) const {
+ if (_objectType != BOOL) {
+ warning("'Object' is not storing a bool.");
+ return false;
+ }
+
+ *returnValue = _value.boolVal;
+ return true;
+}
+
+bool SingleValueContainer::getByteValue(byte *returnValue) const {
+ if (_objectType != BYTE)
+ warning("'Object' is not storing a byte.");
+
+ *returnValue = _value.byteVal;
+ return true;
+}
+
+bool SingleValueContainer::getInt16Value(int16 *returnValue) const {
+ if (_objectType != INT16)
+ warning("'Object' is not storing an int16.");
+
+ *returnValue = _value.int16Val;
+ return true;
+}
+
+bool SingleValueContainer::getUInt16Value(uint16 *returnValue) const {
+ if (_objectType != UINT16)
+ warning("'Object' is not storing a uint16.");
+
+ *returnValue = _value.uint16Val;
+ return true;
+}
+
+bool SingleValueContainer::getInt32Value(int32 *returnValue) const {
+ if (_objectType != INT32)
+ warning("'Object' is not storing an int32.");
+
+ *returnValue = _value.int32Val;
+ return true;
+}
+
+bool SingleValueContainer::getUInt32Value(uint32 *returnValue) const {
+ if (_objectType != UINT32)
+ warning("'Object' is not storing a uint32.");
+
+ *returnValue = _value.uint32Val;
+ return true;
+}
+
+bool SingleValueContainer::getFloatValue(float *returnValue) const {
+ if (_objectType != FLOAT)
+ warning("'Object' is not storing a float.");
+
+ *returnValue = _value.floatVal;
+ return true;
+}
+
+bool SingleValueContainer::getDoubleValue(double *returnValue) const {
+ if (_objectType != DOUBLE)
+ warning("'Object' is not storing a double.");
+
+ *returnValue = _value.doubleVal;
+ return true;
+}
+
+bool SingleValueContainer::getStringValue(Common::String *returnValue) const {
+ if (_objectType != STRING)
+ warning("'Object' is not storing a Common::String.");
+
+ *returnValue = _value.stringVal;
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/single_value_container.h b/engines/zvision/utility/single_value_container.h
new file mode 100644
index 0000000000..45b5a89e95
--- /dev/null
+++ b/engines/zvision/utility/single_value_container.h
@@ -0,0 +1,183 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_SINGLE_VALUE_CONTAINER_H
+#define ZVISION_SINGLE_VALUE_CONTAINER_H
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+/**
+ * A generic single value storage class. It is useful for storing different
+ * value types in a single List, Hashmap, etc.
+ */
+class SingleValueContainer {
+public:
+ enum ValueType {
+ BOOL,
+ BYTE,
+ INT16,
+ UINT16,
+ INT32,
+ UINT32,
+ FLOAT,
+ DOUBLE,
+ STRING
+ };
+
+ // Constructors
+ explicit SingleValueContainer(ValueType type);
+ explicit SingleValueContainer(bool value);
+ explicit SingleValueContainer(byte value);
+ explicit SingleValueContainer(int16 value);
+ explicit SingleValueContainer(uint16 value);
+ explicit SingleValueContainer(int32 value);
+ explicit SingleValueContainer(uint32 value);
+ explicit SingleValueContainer(float value);
+ explicit SingleValueContainer(double value);
+ explicit SingleValueContainer(Common::String value);
+
+ // Copy constructor
+ explicit SingleValueContainer(const SingleValueContainer& other);
+
+ // Destructor
+ ~SingleValueContainer();
+
+private:
+ ValueType _objectType;
+
+ union {
+ bool boolVal;
+ byte byteVal;
+ int16 int16Val;
+ uint16 uint16Val;
+ int32 int32Val;
+ uint32 uint32Val;
+ float floatVal;
+ double doubleVal;
+ char *stringVal;
+ } _value;
+
+public:
+ SingleValueContainer &operator=(const bool &rhs);
+ SingleValueContainer &operator=(const byte &rhs);
+ SingleValueContainer &operator=(const int16 &rhs);
+ SingleValueContainer &operator=(const uint16 &rhs);
+ SingleValueContainer &operator=(const int32 &rhs);
+ SingleValueContainer &operator=(const uint32 &rhs);
+ SingleValueContainer &operator=(const float &rhs);
+ SingleValueContainer &operator=(const double &rhs);
+ SingleValueContainer &operator=(const Common::String &rhs);
+
+ SingleValueContainer& operator=(const SingleValueContainer &rhs);
+
+ /**
+ * Retrieve a bool from the container. If the container is not storing a
+ * bool, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getBoolValue(bool *returnValue) const;
+ /**
+ * Retrieve a byte from the container. If the container is not storing a
+ * byte, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getByteValue(byte *returnValue) const;
+ /**
+ * Retrieve an int16 from the container. If the container is not storing an
+ * int16, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getInt16Value(int16 *returnValue) const;
+ /**
+ * Retrieve a uint16 from the container. If the container is not storing a
+ * uint16, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getUInt16Value(uint16 *returnValue) const;
+ /**
+ * Retrieve an int32 from the container. If the container is not storing an
+ * int32, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getInt32Value(int32 *returnValue) const;
+ /**
+ * Retrieve a uint32 from the container. If the container is not storing a
+ * uint32, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getUInt32Value(uint32 *returnValue) const;
+ /**
+ * Retrieve a float from the container. If the container is not storing a
+ * float, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getFloatValue(float *returnValue) const;
+ /**
+ * Retrieve a double from the container. If the container is not storing a
+ * double, this will return false and display a warning().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getDoubleValue(double *returnValue) const;
+ /**
+ * Retrieve a String from the container. If the container is not storing a
+ * string, this will return false and display a warning().
+ *
+ * Caution: Strings are internally stored as char[]. getStringValue uses
+ * Common::String::operator=(char *) to do the assigment, which uses both
+ * strlen() AND memmove().
+ *
+ * @param returnValue Pointer to where you want the value stored
+ * @return Value indicating whether the value assignment was successful
+ */
+ bool getStringValue(Common::String *returnValue) const;
+
+private:
+ /**
+ * Helper method for destruction and assignment. It checks to see
+ * if the char pointer is being used, and if so calls delete on it
+ */
+ void deleteCharPointer();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/utility/utility.cpp b/engines/zvision/utility/utility.cpp
new file mode 100644
index 0000000000..6471d21e6c
--- /dev/null
+++ b/engines/zvision/utility/utility.cpp
@@ -0,0 +1,237 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/utility/utility.h"
+
+#include "zvision/zvision.h"
+#include "zvision/sound/zork_raw.h"
+
+#include "common/tokenizer.h"
+#include "common/file.h"
+
+
+namespace ZVision {
+
+void writeFileContentsToFile(const Common::String &sourceFile, const Common::String &destFile) {
+ Common::File f;
+ if (!f.open(sourceFile)) {
+ return;
+ }
+
+ byte* buffer = new byte[f.size()];
+ f.read(buffer, f.size());
+
+ Common::DumpFile dumpFile;
+ dumpFile.open(destFile);
+
+ dumpFile.write(buffer, f.size());
+ dumpFile.flush();
+ dumpFile.close();
+
+ delete[] buffer;
+}
+
+void trimCommentsAndWhiteSpace(Common::String *string) {
+ for (int i = string->size() - 1; i >= 0; i--) {
+ if ((*string)[i] == '#') {
+ string->erase(i);
+ }
+ }
+
+ string->trim();
+}
+
+void tryToDumpLine(const Common::String &key,
+ Common::String &line,
+ Common::HashMap<Common::String, byte> *count,
+ Common::HashMap<Common::String, bool> *fileAlreadyUsed,
+ Common::DumpFile &output) {
+ const byte numberOfExamplesPerType = 8;
+
+ if ((*count)[key] < numberOfExamplesPerType && !(*fileAlreadyUsed)[key]) {
+ output.writeString(line);
+ output.writeByte('\n');
+ (*count)[key]++;
+ (*fileAlreadyUsed)[key] = true;
+ }
+}
+
+void dumpEveryResultAction(const Common::String &destFile) {
+ Common::HashMap<Common::String, byte> count;
+ Common::HashMap<Common::String, bool> fileAlreadyUsed;
+
+ Common::DumpFile output;
+ output.open(destFile);
+
+ // Find scr files
+ Common::ArchiveMemberList list;
+ SearchMan.listMatchingMembers(list, "*.scr");
+
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ Common::SeekableReadStream *stream = (*iter)->createReadStream();
+
+ Common::String line = stream->readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream->eos()) {
+ if (line.matchString("*:add*", true)) {
+ tryToDumpLine("add", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:animplay*", true)) {
+ tryToDumpLine("animplay", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:animpreload*", true)) {
+ tryToDumpLine("animpreload", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:animunload*", true)) {
+ tryToDumpLine("animunload", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:attenuate*", true)) {
+ tryToDumpLine("attenuate", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:assign*", true)) {
+ tryToDumpLine("assign", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:change_location*", true)) {
+ tryToDumpLine("change_location", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:crossfade*", true) && !fileAlreadyUsed["add"]) {
+ tryToDumpLine("crossfade", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:debug*", true)) {
+ tryToDumpLine("debug", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:delay_render*", true)) {
+ tryToDumpLine("delay_render", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:disable_control*", true)) {
+ tryToDumpLine("disable_control", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:disable_venus*", true)) {
+ tryToDumpLine("disable_venus", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:display_message*", true)) {
+ tryToDumpLine("display_message", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:dissolve*", true)) {
+ tryToDumpLine("dissolve", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:distort*", true)) {
+ tryToDumpLine("distort", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:enable_control*", true)) {
+ tryToDumpLine("enable_control", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:flush_mouse_events*", true)) {
+ tryToDumpLine("flush_mouse_events", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:inventory*", true)) {
+ tryToDumpLine("inventory", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:kill*", true)) {
+ tryToDumpLine("kill", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:menu_bar_enable*", true)) {
+ tryToDumpLine("menu_bar_enable", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:music*", true)) {
+ tryToDumpLine("music", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:pan_track*", true)) {
+ tryToDumpLine("pan_track", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:playpreload*", true)) {
+ tryToDumpLine("playpreload", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:preferences*", true)) {
+ tryToDumpLine("preferences", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:quit*", true)) {
+ tryToDumpLine("quit", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:random*", true)) {
+ tryToDumpLine("random", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:region*", true)) {
+ tryToDumpLine("region", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:restore_game*", true)) {
+ tryToDumpLine("restore_game", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:rotate_to*", true)) {
+ tryToDumpLine("rotate_to", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:save_game*", true)) {
+ tryToDumpLine("save_game", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:set_partial_screen*", true)) {
+ tryToDumpLine("set_partial_screen", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:set_screen*", true)) {
+ tryToDumpLine("set_screen", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:set_venus*", true)) {
+ tryToDumpLine("set_venus", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:stop*", true)) {
+ tryToDumpLine("stop", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:streamvideo*", true)) {
+ tryToDumpLine("streamvideo", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:syncsound*", true)) {
+ tryToDumpLine("syncsound", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:timer*", true)) {
+ tryToDumpLine("timer", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:ttytext*", true)) {
+ tryToDumpLine("ttytext", line, &count, &fileAlreadyUsed, output);
+ } else if (line.matchString("*:universe_music*", true)) {
+ tryToDumpLine("universe_music", line, &count, &fileAlreadyUsed, output);
+ }
+
+ line = stream->readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ for (Common::HashMap<Common::String, bool>::iterator fileUsedIter = fileAlreadyUsed.begin(); fileUsedIter != fileAlreadyUsed.end(); ++fileUsedIter) {
+ fileUsedIter->_value = false;
+ }
+ }
+
+ output.close();
+}
+
+Common::String getFileName(const Common::String &fullPath) {
+ Common::StringTokenizer tokenizer(fullPath, "/\\");
+ Common::String token;
+ while (!tokenizer.empty()) {
+ token = tokenizer.nextToken();
+ }
+
+ return token;
+}
+
+void convertRawToWav(const Common::String &inputFile, ZVision *engine, const Common::String &outputFile) {
+ Common::File file;
+ if (!file.open(inputFile))
+ return;
+
+ Audio::AudioStream *audioStream = makeRawZorkStream(inputFile, engine);
+
+ Common::DumpFile output;
+ output.open(outputFile);
+
+ output.writeUint32BE(MKTAG('R', 'I', 'F', 'F'));
+ output.writeUint32LE(file.size() * 2 + 36);
+ output.writeUint32BE(MKTAG('W', 'A', 'V', 'E'));
+ output.writeUint32BE(MKTAG('f', 'm', 't', ' '));
+ output.writeUint32LE(16);
+ output.writeUint16LE(1);
+ uint16 numChannels;
+ if (audioStream->isStereo()) {
+ numChannels = 2;
+ output.writeUint16LE(2);
+ } else {
+ numChannels = 1;
+ output.writeUint16LE(1);
+ }
+ output.writeUint32LE(audioStream->getRate());
+ output.writeUint32LE(audioStream->getRate() * numChannels * 2);
+ output.writeUint16LE(numChannels * 2);
+ output.writeUint16LE(16);
+ output.writeUint32BE(MKTAG('d', 'a', 't', 'a'));
+ output.writeUint32LE(file.size() * 2);
+ int16 *buffer = new int16[file.size()];
+ audioStream->readBuffer(buffer, file.size());
+ output.write(buffer, file.size() * 2);
+
+ delete[] buffer;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/utility.h b/engines/zvision/utility/utility.h
new file mode 100644
index 0000000000..fb571f3fe8
--- /dev/null
+++ b/engines/zvision/utility/utility.h
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZVISION_UTILITY_H
+#define ZVISION_UTILITY_H
+
+#include "common/array.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+/**
+ * Opens the sourceFile utilizing Common::File (aka SearchMan) and writes the
+ * contents to destFile. destFile is created in the working directory
+ *
+ * @param sourceFile The 'file' you want the contents of
+ * @param destFile The name of the file where the content will be written to
+ */
+void writeFileContentsToFile(const Common::String &sourceFile, const Common::String &destFile);
+
+/**
+ * Removes any line comments using '#' as a sequence start.
+ * Then removes any trailing and leading 'whitespace' using String::trim()
+ * Note: String::trim uses isspace() to determine what is whitespace and what is not.
+ *
+ * @param string The string to modify. It is modified in place
+ */
+void trimCommentsAndWhiteSpace(Common::String *string);
+
+/**
+ * Searches through all the .scr files and dumps 'numberOfExamplesPerType' examples of each type of ResultAction
+ * ZVision::initialize() must have been called before this function can be used.
+ *
+ * @param destFile Where to write the examples
+ */
+void dumpEveryResultAction(const Common::String &destFile);
+
+/**
+ * Removes all duplicate entries from container. Relative order will be preserved.
+ *
+ * @param container The Array to remove duplicate entries from
+ */
+template<class T>
+void removeDuplicateEntries(Common::Array<T> &container) {
+ // Length of modified array
+ uint newLength = 1;
+ uint j;
+
+ for(uint i = 1; i < container.size(); i++) {
+ for(j = 0; j < newLength; j++) {
+ if (container[i] == container[j]) {
+ break;
+ }
+ }
+
+ // If none of the values in index[0..j] of container are the same as array[i],
+ // then copy the current value to corresponding new position in array
+ if (j == newLength) {
+ container[newLength++] = container[i];
+ }
+ }
+
+ // Actually remove the unneeded space
+ while (container.size() < newLength) {
+ container.pop_back();
+ }
+}
+
+/**
+ * Gets the name of the file (including extension). Forward or back slashes
+ * are interpreted as directory changes
+ *
+ * @param fullPath A full or partial path to the file. Ex: folderOne/folderTwo/file.txt
+ * @return The name of the file without any preceding directories. Ex: file.txt
+ */
+Common::String getFileName(const Common::String &fullPath);
+
+/**
+ * Converts a ZVision .RAW file to a .WAV
+ * The .WAV will be created in the working directory and will overwrite any existing file
+ *
+ * @param inputFile The path to the input .RAW file
+ * @param outputFile The name of the output .WAV file
+ */
+void convertRawToWav(const Common::String &inputFile, ZVision *engine, const Common::String &outputFile);
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
new file mode 100644
index 0000000000..efaecb5045
--- /dev/null
+++ b/engines/zvision/video/video.cpp
@@ -0,0 +1,171 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+
+#include "zvision/utility/clock.h"
+#include "zvision/graphics/render_manager.h"
+
+#include "common/system.h"
+
+#include "video/video_decoder.h"
+
+#include "engines/util.h"
+
+#include "graphics/surface.h"
+
+
+namespace ZVision {
+
+// Taken/modified from SCI
+void scaleBuffer(const byte *src, byte *dst, uint32 srcWidth, uint32 srcHeight, byte bytesPerPixel, uint scaleAmount) {
+ assert(bytesPerPixel == 1 || bytesPerPixel == 2);
+
+ const uint32 newWidth = srcWidth * scaleAmount;
+ const uint32 pitch = newWidth * bytesPerPixel;
+ const byte *srcPtr = src;
+
+ if (bytesPerPixel == 1) {
+ for (uint32 y = 0; y < srcHeight; ++y) {
+ for (uint32 x = 0; x < srcWidth; ++x) {
+ const byte color = *srcPtr++;
+
+ for (uint i = 0; i < scaleAmount; ++i) {
+ dst[i] = color;
+ dst[pitch + i] = color;
+ }
+ dst += scaleAmount;
+ }
+ dst += pitch;
+ }
+ } else if (bytesPerPixel == 2) {
+ for (uint32 y = 0; y < srcHeight; ++y) {
+ for (uint32 x = 0; x < srcWidth; ++x) {
+ const byte color = *srcPtr++;
+ const byte color2 = *srcPtr++;
+
+ for (uint i = 0; i < scaleAmount; ++i) {
+ uint index = i *2;
+
+ dst[index] = color;
+ dst[index + 1] = color2;
+ dst[pitch + index] = color;
+ dst[pitch + index + 1] = color2;
+ }
+ dst += 2 * scaleAmount;
+ }
+ dst += pitch;
+ }
+ }
+}
+
+void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect, bool skippable) {
+ byte bytesPerPixel = videoDecoder.getPixelFormat().bytesPerPixel;
+
+ uint16 origWidth = videoDecoder.getWidth();
+ uint16 origHeight = videoDecoder.getHeight();
+
+ uint scale = 1;
+ // If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
+ if (destRect.isEmpty()) {
+ // Most videos are very small. Therefore we do a simple 2x scale
+ if (origWidth * 2 <= 640 && origHeight * 2 <= 480) {
+ scale = 2;
+ }
+ } else {
+ // Assume bilinear scaling. AKA calculate the scale from just the width.
+ // Also assume that the scaling is in integral intervals. AKA no 1.5x scaling
+ // TODO: Test ^these^ assumptions
+ scale = destRect.width() / origWidth;
+
+ // TODO: Test if we need to support downscale.
+ }
+
+ uint16 pitch = origWidth * bytesPerPixel;
+
+ uint16 finalWidth = origWidth * scale;
+ uint16 finalHeight = origHeight * scale;
+
+ byte *scaledVideoFrameBuffer = 0;
+ if (scale != 1) {
+ scaledVideoFrameBuffer = new byte[finalWidth * finalHeight * bytesPerPixel];
+ }
+
+ uint16 x = ((WINDOW_WIDTH - finalWidth) / 2) + destRect.left;
+ uint16 y = ((WINDOW_HEIGHT - finalHeight) / 2) + destRect.top;
+
+ _clock.stop();
+ videoDecoder.start();
+
+ // Only continue while the video is still playing
+ while (!shouldQuit() && !videoDecoder.endOfVideo() && videoDecoder.isPlaying()) {
+ // Check for engine quit and video stop key presses
+ while (!videoDecoder.endOfVideo() && videoDecoder.isPlaying() && _eventMan->pollEvent(_event)) {
+ switch (_event.type) {
+ case Common::EVENT_KEYDOWN:
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_q:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL))
+ quitGame();
+ break;
+ case Common::KEYCODE_SPACE:
+ if (skippable) {
+ videoDecoder.stop();
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (videoDecoder.needsUpdate()) {
+ const Graphics::Surface *frame = videoDecoder.decodeNextFrame();
+
+ if (frame) {
+ if (scale != 1) {
+ scaleBuffer((const byte *)frame->getPixels(), scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel, scale);
+ _system->copyRectToScreen(scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
+ } else {
+ _system->copyRectToScreen((const byte *)frame->getPixels(), pitch, x, y, finalWidth, finalHeight);
+ }
+ }
+ }
+
+ // Always update the screen so the mouse continues to render
+ _system->updateScreen();
+
+ _system->delayMillis(videoDecoder.getTimeToNextFrame());
+ }
+
+ _clock.start();
+
+ if (scale != 1) {
+ delete[] scaledVideoFrameBuffer;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
new file mode 100644
index 0000000000..d3db3421af
--- /dev/null
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/video/zork_avi_decoder.h"
+
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+
+#include "audio/audiostream.h"
+
+
+namespace ZVision {
+
+Video::AVIDecoder::AVIAudioTrack *ZorkAVIDecoder::createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo) {
+ ZorkAVIDecoder::ZorkAVIAudioTrack *audioTrack = new ZorkAVIDecoder::ZorkAVIAudioTrack(sHeader, wvInfo, _soundType);
+ return (Video::AVIDecoder::AVIAudioTrack *)audioTrack;
+}
+
+void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
+ if (_audStream) {
+ if (_wvInfo.tag == kWaveFormatZorkPCM) {
+ assert(_wvInfo.size == 8);
+ _audStream->queueAudioStream(makeRawZorkStream(stream, _wvInfo.samplesPerSec, _audStream->isStereo(), DisposeAfterUse::YES), DisposeAfterUse::YES);
+ }
+ } else {
+ delete stream;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/video/zork_avi_decoder.h b/engines/zvision/video/zork_avi_decoder.h
new file mode 100644
index 0000000000..ec2be1bb13
--- /dev/null
+++ b/engines/zvision/video/zork_avi_decoder.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZORK_AVI_DECODER_H
+#define ZORK_AVI_DECODER_H
+
+#include "video/avi_decoder.h"
+
+
+namespace ZVision {
+
+class ZorkAVIDecoder : public Video::AVIDecoder {
+public:
+ ZorkAVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType) :
+ Video::AVIDecoder(soundType) {}
+
+ virtual ~ZorkAVIDecoder() {}
+
+private:
+ class ZorkAVIAudioTrack : public Video::AVIDecoder::AVIAudioTrack {
+ public:
+ ZorkAVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType) :
+ Video::AVIDecoder::AVIAudioTrack(streamHeader, waveFormat, soundType) {}
+ virtual ~ZorkAVIAudioTrack() {}
+
+ void queueSound(Common::SeekableReadStream *stream);
+ };
+
+ Video::AVIDecoder::AVIAudioTrack *createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo);
+
+private:
+ // Audio Codecs
+ enum {
+ kWaveFormatZorkPCM = 17 // special Zork PCM audio format (clashes with MS IMA ADPCM)
+ };
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
new file mode 100644
index 0000000000..f57e225ac1
--- /dev/null
+++ b/engines/zvision/zvision.cpp
@@ -0,0 +1,184 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zvision.h"
+
+#include "zvision/core/console.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/core/save_manager.h"
+#include "zvision/strings/string_manager.h"
+#include "zvision/archives/zfs_archive.h"
+#include "zvision/detection.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/textconsole.h"
+#include "common/error.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "engines/util.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+ZVision::ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc)
+ : Engine(syst),
+ _gameDescription(gameDesc),
+ _workingWindow(gameDesc->gameId == GID_NEMESIS ? Common::Rect((WINDOW_WIDTH - ZNEM_WORKING_WINDOW_WIDTH) / 2, (WINDOW_HEIGHT - ZNEM_WORKING_WINDOW_HEIGHT) / 2, ((WINDOW_WIDTH - ZNEM_WORKING_WINDOW_WIDTH) / 2) + ZNEM_WORKING_WINDOW_WIDTH, ((WINDOW_HEIGHT - ZNEM_WORKING_WINDOW_HEIGHT) / 2) + ZNEM_WORKING_WINDOW_HEIGHT) :
+ Common::Rect((WINDOW_WIDTH - ZGI_WORKING_WINDOW_WIDTH) / 2, (WINDOW_HEIGHT - ZGI_WORKING_WINDOW_HEIGHT) / 2, ((WINDOW_WIDTH - ZGI_WORKING_WINDOW_WIDTH) / 2) + ZGI_WORKING_WINDOW_WIDTH, ((WINDOW_HEIGHT - ZGI_WORKING_WINDOW_HEIGHT) / 2) + ZGI_WORKING_WINDOW_HEIGHT)),
+ _pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), /*RGB 565*/
+ _desiredFrameTime(33), /* ~30 fps */
+ _clock(_system),
+ _scriptManager(nullptr),
+ _renderManager(nullptr),
+ _saveManager(nullptr),
+ _stringManager(nullptr),
+ _cursorManager(nullptr) {
+
+ debug(1, "ZVision::ZVision");
+}
+
+ZVision::~ZVision() {
+ debug(1, "ZVision::~ZVision");
+
+ // Dispose of resources
+ delete _console;
+ delete _cursorManager;
+ delete _stringManager;
+ delete _saveManager;
+ delete _renderManager;
+ delete _scriptManager;
+ delete _rnd;
+
+ // Remove all of our debug levels
+ DebugMan.clearAllDebugChannels();
+}
+
+void ZVision::initialize() {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+ // TODO: There are 10 file clashes when we flatten the directories.
+ // From a quick look, the files are exactly the same, so it shouldn't matter.
+ // But I'm noting it here just in-case it does become a problem.
+ SearchMan.addSubDirectoryMatching(gameDataDir, "data1", 0, 4, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "data2", 0, 4, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "data3", 0, 4, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "zassets1", 0, 2, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "zassets2", 0, 2, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "znemmx", 0, 1, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "zgi", 0, 4, true);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "fonts", 0, 1, true);
+
+ // Find zfs archive files
+ Common::ArchiveMemberList list;
+ SearchMan.listMatchingMembers(list, "*.zfs");
+
+ // Register the file entries within the zfs archives with the SearchMan
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ Common::String name = (*iter)->getName();
+ Common::SeekableReadStream *stream = (*iter)->createReadStream();
+ ZfsArchive *archive = new ZfsArchive(name, stream);
+
+ delete stream;
+
+ SearchMan.add(name, archive);
+ }
+
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_pixelFormat);
+
+ // Register random source
+ _rnd = new Common::RandomSource("zvision");
+
+ // Create managers
+ _scriptManager = new ScriptManager(this);
+ _renderManager = new RenderManager(_system, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat);
+ _saveManager = new SaveManager(this);
+ _stringManager = new StringManager(this);
+ _cursorManager = new CursorManager(this, &_pixelFormat);
+
+ // Initialize the managers
+ _cursorManager->initialize();
+ _scriptManager->initialize();
+ _stringManager->initialize(_gameDescription->gameId);
+
+ // Create debugger console. It requires GFX to be initialized
+ _console = new Console(this);
+}
+
+Common::Error ZVision::run() {
+ initialize();
+
+ // Main loop
+ while (!shouldQuit()) {
+ _clock.update();
+ uint32 currentTime = _clock.getLastMeasuredTime();
+ uint32 deltaTime = _clock.getDeltaTime();
+
+ processEvents();
+
+ // Call _renderManager->update() first so the background renders
+ // before anything that puzzles/controls will render
+ _renderManager->update(deltaTime);
+ _scriptManager->update(deltaTime);
+
+ // Render the backBuffer to the screen
+ _renderManager->renderBackbufferToScreen();
+
+ // Update the screen
+ _system->updateScreen();
+
+ // Calculate the frame delay based off a desired frame time
+ int delay = _desiredFrameTime - int32(_system->getMillis() - currentTime);
+ // Ensure non-negative
+ delay = delay < 0 ? 0 : delay;
+ _system->delayMillis(delay);
+ }
+
+ return Common::kNoError;
+}
+
+void ZVision::pauseEngineIntern(bool pause) {
+ _mixer->pauseAll(pause);
+
+ if (pause) {
+ _clock.stop();
+ } else {
+ _clock.start();
+ }
+}
+
+Common::String ZVision::generateSaveFileName(uint slot) {
+ return Common::String::format("%s.%02u", _targetName.c_str(), slot);
+}
+
+Common::String ZVision::generateAutoSaveFileName() {
+ return Common::String::format("%s.auto", _targetName.c_str());
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
new file mode 100644
index 0000000000..1c525c1fc1
--- /dev/null
+++ b/engines/zvision/zvision.h
@@ -0,0 +1,151 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ZVISION_ZVISION_H
+#define ZVISION_ZVISION_H
+
+#include "zvision/detection.h"
+#include "zvision/utility/clock.h"
+
+#include "common/random.h"
+#include "common/events.h"
+
+#include "engines/engine.h"
+
+#include "graphics/pixelformat.h"
+
+#include "gui/debugger.h"
+
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace ZVision {
+
+struct ZVisionGameDescription;
+class Console;
+class ScriptManager;
+class RenderManager;
+class CursorManager;
+class StringManager;
+class SaveManager;
+class RlfAnimation;
+
+class ZVision : public Engine {
+public:
+ ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc);
+ ~ZVision();
+
+public:
+ /**
+ * A Rectangle centered inside the actual window. All in-game coordinates
+ * are given in this coordinate space. Also, all images are clipped to the
+ * edges of this Rectangle
+ */
+ const Common::Rect _workingWindow;
+ const Graphics::PixelFormat _pixelFormat;
+
+private:
+ enum {
+ WINDOW_WIDTH = 640,
+ WINDOW_HEIGHT = 480,
+
+ //Zork nemesis working window sizes
+ ZNEM_WORKING_WINDOW_WIDTH = 512,
+ ZNEM_WORKING_WINDOW_HEIGHT = 320,
+
+ //ZGI(and default) working window sizes
+ ZGI_WORKING_WINDOW_WIDTH = 640,
+ ZGI_WORKING_WINDOW_HEIGHT = 344,
+
+ ROTATION_SCREEN_EDGE_OFFSET = 60,
+ MAX_ROTATION_SPEED = 400 // Pixels per second
+ };
+
+ Console *_console;
+ const ZVisionGameDescription *_gameDescription;
+
+ const int _desiredFrameTime;
+
+ // We need random numbers
+ Common::RandomSource *_rnd;
+
+ // Managers
+ ScriptManager *_scriptManager;
+ RenderManager *_renderManager;
+ CursorManager *_cursorManager;
+ SaveManager *_saveManager;
+ StringManager *_stringManager;
+
+ // Clock
+ Clock _clock;
+
+ // To prevent allocation every time we process events
+ Common::Event _event;
+
+public:
+ uint32 getFeatures() const;
+ Common::Language getLanguage() const;
+ Common::Error run();
+ void pauseEngineIntern(bool pause);
+
+ ScriptManager *getScriptManager() const { return _scriptManager; }
+ RenderManager *getRenderManager() const { return _renderManager; }
+ CursorManager *getCursorManager() const { return _cursorManager; }
+ SaveManager *getSaveManager() const { return _saveManager; }
+ StringManager *getStringManager() const { return _stringManager; }
+ Common::RandomSource *getRandomSource() const { return _rnd; }
+ ZVisionGameId getGameId() const { return _gameDescription->gameId; }
+
+ /**
+ * Play a video until it is finished. This is a blocking call. It will call
+ * _clock.stop() when the video starts and _clock.start() when the video finishes.
+ * It will also consume all events during video playback.
+ *
+ * @param videoDecoder The video to play
+ * @param destRect Where to put the video. (In working window coords)
+ * @param skippable If true, the video can be skipped at any time using [Spacebar]
+ */
+ void playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect = Common::Rect(0, 0, 0, 0), bool skippable = true);
+
+ Common::String generateSaveFileName(uint slot);
+ Common::String generateAutoSaveFileName();
+
+private:
+ void initialize();
+ void initFonts();
+
+ void parseStrFile(const Common::String fileName);
+
+ /** Called every frame from ZVision::run() to process any events from EventMan */
+ void processEvents();
+
+ void onMouseDown(const Common::Point &pos);
+ void onMouseUp(const Common::Point &pos);
+ void onMouseMove(const Common::Point &pos);
+};
+
+} // End of namespace ZVision
+
+#endif